Skip to content

Commit 55175f0

Browse files
committed
Check responses with assertions instead of strings equality
1 parent aaaf448 commit 55175f0

File tree

11 files changed

+108
-129
lines changed

11 files changed

+108
-129
lines changed

language-server/test/dotty/tools/languageserver/CompletionTest.scala

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,31 +9,8 @@ class CompletionTest extends BaseTest {
99

1010
@Test def competion0: Unit = {
1111
val completions =
12-
List(
13-
("clone", "Method", "(): Object"),
14-
("!=", "Method", "(x$0: Any): Boolean"),
15-
("wait", "Method", "(x$0: Long, x$1: Int): Unit"),
16-
("wait", "Method", "(x$0: Long): Unit"),
17-
("wait", "Method", "(): Unit"),
18-
("notifyAll", "Method", "(): Unit"),
19-
("finalize", "Method", "(): Unit"),
20-
("asInstanceOf", "Method", "[X0] => X0"),
21-
("==", "Method", "(x$0: Any): Boolean"),
22-
("equals", "Method", "(x$0: Any): Boolean"),
23-
("isInstanceOf", "Method", "[X0] => Boolean"),
24-
("getClass", "Method", "(): Class[_]"),
25-
("##", "Method", "=> Int"),
26-
("eq", "Method", "(x$0: Object): Boolean"),
27-
("synchronized", "Method", "[X0](x$0: X0): X0"),
28-
("xyz", "Field", "Int"),
29-
("ne", "Method", "(x$0: Object): Boolean"),
30-
("toString", "Method", "(): String"),
31-
("hashCode", "Method", "(): Int"),
32-
("y", "Method", "=> Int"),
33-
("notify", "Method", "(): Unit")
34-
)
35-
// FIXME completions is returned in different order in CI
36-
// checkActions(code"class Foo { val xyz: Int = 0; def y: Int = xy${completion(completions)} }")
37-
// checkActions(code"class Foo { val xyz: Int = 0; def y: Int = xy$p1 }".completion(p1, completions))
12+
List(("xyz", "Field", "Int"), ("y", "Method", "=> Int"))
13+
checkActions(code"class Foo { val xyz: Int = 0; def y: Int = xy${completion(completions)} }")
14+
checkActions(code"class Foo { val xyz: Int = 0; def y: Int = xy$p1 }".completion(p1, completions))
3815
}
3916
}

language-server/test/dotty/tools/languageserver/Main.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ object Main {
2727
println(Console.RED + "failed" + Console.RESET)
2828
System.err.println(s"${method.getName} failed with")
2929
System.err.println(ex1.getMessage)
30+
ex1.printStackTrace()
3031
failed += 1
3132
case _ => throw ex.getCause
3233
}

language-server/test/dotty/tools/languageserver/util/BaseTest.scala

Lines changed: 11 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@ package dotty.tools.languageserver.util
33
import java.nio.file.Path
44
import java.nio.file.Paths
55

6-
import dotty.tools.dotc.util.DiffUtil
76
import dotty.tools.languageserver.util.Code._
87
import dotty.tools.languageserver.util.actions._
9-
import dotty.tools.languageserver.util.embedded.{ActionOnCodePosition, CodePosition}
8+
import dotty.tools.languageserver.util.embedded.CodePosition
109
import dotty.tools.languageserver.util.server.{TestFile, TestServer}
1110

