mirror of https://github.com/sbt/sbt.git
129 lines
4.9 KiB
Scala
129 lines
4.9 KiB
Scala
package sbt
|
|
|
|
import Def.{ displayFull, displayMasked, ScopedKey }
|
|
import java.net.URI
|
|
import TestBuild._
|
|
import complete._
|
|
|
|
import org.scalacheck._
|
|
import Gen._
|
|
import Prop._
|
|
import Arbitrary.arbBool
|
|
|
|
/**
|
|
* Tests that the scoped key parser in Act can correctly parse a ScopedKey converted by Def.show*Key.
|
|
* This includes properly resolving omitted components.
|
|
*/
|
|
object ParseKey extends Properties("Key parser test") {
|
|
final val MaxKeys = 5
|
|
final val MaxScopedKeys = 100
|
|
|
|
implicit val gstructure = genStructure
|
|
|
|
property("An explicitly specified axis is always parsed to that explicit value") =
|
|
forAllNoShrink(structureDefinedKey) { (skm: StructureKeyMask) =>
|
|
import skm.{ structure, key, mask }
|
|
|
|
val expected = resolve(structure, key, mask)
|
|
val string = displayMasked(key, mask)
|
|
|
|
("Key: " + displayFull(key)) |:
|
|
parseExpected(structure, string, expected, mask)
|
|
}
|
|
|
|
property("An unspecified project axis resolves to the current project") =
|
|
forAllNoShrink(structureDefinedKey) { (skm: StructureKeyMask) =>
|
|
import skm.{ structure, key }
|
|
|
|
val mask = skm.mask.copy(project = false)
|
|
val string = displayMasked(key, mask)
|
|
|
|
("Key: " + displayFull(key)) |:
|
|
("Mask: " + mask) |:
|
|
("Current: " + structure.current) |:
|
|
parse(structure, string) {
|
|
case Left(err) => false
|
|
case Right(sk) => sk.scope.project == Select(structure.current)
|
|
}
|
|
}
|
|
|
|
property("An unspecified task axis resolves to Global") =
|
|
forAllNoShrink(structureDefinedKey) { (skm: StructureKeyMask) =>
|
|
import skm.{ structure, key }
|
|
val mask = skm.mask.copy(task = false)
|
|
val string = displayMasked(key, mask)
|
|
|
|
("Key: " + displayFull(key)) |:
|
|
("Mask: " + mask) |:
|
|
parse(structure, string) {
|
|
case Left(err) => false
|
|
case Right(sk) => sk.scope.task == Global
|
|
}
|
|
}
|
|
|
|
property("An unspecified configuration axis resolves to the first configuration directly defining the key or else Global") =
|
|
forAllNoShrink(structureDefinedKey) { (skm: StructureKeyMask) =>
|
|
import skm.{ structure, key }
|
|
val mask = ScopeMask(config = false)
|
|
val string = displayMasked(key, mask)
|
|
val resolvedConfig = Resolve.resolveConfig(structure.extra, key.key, mask)(key.scope).config
|
|
|
|
("Key: " + displayFull(key)) |:
|
|
("Mask: " + mask) |:
|
|
("Expected configuration: " + resolvedConfig.map(_.name)) |:
|
|
parse(structure, string) {
|
|
case Right(sk) => sk.scope.config == resolvedConfig
|
|
case Left(err) => false
|
|
}
|
|
}
|
|
|
|
lazy val structureDefinedKey: Gen[StructureKeyMask] = structureKeyMask { s =>
|
|
for (scope <- TestBuild.scope(s.env); key <- oneOf(s.allAttributeKeys.toSeq)) yield ScopedKey(scope, key)
|
|
}
|
|
def structureKeyMask(genKey: Structure => Gen[ScopedKey[_]])(implicit maskGen: Gen[ScopeMask], structureGen: Gen[Structure]): Gen[StructureKeyMask] =
|
|
for (mask <- maskGen; structure <- structureGen; key <- genKey(structure)) yield new StructureKeyMask(structure, key, mask)
|
|
final class StructureKeyMask(val structure: Structure, val key: ScopedKey[_], val mask: ScopeMask)
|
|
|
|
def resolve(structure: Structure, key: ScopedKey[_], mask: ScopeMask): ScopedKey[_] =
|
|
ScopedKey(Resolve(structure.extra, Select(structure.current), key.key, mask)(key.scope), key.key)
|
|
|
|
def parseExpected(structure: Structure, s: String, expected: ScopedKey[_], mask: ScopeMask): Prop =
|
|
("Expected: " + displayFull(expected)) |:
|
|
("Mask: " + mask) |:
|
|
parse(structure, s) {
|
|
case Left(err) => false
|
|
case Right(sk) => Project.equal(sk, expected, mask)
|
|
}
|
|
|
|
def parse(structure: Structure, s: String)(f: Either[String, ScopedKey[_]] => Prop): Prop =
|
|
{
|
|
val parser = makeParser(structure)
|
|
val parsed = DefaultParsers.result(parser, s).left.map(_().toString)
|
|
val showParsed = parsed.right.map(displayFull)
|
|
("Key string: '" + s + "'") |:
|
|
("Parsed: " + showParsed) |:
|
|
("Structure: " + structure) |:
|
|
f(parsed)
|
|
}
|
|
|
|
def genStructure(implicit genEnv: Gen[Env]): Gen[Structure] =
|
|
structureGenF { (scopes: Seq[Scope], env: Env, current: ProjectRef) =>
|
|
val settings = for (scope <- scopes; t <- env.tasks) yield Def.setting(ScopedKey(scope, t.key), Def.value(""))
|
|
TestBuild.structure(env, settings, current)
|
|
}
|
|
|
|
def structureGenF(f: (Seq[Scope], Env, ProjectRef) => Structure)(implicit genEnv: Gen[Env]): Gen[Structure] =
|
|
structureGen((s, e, p) => Gen.value(f(s, e, p)))
|
|
def structureGen(f: (Seq[Scope], Env, ProjectRef) => Gen[Structure])(implicit genEnv: Gen[Env]): Gen[Structure] =
|
|
for {
|
|
env <- genEnv
|
|
loadFactor <- choose(0.0, 1.0)
|
|
scopes <- pickN(loadFactor, env.allFullScopes)
|
|
current <- oneOf(env.allProjects.unzip._1)
|
|
structure <- f(scopes, env, current)
|
|
} yield structure
|
|
|
|
def pickN[T](load: Double, from: Seq[T]): Gen[Seq[T]] =
|
|
pick((load * from.size).toInt, from)
|
|
}
|