diff --git a/main-settings/src/test/scala/sbt/BuildSettingsInstances.scala b/main-settings/src/test/scala/sbt/BuildSettingsInstances.scala index 00405643b..31c3869fe 100644 --- a/main-settings/src/test/scala/sbt/BuildSettingsInstances.scala +++ b/main-settings/src/test/scala/sbt/BuildSettingsInstances.scala @@ -5,134 +5,136 @@ * Copyright 2008 - 2010, Mark Harrah * Licensed under Apache License 2.0 (see LICENSE) */ -/* -package sbt.test -import org.scalacheck.{ Test => _, _ }, Arbitrary.arbitrary, Gen._ +package sbt +package test import java.io.File -import sbt.io.IO -import sbt.{ Scope, ScopeAxis, Scoped, Select, This, Zero } -import sbt.{ - BuildRef, - LocalProject, - LocalRootProject, - ProjectRef, - Reference, - RootProject, - ThisBuild, - ThisProject -} -import sbt.ConfigKey -import sbt.librarymanagement.syntax._ -import sbt.{ InputKey, SettingKey, TaskKey } -import sbt.internal.util.{ AttributeKey, AttributeMap } +import hedgehog.* import scala.annotation.nowarn +import scala.reflect.ClassTag +import _root_.sbt.io.IO +import _root_.sbt.Scoped.ScopingSetting +import _root_.sbt.librarymanagement.syntax.* +import _root_.sbt.internal.util.{ AttributeKey, AttributeMap } -object BuildSettingsInstances { - val genFile: Gen[File] = Gen.oneOf(new File("."), new File("/tmp")) // for now.. +object BuildSettingsInstances: + type Key[A1] = ScopingSetting[?] & Scoped - implicit val arbBuildRef: Arbitrary[BuildRef] = Arbitrary(genFile map (f => BuildRef(IO toURI f))) - - implicit val arbProjectRef: Arbitrary[ProjectRef] = - Arbitrary(for (f <- genFile; id <- Gen.identifier) yield ProjectRef(f, id)) - - implicit val arbLocalProject: Arbitrary[LocalProject] = - Arbitrary(arbitrary[String] map LocalProject) - - implicit val arbRootProject: Arbitrary[RootProject] = Arbitrary(genFile map (RootProject(_))) - - implicit val arbReference: Arbitrary[Reference] = Arbitrary { - Gen.frequency( - 96 -> arbitrary[BuildRef], - 10271 -> ThisBuild, - 325 -> LocalRootProject, - 2283 -> arbitrary[ProjectRef], - 299 -> ThisProject, - 436 -> arbitrary[LocalProject], - 1133 -> arbitrary[RootProject], + given Gen[Reference] = + val genFile: Gen[File] = + Gen.choice1(Gen.constant(new File(".")), Gen.constant(new File("/tmp"))) + given genBuildRef: Gen[BuildRef] = genFile.map: f => + BuildRef(IO.toURI(f)) + given genProjectRef: Gen[ProjectRef] = + for + f <- genFile + id <- identifier + yield ProjectRef(f, id) + given genLocalProject: Gen[LocalProject] = + identifier.map(LocalProject.apply) + given genRootProject: Gen[RootProject] = + genFile.map(RootProject.apply) + Gen.frequency1( + 96 -> genBuildRef.map(x => x: Reference), + 10271 -> Gen.constant(ThisBuild), + 325 -> Gen.constant(LocalRootProject), + 2283 -> genProjectRef.map(x => x: Reference), + 299 -> Gen.constant(ThisProject), + 436 -> genLocalProject.map(x => x: Reference), + 1133 -> genRootProject.map(x => x: Reference), ) - } @nowarn - implicit def arbConfigKey: Arbitrary[ConfigKey] = Arbitrary { - Gen.frequency( - 2 -> const[ConfigKey](Compile), - 2 -> const[ConfigKey](Test), - 1 -> const[ConfigKey](Runtime), - 1 -> const[ConfigKey](IntegrationTest), - 1 -> const[ConfigKey](Provided), - ) - } - - implicit def arbAttrKey[A: Manifest]: Arbitrary[AttributeKey[_]] = - Arbitrary(Gen.identifier map (AttributeKey[A](_))) - - implicit val arbAttributeMap: Arbitrary[AttributeMap] = Arbitrary { - Gen.frequency( - 20 -> AttributeMap.empty, - 1 -> { - for (name <- Gen.identifier; isModule <- arbitrary[Boolean]) - yield AttributeMap.empty - .put(AttributeKey[String]("name"), name) - .put(AttributeKey[Boolean]("isModule"), isModule) - } - ) - } - - implicit def arbScopeAxis[A: Arbitrary]: Arbitrary[ScopeAxis[A]] = - Arbitrary(Gen.oneOf[ScopeAxis[A]](This, Zero, arbitrary[A] map (Select(_)))) - - implicit def arbScope: Arbitrary[Scope] = Arbitrary( - for { - r <- arbitrary[ScopeAxis[Reference]] - c <- arbitrary[ScopeAxis[ConfigKey]] - t <- arbitrary[ScopeAxis[AttributeKey[_]]] - e <- arbitrary[ScopeAxis[AttributeMap]] - } yield Scope(r, c, t, e) + given Gen[ConfigKey] = Gen.frequency1( + 2 -> Gen.constant[ConfigKey](Compile), + 2 -> Gen.constant[ConfigKey](Test), + 1 -> Gen.constant[ConfigKey](Runtime), + 1 -> Gen.constant[ConfigKey](IntegrationTest), + 1 -> Gen.constant[ConfigKey](Provided), ) - type Key = K forSome { type K <: Scoped.ScopingSetting[K] with Scoped } + given genSettingKey[A1: ClassTag]: Gen[SettingKey[A1]] = + withScope(WithoutScope.genSettingKey) + given genTaskKey[A1: ClassTag]: Gen[TaskKey[A1]] = + withScope(WithoutScope.genTaskKey) + given genInputKey[A1: ClassTag]: Gen[InputKey[A1]] = + withScope(WithoutScope.genInputKey) + given genScopeAxis[A1: Gen]: Gen[ScopeAxis[A1]] = + Gen.choice1[ScopeAxis[A1]]( + Gen.constant(This), + Gen.constant(Zero), + summon[Gen[A1]].map(Select(_)) + ) - final case class Label(value: String) - val genLabel: Gen[Label] = Gen.identifier map Label - implicit def arbLabel: Arbitrary[Label] = Arbitrary(genLabel) + given genKey[A1: ClassTag]: Gen[Key[A1]] = + def convert[A2](g: Gen[A2]) = g.asInstanceOf[Gen[Key[A1]]] + Gen.frequency1( + 15431 -> convert(genInputKey), + 19645 -> convert(genSettingKey), + 22867 -> convert(genTaskKey), + ) - def genInputKey[A: Manifest]: Gen[InputKey[A]] = genLabel map (x => InputKey[A](x.value)) - def genSettingKey[A: Manifest]: Gen[SettingKey[A]] = genLabel map (x => SettingKey[A](x.value)) - def genTaskKey[A: Manifest]: Gen[TaskKey[A]] = genLabel map (x => TaskKey[A](x.value)) + given genAttrKey: Gen[AttributeKey[?]] = + identifier.map(AttributeKey[Unit](_)) - @nowarn - def withScope[K <: Scoped.ScopingSetting[K]](keyGen: Gen[K]): Arbitrary[K] = Arbitrary { - Gen.frequency( + given genAttributeMap: Gen[AttributeMap] = Gen.frequency1( + 20 -> Gen.constant(AttributeMap.empty), + 1 -> + (for + name <- identifier + isModule <- Gen.boolean + yield AttributeMap.empty + .put(AttributeKey[String]("name"), name) + .put(AttributeKey[Boolean]("isModule"), isModule)) + ) + + given Gen[Scope] = + for + r <- summon[Gen[ScopeAxis[Reference]]] + c <- summon[Gen[ScopeAxis[ConfigKey]]] + t <- summon[Gen[ScopeAxis[AttributeKey[?]]]] + e <- summon[Gen[ScopeAxis[AttributeMap]]] + yield Scope(r, c, t, e) + + def withScope[K <: Scoped.ScopingSetting[K]](keyGen: Gen[K]): Gen[K] = + Gen.frequency1( 5 -> keyGen, - 1 -> (for (key <- keyGen; scope <- arbitrary[Scope]) yield key in scope) + 1 -> (for + key <- keyGen + scope <- summon[Gen[Scope]] + yield key.rescope(scope)), ) - } - implicit def arbInputKey[A: Manifest]: Arbitrary[InputKey[A]] = withScope(genInputKey[A]) - implicit def arbSettingKey[A: Manifest]: Arbitrary[SettingKey[A]] = withScope(genSettingKey[A]) - implicit def arbTaskKey[A: Manifest]: Arbitrary[TaskKey[A]] = withScope(genTaskKey[A]) + case class Label(value: String) + object Label: + given genLabel: Gen[Label] = identifier.map(Label.apply) + end Label - implicit def arbKey[A: Manifest](implicit - arbInputKey: Arbitrary[InputKey[A]], - arbSettingKey: Arbitrary[SettingKey[A]], - arbTaskKey: Arbitrary[TaskKey[A]], - ): Arbitrary[Key] = Arbitrary { - def convert[T](g: Gen[T]) = g.asInstanceOf[Gen[Key]] - Gen.frequency( - 15431 -> convert(arbitrary[InputKey[A]]), - 19645 -> convert(arbitrary[SettingKey[A]]), - 22867 -> convert(arbitrary[TaskKey[A]]), + object WithoutScope: + def genSettingKey[A1: ClassTag]: Gen[SettingKey[A1]] = + Label.genLabel.map: label => + SettingKey[A1](label.value) + def genTaskKey[A1: ClassTag]: Gen[TaskKey[A1]] = + Label.genLabel.map: label => + TaskKey[A1](label.value) + def genInputKey[A1: ClassTag]: Gen[InputKey[A1]] = + Label.genLabel.map: label => + InputKey[A1](label.value) + end WithoutScope + + def identifier: Gen[String] = for + first <- Gen.char('a', 'z') + length <- Gen.int(Range.linear(0, 20)) + rest <- Gen.list( + Gen.frequency1( + 8 -> Gen.char('a', 'z'), + 8 -> Gen.char('A', 'Z'), + 5 -> Gen.char('0', '9'), + 1 -> Gen.constant('_') + ), + Range.singleton(length) ) - } + yield (first :: rest).mkString - object WithoutScope { - implicit def arbInputKey[A: Manifest]: Arbitrary[InputKey[A]] = Arbitrary(genInputKey[A]) - implicit def arbSettingKey[A: Manifest]: Arbitrary[SettingKey[A]] = Arbitrary(genSettingKey[A]) - implicit def arbTaskKey[A: Manifest]: Arbitrary[TaskKey[A]] = Arbitrary(genTaskKey[A]) - } - - implicit def arbScoped[A: Manifest]: Arbitrary[Scoped] = Arbitrary(arbitrary[Key]) -} - */ +end BuildSettingsInstances diff --git a/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala index f6816ca1d..9b71f48ce 100644 --- a/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala +++ b/main-settings/src/test/scala/sbt/SlashSyntaxSpec.scala @@ -5,109 +5,391 @@ * Copyright 2008 - 2010, Mark Harrah * Licensed under Apache License 2.0 (see LICENSE) */ -/* -package sbt.test -import org.scalacheck.{ Test => _, _ }, Prop._ +package sbt +package test -import sbt.SlashSyntax -import sbt.{ Scope, ScopeAxis, Scoped }, Scope.{ Global, ThisScope } -import sbt.Reference -import sbt.ConfigKey -import sbt.internal.util.AttributeKey +import hedgehog.* +import hedgehog.runner.* +import Scope.{ Global, ThisScope } +import SlashSyntax0.given +import BuildSettingsInstances.given +import _root_.sbt.internal.util.AttributeKey -import BuildSettingsInstances._ -import scala.annotation.nowarn +object SlashSyntaxSpec extends Properties: + override def tests: List[Test] = List( + property("Global / key", propGlobalKey), + property("Reference / key", propReferenceKey), + property("Reference / Config / key", propReferenceConfigKey), + property("Reference / task.key / key", propReferenceAttrKeyKey), + property("Reference / task / key", propReferenceTaskKey), + property("Reference / inputtask / key", propReferenceInputTaskKey), + property("Reference / Config / task.key / key", propReferenceConfigAttrKeyKey), + property("Reference / Config / task / key", propReferenceConfigTaskKey), + property("Reference / Config / inputtask / key", propReferenceConfigInputTaskKey), + property("Config / key", propConfigKey), + property("Config / task.key / key", propConfigAttrKeyKey), + property("Config / task / key", propConfigTaskKey), + property("Config / inputtask / key", propConfigInputTaskKey), + property("task.key / key", propAttrKeyKey), + property("task / key", propTaskKey), + property("inputtask / key", propInputTaskKey), + property("Scope / key", propScopeKey), + property("Reference? / key", propReferenceAxisKey), + property("Reference? / Config? / key", propReferenceAxisConfigAxisKey), + // property("Reference? / task.key? / key", propReferenceAxisAttrKeyAxisKey), + property("Reference? / Config? / task.key? / key", propReferenceAxisConfigAxisAttrKeyAxisKey), + ) -@nowarn -object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax { - property("Global / key == key in Global") = { - forAll((k: Key) => expectValue(k in Global)(Global / k)) - } + def gen[A1: Gen]: Gen[A1] = summon[Gen[A1]] - property("Reference / key == key in Reference") = { - forAll((r: Reference, k: Key) => expectValue(k in r)(r / k)) - } - - property("Reference / Config / key == key in Reference in Config") = { - forAll((r: Reference, c: ConfigKey, k: Key) => expectValue(k in r in c)(r / c / k)) - } - - property("Reference / task.key / key == key in Reference in task") = { - forAll((r: Reference, t: Scoped, k: Key) => expectValue(k in (r, t))(r / t.key / k)) - } - - property("Reference / task / key ~= key in Reference in task") = { - import WithoutScope._ - forAll((r: Reference, t: Key, k: Key) => expectValue(k in (r, t))(r / t / k)) - } - - property("Reference / Config / task.key / key == key in Reference in Config in task") = { - forAll { (r: Reference, c: ConfigKey, t: Scoped, k: Key) => - expectValue(k in (r, c, t))(r / c / t.key / k) - } - } - - property("Reference / Config / task / key ~= key in Reference in Config in task") = { - import WithoutScope._ - forAll { (r: Reference, c: ConfigKey, t: Key, k: Key) => - expectValue(k in (r, c, t))(r / c / t / k) - } - } - - property("Config / key == key in Config") = { - forAll((c: ConfigKey, k: Key) => expectValue(k in c)(c / k)) - } - - property("Config / task.key / key == key in Config in task") = { - forAll((c: ConfigKey, t: Scoped, k: Key) => expectValue(k in c in t)(c / t.key / k)) - } - - property("Config / task / key ~= key in Config in task") = { - import WithoutScope._ - forAll((c: ConfigKey, t: Key, k: Key) => expectValue(k in c in t)(c / t / k)) - } - - property("task.key / key == key in task") = { - forAll((t: Scoped, k: Key) => expectValue(k in t)(t.key / k)) - } - - property("task / key ~= key in task") = { - import WithoutScope._ - forAll((t: Key, k: Key) => expectValue(k in t)(t / k)) - } - - property("Scope / key == key in Scope") = { - forAll((s: Scope, k: Key) => expectValue(k in s)(s / k)) - } - - property("Reference? / key == key in ThisScope.copy(..)") = { - forAll { (r: ScopeAxis[Reference], k: Key) => - expectValue(k in ThisScope.copy(project = r))(r / k) - } - } - - property("Reference? / ConfigKey? / key == key in ThisScope.copy(..)") = { - forAll((r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], k: Key) => - expectValue(k in ThisScope.copy(project = r, config = c))(r / c / k) + def propGlobalKey: Property = + for + k <- genKey[Unit].forAll + actual = k match + case k: InputKey[?] => Global / k + case k: TaskKey[?] => Global / k + case k: SettingKey[?] => Global / k + yield Result.assert( + actual.key == k.key && + // Only if the incoming scope is This/This/This, + // Global scoping is effective. + (if k.scope == ThisScope then actual.scope == Global + else true) ) - } -// property("Reference? / AttributeKey? / key == key in ThisScope.copy(..)") = { -// forAll((r: ScopeAxis[Reference], t: ScopeAxis[AttributeKey[_]], k: AnyKey) => -// expectValue(k in ThisScope.copy(project = r, task = t))(r / t / k)) -// } + def propReferenceKey: Property = + for + ref <- gen[Reference].forAll + k <- genKey[Unit].forAll + actual = k match + case k: InputKey[?] => ref / k + case k: TaskKey[?] => ref / k + case k: SettingKey[?] => ref / k + yield Result.assert( + actual.key == k.key && + (if k.scope.project == This then actual.scope.project == Select(ref) + else true) + ) - property("Reference? / ConfigKey? / AttributeKey? / key == key in ThisScope.copy(..)") = { - forAll { - (r: ScopeAxis[Reference], c: ScopeAxis[ConfigKey], t: ScopeAxis[AttributeKey[_]], k: Key) => - expectValue(k in ThisScope.copy(project = r, config = c, task = t))(r / c / t / k) - } - } + def propReferenceConfigKey: Property = + for + ref <- gen[Reference].forAll + config <- gen[ConfigKey].forAll + k <- genKey[Unit].forAll + actual = k match + case k: InputKey[?] => ref / config / k + case k: TaskKey[?] => ref / config / k + case k: SettingKey[?] => ref / config / k + yield Result.assert( + actual.key == k.key && + (if k.scope.project == This then actual.scope.project == Select(ref) + else true) && + (if k.scope.config == This then actual.scope.config == Select(config) + else true) + ) - def expectValue(expected: Scoped)(x: Scoped) = { - val equals = x.scope == expected.scope && x.key == expected.key - if (equals) proved else falsified :| s"Expected $expected but got $x" - } -} - */ + def propReferenceAttrKeyKey: Property = + for + ref <- gen[Reference].forAll + scoped <- genKey[Unit].forAll + k <- genKey[Unit].forAll + actual = k match + case k: InputKey[?] => ref / scoped.key / k + case k: TaskKey[?] => ref / scoped.key / k + case k: SettingKey[?] => ref / scoped.key / k + yield Result.assert( + actual.key == k.key && + (if k.scope.project == This then actual.scope.project == Select(ref) + else true) && + (if k.scope.task == This then actual.scope.task == Select(scoped.key) + else true) + ) + + def propReferenceTaskKey: Property = + for + ref <- gen[Reference].forAll + t <- genTaskKey[Unit].forAll + k <- genKey[Unit].forAll + actual = k match + case k: InputKey[?] => ref / t / k + case k: TaskKey[?] => ref / t / k + case k: SettingKey[?] => ref / t / k + yield Result.assert( + actual.key == k.key && + (if k.scope.project == This then actual.scope.project == Select(ref) + else true) && + (if k.scope.task == This then actual.scope.task == Select(t.key) + else true) + ) + + def propReferenceInputTaskKey: Property = + for + ref <- gen[Reference].forAll + t <- genInputKey[Unit].forAll + k <- genKey[Unit].forAll + actual = k match + case k: InputKey[?] => ref / t / k + case k: TaskKey[?] => ref / t / k + case k: SettingKey[?] => ref / t / k + yield Result.assert( + actual.key == k.key && + (if k.scope.project == This then actual.scope.project == Select(ref) + else true) && + (if k.scope.task == This then actual.scope.task == Select(t.key) + else true) + ) + + def propReferenceConfigAttrKeyKey: Property = + for + ref <- gen[Reference].forAll + config <- gen[ConfigKey].forAll + scoped <- genKey[Unit].forAll + k <- genKey[Unit].forAll + actual = k match + case k: InputKey[?] => ref / config / scoped.key / k + case k: TaskKey[?] => ref / config / scoped.key / k + case k: SettingKey[?] => ref / config / scoped.key / k + yield Result.assert( + actual.key == k.key && + (if k.scope.project == This then actual.scope.project == Select(ref) + else true) && + (if k.scope.config == This then actual.scope.config == Select(config) + else true) && + (if k.scope.task == This then actual.scope.task == Select(scoped.key) + else true) + ) + + def propReferenceConfigTaskKey: Property = + for + ref <- gen[Reference].forAll + config <- gen[ConfigKey].forAll + t <- genTaskKey[Unit].forAll + k <- genKey[Unit].forAll + actual = k match + case k: InputKey[?] => ref / config / t / k + case k: TaskKey[?] => ref / config / t / k + case k: SettingKey[?] => ref / config / t / k + yield Result.assert( + actual.key == k.key && + (if k.scope.project == This then actual.scope.project == Select(ref) + else true) && + (if k.scope.config == This then actual.scope.config == Select(config) + else true) && + (if k.scope.task == This then actual.scope.task == Select(t.key) + else true) + ) + + def propReferenceConfigInputTaskKey: Property = + for + ref <- gen[Reference].forAll + config <- gen[ConfigKey].forAll + t <- genInputKey[Unit].forAll + k <- genKey[Unit].forAll + actual = k match + case k: InputKey[?] => ref / config / t / k + case k: TaskKey[?] => ref / config / t / k + case k: SettingKey[?] => ref / config / t / k + yield Result.assert( + actual.key == k.key && + (if k.scope.project == This then actual.scope.project == Select(ref) + else true) && + (if k.scope.config == This then actual.scope.config == Select(config) + else true) && + (if k.scope.task == This then actual.scope.task == Select(t.key) + else true) + ) + + def propConfigKey: Property = + for + config <- gen[ConfigKey].forAll + k <- genKey[Unit].forAll + actual = k match + case k: InputKey[?] => config / k + case k: TaskKey[?] => config / k + case k: SettingKey[?] => config / k + yield Result.assert( + actual.key == k.key && + (if k.scope.config == This then actual.scope.config == Select(config) + else true) + ) + + def propConfigAttrKeyKey: Property = + for + config <- gen[ConfigKey].forAll + scoped <- genKey[Unit].forAll + k <- genKey[Unit].forAll + actual = k match + case k: InputKey[?] => config / scoped.key / k + case k: TaskKey[?] => config / scoped.key / k + case k: SettingKey[?] => config / scoped.key / k + yield Result.assert( + actual.key == k.key && + (if k.scope.config == This then actual.scope.config == Select(config) + else true) && + (if k.scope.task == This then actual.scope.task == Select(scoped.key) + else true) + ) + + def propConfigTaskKey: Property = + for + config <- gen[ConfigKey].forAll + t <- genTaskKey[Unit].forAll + k <- genKey[Unit].forAll + actual = k match + case k: InputKey[?] => config / t / k + case k: TaskKey[?] => config / t / k + case k: SettingKey[?] => config / t / k + yield Result.assert( + actual.key == k.key && + (if k.scope.config == This then actual.scope.config == Select(config) + else true) && + (if k.scope.task == This then actual.scope.task == Select(t.key) + else true) + ) + + def propConfigInputTaskKey: Property = + for + config <- gen[ConfigKey].forAll + t <- genInputKey[Unit].forAll + k <- genKey[Unit].forAll + actual = k match + case k: InputKey[?] => config / t / k + case k: TaskKey[?] => config / t / k + case k: SettingKey[?] => config / t / k + yield Result.assert( + actual.key == k.key && + (if k.scope.config == This then actual.scope.config == Select(config) + else true) && + (if k.scope.task == This then actual.scope.task == Select(t.key) + else true) + ) + + def propAttrKeyKey: Property = + for + scoped <- genKey[Unit].forAll + k <- genKey[Unit].forAll + actual = k match + case k: InputKey[?] => scoped.key / k + case k: TaskKey[?] => scoped.key / k + case k: SettingKey[?] => scoped.key / k + yield Result.assert( + actual.key == k.key && + (if k.scope.task == This then actual.scope.task == Select(scoped.key) + else true) + ) + + def propTaskKey: Property = + for + t <- genTaskKey[Unit].forAll + k <- genKey[Unit].forAll + actual = k match + case k: InputKey[?] => t / k + case k: TaskKey[?] => t / k + case k: SettingKey[?] => t / k + yield Result.assert( + actual.key == k.key && + (if k.scope.task == This then actual.scope.task == Select(t.key) + else true) + ) + + def propInputTaskKey: Property = + for + t <- genInputKey[Unit].forAll + k <- genKey[Unit].forAll + actual = k match + case k: InputKey[?] => t / k + case k: TaskKey[?] => t / k + case k: SettingKey[?] => t / k + yield Result.assert( + actual.key == k.key && + (if k.scope.task == This then actual.scope.task == Select(t.key) + else true) + ) + + def propScopeKey: Property = + for + scope <- gen[Scope].forAll + k <- genKey[Unit].forAll + actual = k match + case k: InputKey[?] => scope / k + case k: TaskKey[?] => scope / k + case k: SettingKey[?] => scope / k + yield Result.assert( + actual.key == k.key && + // Only if the incoming scope is This/This/This, + // Global scoping is effective. + (if k.scope == ThisScope then actual.scope == scope + else true) + ) + + def propReferenceAxisKey: Property = + for + ref <- gen[ScopeAxis[Reference]].forAll + k <- genKey[Unit].forAll + actual = k match + case k: InputKey[?] => ref / k + case k: TaskKey[?] => ref / k + case k: SettingKey[?] => ref / k + yield Result.assert( + actual.key == k.key && + (if k.scope.project == This then actual.scope.project == ref + else true) + ) + + def propReferenceAxisConfigAxisKey: Property = + for + ref <- gen[ScopeAxis[Reference]].forAll + config <- gen[ScopeAxis[ConfigKey]].forAll + k <- genKey[Unit].forAll + actual = k match + case k: InputKey[?] => ref / config / k + case k: TaskKey[?] => ref / config / k + case k: SettingKey[?] => ref / config / k + yield Result.assert( + actual.key == k.key && + (if k.scope.project == This then actual.scope.project == ref + else true) && + (if k.scope.config == This then actual.scope.config == config + else true) + ) + + /* + def propReferenceAxisAttrKeyAxisKey: Property = + for + ref <- gen[ScopeAxis[Reference]].forAll + t <- gen[ScopeAxis[AttributeKey[?]]].forAll + k <- genKey[Unit].forAll + actual = k match + case k: InputKey[?] => ref / t / k + case k: TaskKey[?] => ref / t / k + case k: SettingKey[?] => ref / t / k + yield Result.assert( + actual.key == k.key && + (if k.scope.project == This then actual.scope.project == ref + else true) && + (if k.scope.task == This then actual.scope.task == t + else true) + ) + */ + + def propReferenceAxisConfigAxisAttrKeyAxisKey: Property = + for + ref <- gen[ScopeAxis[Reference]].forAll + config <- gen[ScopeAxis[ConfigKey]].forAll + t <- gen[ScopeAxis[AttributeKey[?]]].forAll + k <- genKey[Unit].forAll + actual = k match + case k: InputKey[?] => ref / config / t / k + case k: TaskKey[?] => ref / config / t / k + case k: SettingKey[?] => ref / config / t / k + yield Result.assert( + actual.key == k.key && + (if k.scope.project == This then actual.scope.project == ref + else true) && + (if k.scope.config == This then actual.scope.config == config + else true) && + (if k.scope.task == This then actual.scope.task == t + else true) + ) +end SlashSyntaxSpec