package scala.tools.nsc package settings import org.junit.Assert._ import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.JUnit4 import scala.tools.testing.AssertUtil.assertThrows @RunWith(classOf[JUnit4]) class SettingsTest { @Test def booleanSettingColon() { def check(args: String*): MutableSettings#BooleanSetting = { val s = new MutableSettings(msg => throw new IllegalArgumentException(msg)) val b1 = new s.BooleanSetting("-Ytest-setting", "") s.allSettings += b1 val (ok, residual) = s.processArguments(args.toList, processAll = true) assert(residual.isEmpty) b1 } assertTrue(check("-Ytest-setting").value) assertTrue(check("-Ytest-setting:true").value) assertTrue(check("-Ytest-setting:TRUE").value) assertFalse(check("-Ytest-setting:false").value) assertFalse(check("-Ytest-setting:FALSE").value) assertThrows[IllegalArgumentException](check("-Ytest-setting:rubbish")) } @Test def userSettingsHavePrecedenceOverOptimize() { def check(args: String*): MutableSettings#BooleanSetting = { val s = new MutableSettings(msg => throw new IllegalArgumentException(msg)) val (ok, residual) = s.processArguments(args.toList, processAll = true) assert(residual.isEmpty) s.inline // among -optimize } assertTrue(check("-optimise").value) assertFalse(check("-optimise", "-Yinline:false").value) assertFalse(check("-Yinline:false", "-optimise").value) } // for the given args, select the desired setting private def check(args: String*)(b: MutableSettings => Boolean): Boolean = { val s = new MutableSettings(msg => throw new IllegalArgumentException(msg)) val (ok, residual) = s.processArguments(args.toList, processAll = true) assert(residual.isEmpty) b(s) } @Test def userSettingsHavePrecedenceOverLint() { assertTrue(check("-Xlint")(_.warnAdaptedArgs)) assertFalse(check("-Xlint", "-Ywarn-adapted-args:false")(_.warnAdaptedArgs)) assertFalse(check("-Ywarn-adapted-args:false", "-Xlint")(_.warnAdaptedArgs)) } @Test def anonymousLintersCanBeNamed() { assertTrue(check("-Xlint")(_.warnMissingInterpolator)) // among Xlint assertFalse(check("-Xlint:-missing-interpolator")(_.warnMissingInterpolator)) // positive overrides negative, but not the other way around assertTrue(check("-Xlint:-missing-interpolator,missing-interpolator")(_.warnMissingInterpolator)) assertTrue(check("-Xlint:-missing-interpolator", "-Xlint:missing-interpolator")(_.warnMissingInterpolator)) assertTrue(check("-Xlint:missing-interpolator,-missing-interpolator")(_.warnMissingInterpolator)) assertTrue(check("-Xlint:missing-interpolator", "-Xlint:-missing-interpolator")(_.warnMissingInterpolator)) // -Xlint:_ adds all possible choices, but explicit negative settings will override assertFalse(check("-Xlint:-missing-interpolator,_")(_.warnMissingInterpolator)) assertFalse(check("-Xlint:-missing-interpolator", "-Xlint:_")(_.warnMissingInterpolator)) assertFalse(check("-Xlint:_", "-Xlint:-missing-interpolator")(_.warnMissingInterpolator)) assertFalse(check("-Xlint:_,-missing-interpolator")(_.warnMissingInterpolator)) // -Xlint is the same as -Xlint:_ assertFalse(check("-Xlint:-missing-interpolator", "-Xlint")(_.warnMissingInterpolator)) assertFalse(check("-Xlint", "-Xlint:-missing-interpolator")(_.warnMissingInterpolator)) // combination of positive, negative and _ assertTrue(check("-Xlint:_,-missing-interpolator,missing-interpolator")(_.warnMissingInterpolator)) assertTrue(check("-Xlint:-missing-interpolator,_,missing-interpolator")(_.warnMissingInterpolator)) assertTrue(check("-Xlint:-missing-interpolator,missing-interpolator,_")(_.warnMissingInterpolator)) assertTrue(check("-Xlint:missing-interpolator,-missing-interpolator,_")(_.warnMissingInterpolator)) assertTrue(check("-Xlint:missing-interpolator,_,-missing-interpolator")(_.warnMissingInterpolator)) } @Test def xLintInvalidChoices(): Unit = { assertThrows[IllegalArgumentException](check("-Xlint:-_")(_.warnAdaptedArgs)) assertThrows[IllegalArgumentException](check("-Xlint:-warn-adapted-args")(_.warnAdaptedArgs)) // "warn-" should not be there } @Test def xLintNonColonated(): Unit = { assertTrue(check("-Xlint", "adapted-args", "-deprecation")(_.warnAdaptedArgs)) assertFalse(check("-Xlint", "adapted-args", "-deprecation")(_.warnMissingInterpolator)) assertTrue(check("-Xlint", "adapted-args", "missing-interpolator", "-deprecation")(s => s.warnMissingInterpolator && s.warnAdaptedArgs)) assertThrows[IllegalArgumentException](check("-Xlint", "adapted-args", "-missing-interpolator")(_.warnAdaptedArgs)) // non-colonated: cannot provide negative args } @Test def xLintContainsValues(): Unit = { // make sure that lint.contains and lint.value.contains are consistent def t(s: MutableSettings, v: String) = { val r = s.lint.contains(v) assertSame(r, s.lint.value.contains((s.LintWarnings withName v).asInstanceOf[s.lint.domain.Value])) r } assertTrue(check("-Xlint")(t(_, "adapted-args"))) assertTrue(check("-Xlint:_")(t(_, "adapted-args"))) assertFalse(check("-Xlint:_,-adapted-args")(t(_, "adapted-args"))) assertFalse(check("-Xlint:-adapted-args,_")(t(_, "adapted-args"))) assertTrue(check("-Xlint:-adapted-args,_,adapted-args")(t(_, "adapted-args"))) } @Test def xLintDeprecatedAlias(): Unit = { assertTrue(check("-Ywarn-adapted-args")(_.warnAdaptedArgs)) assertTrue(check("-Xlint:_,-adapted-args", "-Ywarn-adapted-args")(_.warnAdaptedArgs)) assertTrue(check("-Xlint:-adapted-args", "-Ywarn-adapted-args")(_.warnAdaptedArgs)) assertTrue(check("-Ywarn-adapted-args", "-Xlint:-adapted-args,_")(_.warnAdaptedArgs)) assertFalse(check("-Ywarn-adapted-args:false")(_.warnAdaptedArgs)) assertFalse(check("-Ywarn-adapted-args:false", "-Xlint:_")(_.warnAdaptedArgs)) assertFalse(check("-Ywarn-adapted-args:false", "-Xlint:_,-adapted-args")(_.warnAdaptedArgs)) assertTrue(check("-Ywarn-adapted-args:false", "-Xlint:_,adapted-args")(_.warnAdaptedArgs)) } @Test def expandingMultichoice(): Unit = { val s = new MutableSettings(msg => throw new IllegalArgumentException(msg)) object mChoices extends s.MultiChoiceEnumeration { val a = Choice("a") val b = Choice("b") val c = Choice("c") val d = Choice("d") val ab = Choice("ab", expandsTo = List(a, b)) val ac = Choice("ac", expandsTo = List(a, c)) val uber = Choice("uber", expandsTo = List(ab, d)) } val m = s.MultiChoiceSetting("-m", "args", "magic sauce", mChoices, Some(List("ac"))) def check(args: String*)(t: s.MultiChoiceSetting[mChoices.type] => Boolean): Boolean = { m.clear() val (ok, rest) = s.processArguments(args.toList, processAll = true) assert(rest.isEmpty) t(m) } import mChoices._ assertTrue(check("-m")(_.value == Set(a,c))) assertTrue(check("-m:a,-b,c")(_.value == Set(a,c))) // expanding options don't end up in the value set, only the terminal ones assertTrue(check("-m:ab,ac")(_.value == Set(a,b,c))) assertTrue(check("-m:_")(_.value == Set(a,b,c,d))) assertTrue(check("-m:uber,ac")(_.value == Set(a,b,c,d))) // recursive expansion of uber // explicit nays assertTrue(check("-m:_,-b")(_.value == Set(a,c,d))) assertTrue(check("-m:b,_,-b")(_.value == Set(a,b,c,d))) assertTrue(check("-m:ac,-c")(_.value == Set(a))) assertTrue(check("-m:ac,-a,-c")(_.value == Set())) assertTrue(check("-m:-d,ac")(_.value == Set(a,c))) assertTrue(check("-m:-b,ac,uber")(_.value == Set(a,c,d))) assertFalse(check("-m:uber")(_.contains("i-m-not-an-option"))) assertThrows[IllegalArgumentException](check("-m:-_")(_ => true), _ contains "'-_' is not a valid choice") assertThrows[IllegalArgumentException](check("-m:a,b,-ab")(_ => true), _ contains "'ab' cannot be negated") assertThrows[IllegalArgumentException](check("-m:a,ac,-uber,uber")(_ => true), _ contains "'uber' cannot be negated") } @Test def xSourceTest(): Unit = { def check(expected: String, args: String*): Unit = { val s = new MutableSettings(msg => throw new IllegalArgumentException(msg)) val (_, residual) = s.processArguments(args.toList, processAll = true) assert(residual.isEmpty) assertTrue(s.source.value == ScalaVersion(expected)) } check(expected = "2.11.0") // default check(expected = "2.11.0", "-Xsource:2.11") check(expected = "2.10", "-Xsource:2.10.0") check(expected = "2.12", "-Xsource:2.12") assertThrows[IllegalArgumentException](check(expected = "2.11", "-Xsource"), _ == "-Xsource requires an argument, the syntax is -Xsource:") assertThrows[IllegalArgumentException](check(expected = "2.11", "-Xsource", "2.11"), _ == "-Xsource requires an argument, the syntax is -Xsource:") assertThrows[IllegalArgumentException](check(expected = "2.11", "-Xsource:2.invalid"), _ contains "There was a problem parsing 2.invalid") } // equal with stripped margins and normalized line endings private def marginallyEquals(s1: String, s2: String): Boolean = { def normally(s: String): String = s.stripMargin.lines.mkString("\n") normally(s1) == normally(s2) } @Test def helpHasDefault(): Unit = { val s = new MutableSettings(msg => throw new IllegalArgumentException(msg)) object mChoices extends s.MultiChoiceEnumeration { val a = Choice("a", "help a") val b = Choice("b", "help b") val c = Choice("c", "help c") } val m = s.MultiChoiceSetting("-m", "args", "magic sauce", mChoices, Some(List("b"))) def check(args: String*)(t: s.MultiChoiceSetting[mChoices.type] => Boolean): Boolean = { m.clear() val (ok, rest) = s.processArguments(args.toList, processAll = true) assert(rest.isEmpty) t(m) } import mChoices._ assertTrue(check("-m")(_.value == Set(b))) assertTrue(check("-m") { _ => val expected = """|magic sauce | a help a | b help b | c help c |Default: b |""" marginallyEquals(expected, m.help) }) } @Test def helpHasDefaultAll(): Unit = { val s = new MutableSettings(msg => throw new IllegalArgumentException(msg)) object mChoices extends s.MultiChoiceEnumeration { val a = Choice("a", "help a") val b = Choice("b", "help b") val c = Choice("c", "help c") } val m = s.MultiChoiceSetting("-m", "args", "magic sauce", mChoices, Some(List("_"))) def check(args: String*)(t: s.MultiChoiceSetting[mChoices.type] => Boolean): Boolean = { m.clear() val (ok, rest) = s.processArguments(args.toList, processAll = true) assert(rest.isEmpty) t(m) } import mChoices._ assertTrue(check("-m")(_.value == Set(a, b, c))) assertTrue(check("-m") { _ => val expected = """|magic sauce | a help a | b help b | c help c |Default: All choices are enabled by default. |""" marginallyEquals(expected, m.help) }) } }