1211
class BaseTest {
@@ -29,30 +28,16 @@ class BaseTest {
2928

3029
val testServer = new TestServer(BaseTest.testDir)
3130

32-
def actionOnPosition(file: TestFile, action: Action, line: Int, char: Int) = {
33-
val response = action match {
34-
case _: CodeHover => testServer.hover(file, line, char).toString
35-
case _: CodeDefinition => testServer.definition(file, line, char).toString
36-
case codeRef: CodeReferences => testServer.references(file, line, char, codeRef.withDecl).toString
37-
case code: CodeCompletion =>
38-
testServer.completion(file, code.position.line, code.position.character).toString
39-
}
31+
def actionOnPosition(file: TestFile, action: Action, line: Int, char: Int): Unit = {
32+
val response = action match {
33+
case _: CodeHover => testServer.hover(file, line, char)
34+
case _: CodeDefinition => testServer.definition(file, line, char)
35+
case codeRef: CodeReferences => testServer.references(file, line, char, codeRef.withDecl)
36+
case code: CodeCompletion =>
37+
testServer.completion(file, code.position.line, code.position.character)
38+
}
4039

41-
val expected = action.expectedOutput(positions)
42-
43-
if (expected != response) {
44-
45-
val diff = DiffUtil.mkColoredLineDiff(expected.split("\n"), response.split("\n"))
46-
47-
val message = // TODO highlight position in code
48-
s"""When hovering line $line on character $char
49-
|${codeInFiles.map { case (fileName, code) => s"// $fileName\n${code.text}"}.mkString("\n")}
50-
|
51-
|expected output (left) did not match response (right)
52-
|$diff
53-
""".stripMargin
54-
assert(false, message)
55-
}
40+
action.checkOutput(response)
5641
}
5742

5843
val allFilesOpened = codeInFiles.map { case (fileName, code) =>
@@ -67,7 +52,7 @@ class BaseTest {
6752
}
6853
}
6954

70-
def getPositions(codeInFiles: Seq[(String, CodeWithActions)]): PositionContext = {
55+
private def getPositions(codeInFiles: Seq[(String, CodeWithActions)]): PositionContext = {
7156
val posSeq = {
7257
for {
7358
(fileName, code) <- codeInFiles
Lines changed: 9 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,19 @@
11
package dotty.tools.languageserver.util
22

3+
import java.util
4+
35
import dotty.tools.languageserver.util.actions.CodeReference
6+
import org.eclipse.lsp4j._
47

58
object Responses {
69

7-
def location(refs: List[CodeReference])(implicit ctx: PositionContext): String =
8-
refs.map(ref => Responses.location(ref)).mkString("List(", ", ", ")")
9-
10-
def location(ref: CodeReference)(implicit ctx: PositionContext): String = {
10+
def checkLocation(loc: Location, ref: CodeReference)(implicit ctx: PositionContext): Unit = {
1111
ref.check()
12-
val start = ref.range.start
13-
val end = ref.range.end
14-
s"""Location [
15-
| uri = "file://${BaseTest.sourceDir}/${ref.fileName}"
16-
| range = Range [
17-
| start = Position [
18-
| line = ${start.line}
19-
| character = ${start.character}
20-
| ]
21-
| end = Position [
22-
| line = ${end.line}
23-
| character = ${end.character}
24-
| ]
25-
| ]
26-
|]""".stripMargin
12+
assert(loc.getUri == ref.fileUri)
13+
assert(loc.getRange.getStart.getLine == ref.range.start.line)
14+
assert(loc.getRange.getStart.getCharacter == ref.range.start.character)
15+
assert(loc.getRange.getEnd.getLine == ref.range.end.line)
16+
assert(loc.getRange.getEnd.getCharacter == ref.range.end.character)
2717
}
2818

29-
def emptyHover: String =
30-
s"""Hover [
31-
| contents = null
32-
| range = null
33-
|]""".stripMargin
34-
35-
def hover(expected: String): String =
36-
s"""Hover [
37-
| contents = SeqWrapper (
38-
| Either [
39-
| left = $expected
40-
| right = null
41-
| ]
42-
| )
43-
| range = null
44-
|]""".stripMargin
45-
4619
}

language-server/test/dotty/tools/languageserver/util/actions/Action.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ package dotty.tools.languageserver.util.actions
33
import dotty.tools.languageserver.util.PositionContext
44

55
trait Action {
6-
def expectedOutput(implicit posCtx: PositionContext): String
6+
def checkOutput(obj: Object)(implicit posCtx: PositionContext): Unit
77
def onEachPosition(f: (Int, Int) => Unit)(implicit posCtx: PositionContext): Unit
88
}
Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,35 @@
11
package dotty.tools.languageserver.util.actions
22

33
import dotty.tools.languageserver.util.PositionContext
4-
import dotty.tools.languageserver.util.Responses._
54
import dotty.tools.languageserver.util.embedded.CodePosition
65

6+
import scala.collection.JavaConverters._
7+
8+
import org.eclipse.lsp4j._
9+
import org.eclipse.lsp4j.jsonrpc.messages._
10+
711
case class CodeCompletion(position: CodePosition, completions: List[(String, String, String)]) extends ActionOnPosition {
812

9-
def expectedOutput(implicit posCtx: PositionContext): String =
10-
s"""Either [
11-
| left = null
12-
| right = CompletionList [
13-
| isIncomplete = false
14-
| items = SeqWrapper (
15-
|${completions.map(comp => completionItem(comp._1, comp._2, comp._3)).mkString(",\n")}
16-
| )
17-
|]
18-
|]""".stripMargin
13+
override def checkOutput(obj: Object)(implicit posCtx: PositionContext): Unit = {
14+
obj match {
15+
case obj: Either[_, _] =>
16+
assert(obj.isRight)
17+
obj.getRight match {
18+
case cList: CompletionList =>
19+
assert(!cList.isIncomplete)
20+
completions.foreach { completion =>
21+
assert(
22+
cList.getItems.asScala.exists ( item =>
23+
completion == (item.getLabel, item.getKind.toString, item.getDetail)
24+
),
25+
"Did not return completion for " + completion + "\n" + cList.getItems.asScala.toList
26+
)
27+
28+
}
29+
}
1930

20-
def completionItem(label: String, kind: String, detail: String): String =
21-
s""" CompletionItem [
22-
| label = "$label"
23-
| kind = $kind
24-
| detail = "$detail"
25-
| documentation = null
26-
| sortText = null
27-
| filterText = null
28-
| insertText = null
29-
| insertTextFormat = null
30-
| textEdit = null
31-
| additionalTextEdits = null
32-
| command = null
33-
| data = null
34-
| ]""".stripMargin
31+
case _ =>
32+
assert(false, "Location response to be a Either but got " + obj)
33+
}
34+
}
3535
}
Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,20 @@
11
package dotty.tools.languageserver.util.actions
22

3-
import dotty.tools.languageserver.util.{PositionContext, CodeRange, Responses}
3+
import java.util
4+
5+
import dotty.tools.languageserver.util._
6+
import org.eclipse.lsp4j._
7+
48

59
case class CodeDefinition(text: String, refOpt: Option[CodeReference], range: CodeRange) extends ActionOnRange {
6-
override def expectedOutput(implicit posCtx: PositionContext): String =
7-
Responses.location(refOpt.toList)
10+
11+
override def checkOutput(obj: Object)(implicit posCtx: PositionContext): Unit = {
12+
obj match {
13+
case obj: util.List[Location] =>
14+
assert(obj.size() == refOpt.size)
15+
refOpt.foreach(Responses.checkLocation(obj.get(0), _))
16+
case _ =>
17+
assert(false, "Location response to be a List but got " + obj)
18+
}
19+
}
820
}
Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,23 @@
11
package dotty.tools.languageserver.util.actions
22

3-
import dotty.tools.languageserver.util.Responses._
4-
import dotty.tools.languageserver.util.{PositionContext, CodeRange}
3+
4+
import dotty.tools.languageserver.util.{CodeRange, PositionContext}
5+
import org.eclipse.lsp4j.Hover
56

67
case class CodeHover(expected: String, range: CodeRange) extends ActionOnRange {
7-
override def expectedOutput(implicit posCtx: PositionContext): String =
8-
if (expected.isEmpty) emptyHover else hover(expected)
8+
9+
override def checkOutput(obj: Object)(implicit posCtx: PositionContext): Unit = {
10+
obj match {
11+
case obj: Hover =>
12+
assert(obj.getRange == null)
13+
if (expected == "") assert(obj.getContents == null, "Expected null contents in " + obj)
14+
else {
15+
assert(obj.getContents.size() == 1, obj)
16+
val content = obj.getContents.get(0)
17+
assert(content.isLeft, "Expected left but was " + content)
18+
assert(content.getLeft == expected, s"Expected $expected but was ${content.getLeft}")
19+
}
20+
case _ => assert(false, "Expected response to be a Hover but got " + obj)
21+
}
22+
}
923
}

language-server/test/dotty/tools/languageserver/util/actions/CodeReference.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package dotty.tools.languageserver.util.actions
22

3-
import dotty.tools.languageserver.util.{PositionContext, CodeRange}
3+
import dotty.tools.languageserver.util.{BaseTest, CodeRange, PositionContext}
44

55
case class CodeReference(fileName: String, range: CodeRange) {
66

7+
def fileUri: String = s"file://${BaseTest.sourceDir}/$fileName"
8+
79
def check()(implicit posCtx: PositionContext): Unit = {
810
assert(fileName == range.start.file, s"Position vas expected in $fileName buy was found in ${range.start.file}")
911
assert(fileName == range.end.file, s"Position vas expected in $fileName buy was found in ${range.end.file}")
Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,21 @@
11
package dotty.tools.languageserver.util.actions
22

3-
import dotty.tools.languageserver.util.{PositionContext, CodeRange, Responses}
3+
import java.util
4+
5+
import dotty.tools.languageserver.util.{CodeRange, PositionContext, Responses}
6+
import org.eclipse.lsp4j._
7+
8+
import scala.collection.JavaConverters._
49

510
case class CodeReferences(text: String, refs: List[CodeReference], withDecl: Boolean, range: CodeRange) extends ActionOnRange {
6-
def expectedOutput(implicit posCtx: PositionContext): String = Responses.location(refs)
11+
12+
override def checkOutput(obj: Object)(implicit posCtx: PositionContext): Unit = {
13+
obj match {
14+
case obj: util.List[Location] =>
15+
assert(obj.size() == refs.size)
16+
obj.asScala.zip(refs).foreach { case (loc, ref) => Responses.checkLocation(loc, ref) }
17+
case _ =>
18+
assert(false, "Location response to be a List but got " + obj)
19+
}
20+
}
721
}

language-server/test/dotty/tools/languageserver/util/server/TestServer.scala

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package dotty.tools.languageserver.util.server
33
import java.io.PrintWriter
44
import java.net.URI
55
import java.nio.file.Path
6+
import java.util
67

78
import dotty.tools.languageserver.DottyLanguageServer
89
import org.eclipse.lsp4j._
@@ -56,18 +57,18 @@ class TestServer(testFolder: Path) {
5657
testFile
5758
}
5859

59-
def definition(file: TestFile, line: Int, character: Int): List[Location] =
60-
server.definition(pos(file, line, character)).get().asScala.toList
60+
def definition(file: TestFile, line: Int, character: Int): util.List[Location] =
61+
server.definition(pos(file, line, character)).get().asInstanceOf[util.List[Location]]
6162

6263
def hover(file: TestFile, line: Int, character: Int): Hover =
6364
server.hover(pos(file, line, character)).get()
6465

65-
def references(file: TestFile, line: Int, character: Int, withDecl: Boolean): List[Location] = {
66+
def references(file: TestFile, line: Int, character: Int, withDecl: Boolean): util.List[Location] = {
6667
val rp = new ReferenceParams()
6768
rp.setContext(new ReferenceContext(withDecl))
6869
rp.setTextDocument(file.textDocumentIdentifier)
6970
rp.setPosition(new Position(line, character))
70-
server.references(rp).get().asScala.toList
71+
server.references(rp).get().asInstanceOf[util.List[Location]]
7172
}
7273

7374
def completion(file: TestFile, line: Int, character: Int) =

0 commit comments

Comments
 (0)