Created
January 10, 2019 15:54
-
-
Save olafurpg/eabbf6c7775be0556ba5f2b2c55a295e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package tests | |
import scala.concurrent.Future | |
object SyntaxErrorSlowSuite extends BaseSlowSuite("syntax-error") { | |
type Assert = (String => String, String) | |
def check( | |
name: String, | |
code: String, | |
asserts: Assert* | |
): Unit = { | |
testAsync(name) { | |
def runAsserts(as: List[Assert]): Future[Unit] = as match { | |
case Nil => Future.successful(()) | |
case (fn, expected) :: tail => | |
server | |
.didChange("a/src/main/scala/A.scala")(fn) | |
.flatMap { _ => | |
assertNoDiff(client.workspaceDiagnostics, expected) | |
runAsserts(tail) | |
} | |
} | |
for { | |
_ <- server.initialize( | |
s""" | |
|/metals.json | |
|{"a": {}} | |
|/a/src/main/scala/A.scala | |
|""".stripMargin + code | |
) | |
_ <- server.didOpen("a/src/main/scala/A.scala") | |
_ = assertNotEmpty(client.workspaceDiagnostics) | |
_ <- runAsserts(asserts.toList) | |
} yield () | |
} | |
} | |
testAsync("basic") { | |
for { | |
_ <- server.initialize( | |
"""| | |
|/metals.json | |
|{"a": {}} | |
|/project/plugins.sbt | |
|lazy lazy val x = 1 | |
|/Main.scala | |
|object object A | |
|""".stripMargin | |
) | |
_ <- server.didOpen("Main.scala") | |
_ <- server.didOpen("project/plugins.sbt") | |
_ = assertNoDiff( | |
client.workspaceDiagnostics, | |
""" | |
|Main.scala:1:8: error: identifier expected but object found | |
|object object A | |
| ^^^^^^ | |
|project/plugins.sbt:1:6: error: repeated modifier | |
|lazy lazy val x = 1 | |
| ^^^^ | |
|""".stripMargin | |
) | |
_ <- server.didClose("Main.scala") | |
_ <- server.didClose("project/plugins.sbt") | |
_ = assertNoDiff(client.workspaceDiagnostics, "") | |
_ <- server.didOpen("Main.scala") | |
_ <- server.didOpen("project/plugins.sbt") | |
_ <- server.didSave("Main.scala")(_ => "object A\n") | |
_ = assertNoDiff( | |
client.workspaceDiagnostics, | |
""" | |
|project/plugins.sbt:1:6: error: repeated modifier | |
|lazy lazy val x = 1 | |
| ^^^^ | |
|""".stripMargin | |
) | |
_ <- server.didSave("project/plugins.sbt")(_ => "lazy val x = 1\n") | |
_ = assertNoDiff(client.workspaceDiagnostics, "") | |
} yield () | |
} | |
testAsync("mix1") { | |
for { | |
_ <- server.initialize( | |
"""| | |
|/metals.json | |
|{"a": {}} | |
|/a/src/main/scala/Main.scala | |
|object object A | |
|object object B | |
|""".stripMargin | |
) | |
_ <- server.didOpen("a/src/main/scala/Main.scala") | |
_ = assertNoDiff( | |
client.workspaceDiagnostics, | |
"""|a/src/main/scala/Main.scala:1:8: error: identifier expected but 'object' found. | |
|object object A | |
| ^^^^^^ | |
|a/src/main/scala/Main.scala:2:8: error: identifier expected but 'object' found. | |
|object object B | |
| ^^^^^^ | |
|""".stripMargin | |
) | |
_ <- server.didChange("a/src/main/scala/Main.scala")(t => "\n" + t) | |
_ = assertNoDiff( | |
client.workspaceDiagnostics, | |
"""|a/src/main/scala/Main.scala:2:8: error: identifier expected but 'object' found. | |
|object object A | |
| ^^^^^^ | |
|a/src/main/scala/Main.scala:3:8: error: identifier expected but 'object' found. | |
|object object B | |
| ^^^^^^ | |
|""".stripMargin | |
) | |
} yield () | |
} | |
testAsync("mix2") { | |
for { | |
_ <- server.initialize( | |
"""| | |
|/metals.json | |
|{"a": {}} | |
|/a/src/main/scala/Main.scala | |
|object Main { | |
| val b: Int = "" | |
|} | |
|""".stripMargin | |
) | |
_ <- server.didOpen("a/src/main/scala/Main.scala") | |
_ <- server.didChange("a/src/main/scala/Main.scala")( | |
_.replaceAllLiterally("val b", "val\n val b") | |
) | |
_ <- server.didChange("a/src/main/scala/Main.scala")( | |
_.replaceAllLiterally("val\n", "val \n") | |
) | |
_ <- server.didChange("a/src/main/scala/Main.scala")( | |
_.replaceAllLiterally("val \n", "") | |
) | |
_ = assertNoDiff( | |
client.workspaceDiagnostics, | |
"""|a/src/main/scala/Main.scala:2:18: error: type mismatch; | |
| found : String("") | |
| required: Int | |
| val b: Int = "" | |
| ^^ | |
|""".stripMargin | |
) | |
} yield () | |
} | |
testAsync("no-build-tool") { | |
for { | |
_ <- server.initialize( | |
""" | |
|/A.scala | |
|object A { val x = } | |
|""".stripMargin, | |
expectError = true | |
) | |
_ <- server.didOpen("A.scala") | |
_ = assertNoDiff( | |
client.workspaceDiagnostics, | |
"""|A.scala:1:20: error: illegal start of simple expression | |
|object A { val x = } | |
| ^ | |
|""".stripMargin | |
) | |
} yield () | |
} | |
testAsync("unclosed-literal") { | |
for { | |
_ <- server.initialize( | |
""" | |
|/metals.json | |
|{"a": {}} | |
|/a/src/main/scala/A.scala | |
|object A { | |
| val x: Int = "" | |
|} | |
|""".stripMargin | |
) | |
_ <- server.didOpen("a/src/main/scala/A.scala") | |
typeMismatch = { | |
"""|a/src/main/scala/A.scala:2:16: error: type mismatch; | |
| found : String("") | |
| required: Int | |
| val x: Int = "" | |
| ^^ | |
|""".stripMargin | |
} | |
_ = assertNoDiff(client.workspaceDiagnostics, typeMismatch) | |
_ <- server.didChange("a/src/main/scala/A.scala")( | |
_.replaceAllLiterally("\"\"", "\"") | |
) | |
// assert that a tokenization error results in a single diagnostic, hides type errors. | |
_ = assertNoDiff( | |
client.workspaceDiagnostics, | |
"""|a/src/main/scala/A.scala:2:16: error: unclosed string literal | |
| val x: Int = " | |
| ^ | |
|""".stripMargin | |
) | |
_ <- server.didChange("a/src/main/scala/A.scala")( | |
_.replaceAllLiterally("\"", "\"\"\n // close") | |
) | |
// assert that once the tokenization error is fixed, the type error reappears. | |
_ = assertNoDiff(client.workspaceDiagnostics, typeMismatch) | |
} yield () | |
} | |
check( | |
"sticky", | |
"""|object A { | |
| "".lengthCompare("1".substring(0)) | |
|} | |
|""".stripMargin, | |
( | |
_.replaceAllLiterally("\"1\".substring(0)", ""), | |
"""|a/src/main/scala/A.scala:2:19: error: type mismatch; | |
| found : String | |
| required: Int | |
| "".lengthCompare() | |
| ^^ | |
|""".stripMargin | |
), | |
( | |
_.replaceAllLiterally(".lengthCompare()", "."), | |
"""|a/src/main/scala/A.scala:2:5: error: type mismatch; | |
| found : String | |
| required: Int | |
| "". | |
| ^ | |
|a/src/main/scala/A.scala:3:1: error: identifier expected but } found | |
|} | |
|^ | |
|""".stripMargin | |
) | |
) | |
check( | |
"stable1", | |
"""|object A { | |
| "".lengthCompare() | |
|} | |
|""".stripMargin, | |
( | |
_.replaceAllLiterally("object A", "object B"), | |
"""|a/src/main/scala/A.scala:2:19: error: not enough arguments for method lengthCompare: (len: Int)Int. | |
|Unspecified value parameter len. | |
| "".lengthCompare() | |
| ^^ | |
|""".stripMargin | |
) | |
) | |
check( | |
"stable2", | |
"""|object A { | |
| val x: Int = "" | |
|} | |
|""".stripMargin, | |
( | |
_.replaceAllLiterally("\"\"", "\"a\" // comment"), | |
"""|a/src/main/scala/A.scala:2:16: error: type mismatch; | |
| found : String("") | |
| required: Int | |
| val x: Int = "a" // comment | |
| ^ | |
|""".stripMargin | |
) | |
) | |
check( | |
"stable3", | |
"""|object A { | |
| val x: Int = "a" + "b" | |
|} | |
|""".stripMargin, | |
( | |
_.replaceAllLiterally("\"b\"", "\"c\""), | |
"""|a/src/main/scala/A.scala:2:20: error: type mismatch; | |
| found : String("ab") | |
| required: Int | |
| val x: Int = "a" + "c" | |
| ^^^^^ | |
|""".stripMargin | |
) | |
) | |
check( | |
"strip", | |
"""|object A { | |
| val x: Int = "a" + "b" | |
|} | |
|""".stripMargin, | |
( | |
_.replaceAllLiterally("t = \"a\" + \"b\"", ""), | |
"""|a/src/main/scala/A.scala:2:11: error: type mismatch; | |
| found : String("ab") | |
| required: Int | |
| val x: In | |
| ^ | |
|""".stripMargin | |
) | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment