mirror of https://github.com/sbt/sbt.git
Merge pull request #4041 from dwijnand/Scoped.equals
Give Scoped a default equals/hashCode implementation
This commit is contained in:
commit
54a6262f7f
|
|
@ -492,6 +492,10 @@ lazy val mainSettingsProj = (project in file("main-settings"))
|
||||||
mimaSettings,
|
mimaSettings,
|
||||||
mimaBinaryIssueFilters ++= Seq(
|
mimaBinaryIssueFilters ++= Seq(
|
||||||
exclude[DirectMissingMethodProblem]("sbt.Scope.display012StyleMasked"),
|
exclude[DirectMissingMethodProblem]("sbt.Scope.display012StyleMasked"),
|
||||||
|
|
||||||
|
// added a method to a sealed trait
|
||||||
|
exclude[InheritedNewAbstractMethodProblem]("sbt.Scoped.canEqual"),
|
||||||
|
exclude[InheritedNewAbstractMethodProblem]("sbt.ScopedTaskable.canEqual"),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.configure(
|
.configure(
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,18 @@ import sbt.Def.{ Initialize, KeyedInitialize, ScopedKey, Setting, setting }
|
||||||
import std.TaskExtra.{ task => mktask, _ }
|
import std.TaskExtra.{ task => mktask, _ }
|
||||||
|
|
||||||
/** An abstraction on top of Settings for build configuration and task definition. */
|
/** An abstraction on top of Settings for build configuration and task definition. */
|
||||||
sealed trait Scoped { def scope: Scope; val key: AttributeKey[_] }
|
sealed trait Scoped extends Equals {
|
||||||
|
def scope: Scope
|
||||||
|
val key: AttributeKey[_]
|
||||||
|
|
||||||
|
override def equals(that: Any) =
|
||||||
|
(this eq that.asInstanceOf[AnyRef]) || (that match {
|
||||||
|
case that: Scoped => scope == that.scope && key == that.key && canEqual(that)
|
||||||
|
case _ => false
|
||||||
|
})
|
||||||
|
|
||||||
|
override def hashCode() = (scope, key).##
|
||||||
|
}
|
||||||
|
|
||||||
/** A common type for SettingKey and TaskKey so that both can be used as inputs to tasks.*/
|
/** A common type for SettingKey and TaskKey so that both can be used as inputs to tasks.*/
|
||||||
sealed trait ScopedTaskable[T] extends Scoped {
|
sealed trait ScopedTaskable[T] extends Scoped {
|
||||||
|
|
@ -95,6 +106,8 @@ sealed abstract class SettingKey[T]
|
||||||
|
|
||||||
final def withRank(rank: Int): SettingKey[T] =
|
final def withRank(rank: Int): SettingKey[T] =
|
||||||
SettingKey(AttributeKey.copyWithRank(key, rank))
|
SettingKey(AttributeKey.copyWithRank(key, rank))
|
||||||
|
|
||||||
|
def canEqual(that: Any): Boolean = that.isInstanceOf[SettingKey[_]]
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -163,6 +176,8 @@ sealed abstract class TaskKey[T]
|
||||||
|
|
||||||
final def withRank(rank: Int): TaskKey[T] =
|
final def withRank(rank: Int): TaskKey[T] =
|
||||||
TaskKey(AttributeKey.copyWithRank(key, rank))
|
TaskKey(AttributeKey.copyWithRank(key, rank))
|
||||||
|
|
||||||
|
def canEqual(that: Any): Boolean = that.isInstanceOf[TaskKey[_]]
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -195,6 +210,8 @@ sealed trait InputKey[T]
|
||||||
|
|
||||||
final def withRank(rank: Int): InputKey[T] =
|
final def withRank(rank: Int): InputKey[T] =
|
||||||
InputKey(AttributeKey.copyWithRank(key, rank))
|
InputKey(AttributeKey.copyWithRank(key, rank))
|
||||||
|
|
||||||
|
def canEqual(that: Any): Boolean = that.isInstanceOf[InputKey[_]]
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Methods and types related to constructing settings, including keys, scopes, and initializations. */
|
/** Methods and types related to constructing settings, including keys, scopes, and initializations. */
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,135 @@
|
||||||
|
/*
|
||||||
|
* sbt
|
||||||
|
* Copyright 2011 - 2017, Lightbend, Inc.
|
||||||
|
* Copyright 2008 - 2010, Mark Harrah
|
||||||
|
* Licensed under BSD-3-Clause license (see LICENSE)
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sbt.test
|
||||||
|
|
||||||
|
import org.scalacheck.{ Test => _, _ }, Arbitrary.arbitrary, Gen._
|
||||||
|
|
||||||
|
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 }
|
||||||
|
|
||||||
|
object BuildSettingsInstances {
|
||||||
|
val genFile: Gen[File] = Gen.oneOf(new File("."), new File("/tmp")) // for now..
|
||||||
|
|
||||||
|
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],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
)
|
||||||
|
|
||||||
|
type Key = K forSome { type K <: Scoped.ScopingSetting[K] with Scoped }
|
||||||
|
|
||||||
|
final case class Label(value: String)
|
||||||
|
val genLabel: Gen[Label] = Gen.identifier map Label
|
||||||
|
implicit def arbLabel: Arbitrary[Label] = Arbitrary(genLabel)
|
||||||
|
|
||||||
|
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))
|
||||||
|
|
||||||
|
def withScope[K <: Scoped.ScopingSetting[K]](keyGen: Gen[K]): Arbitrary[K] = Arbitrary {
|
||||||
|
Gen.frequency(
|
||||||
|
5 -> keyGen,
|
||||||
|
1 -> (for (key <- keyGen; scope <- arbitrary[Scope]) yield key in 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])
|
||||||
|
|
||||||
|
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 {
|
||||||
|
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])
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,145 @@
|
||||||
|
/*
|
||||||
|
* sbt
|
||||||
|
* Copyright 2011 - 2017, Lightbend, Inc.
|
||||||
|
* Copyright 2008 - 2010, Mark Harrah
|
||||||
|
* Licensed under BSD-3-Clause license (see LICENSE)
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sbt.test
|
||||||
|
|
||||||
|
import org.scalacheck._, Prop._, util.Pretty
|
||||||
|
|
||||||
|
import sbt.internal.util.AttributeKey
|
||||||
|
import sbt.util.NoJsonWriter
|
||||||
|
import sbt.{ InputTask, Scope, Task }
|
||||||
|
import sbt.{ InputKey, Scoped, SettingKey, TaskKey }
|
||||||
|
|
||||||
|
import BuildSettingsInstances._
|
||||||
|
|
||||||
|
object ScopedSpec extends Properties("Scoped") {
|
||||||
|
val intManifest = manifest[Int]
|
||||||
|
val stringManifest = manifest[String]
|
||||||
|
|
||||||
|
implicit val arbManifest: Arbitrary[Manifest[_]] =
|
||||||
|
Arbitrary(Gen.oneOf(intManifest, stringManifest))
|
||||||
|
|
||||||
|
property("setting keys are structurally equal") = {
|
||||||
|
forAll { (label: Label, manifest: Manifest[_], scope: Scope) =>
|
||||||
|
val k1 = settingKey(label, manifest, scope)
|
||||||
|
val k2 = settingKey(label, manifest, scope)
|
||||||
|
expectEq(k1, k2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
property("task keys are structurally equal") = {
|
||||||
|
forAll { (label: Label, manifest: Manifest[_], scope: Scope) =>
|
||||||
|
val k1 = taskKey(label, manifest, scope)
|
||||||
|
val k2 = taskKey(label, manifest, scope)
|
||||||
|
expectEq(k1, k2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
property("input keys are structurally equal") = {
|
||||||
|
forAll { (label: Label, manifest: Manifest[_], scope: Scope) =>
|
||||||
|
val k1 = inputKey(label, manifest, scope)
|
||||||
|
val k2 = inputKey(label, manifest, scope)
|
||||||
|
expectEq(k1, k2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
property("different key types are not equal") = {
|
||||||
|
forAll { (label: Label, manifest: Manifest[_], scope: Scope) =>
|
||||||
|
val settingKey1 = settingKey(label, manifest, scope)
|
||||||
|
val taskKey1 = taskKey(label, manifest, scope)
|
||||||
|
val inputKey1 = inputKey(label, manifest, scope)
|
||||||
|
|
||||||
|
all(
|
||||||
|
expectNe(settingKey1, taskKey1),
|
||||||
|
expectNe(settingKey1, inputKey1),
|
||||||
|
expectNe(taskKey1, inputKey1),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
property("different key types, with the same manifest, are not equal") = {
|
||||||
|
forAll { (label: Label, scope: Scope) =>
|
||||||
|
val prop1 = {
|
||||||
|
val manifest1 = manifest[Task[String]]
|
||||||
|
val attrKey = attributeKey(label, manifest1)
|
||||||
|
val k1 = SettingKey(attrKey) in scope
|
||||||
|
val k2 = TaskKey(attrKey) in scope
|
||||||
|
expectNeSameManifest(k1, k2)
|
||||||
|
}
|
||||||
|
|
||||||
|
val prop2 = {
|
||||||
|
val manifest1 = manifest[InputTask[String]]
|
||||||
|
val attrKey = attributeKey(label, manifest1)
|
||||||
|
val k1 = SettingKey(attrKey) in scope
|
||||||
|
val k2 = InputKey(attrKey) in scope
|
||||||
|
expectNeSameManifest(k1, k2)
|
||||||
|
}
|
||||||
|
|
||||||
|
all(prop1, prop2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
def settingKey[A](label: Label, manifest: Manifest[A], scope: Scope): SettingKey[A] = {
|
||||||
|
val noJsonWriter = NoJsonWriter[A]()
|
||||||
|
SettingKey[A](label.value)(manifest, noJsonWriter) in scope
|
||||||
|
}
|
||||||
|
|
||||||
|
def taskKey[A](label: Label, manifest: Manifest[A], s: Scope): TaskKey[A] =
|
||||||
|
TaskKey[A](label.value)(manifest) in s
|
||||||
|
|
||||||
|
def inputKey[A](label: Label, manifest: Manifest[A], scope: Scope): InputKey[A] =
|
||||||
|
InputKey[A](label.value)(manifest) in scope
|
||||||
|
|
||||||
|
def attributeKey[A](label: Label, manifest: Manifest[A]): AttributeKey[A] = {
|
||||||
|
val jsonWriter = NoJsonWriter[A]()
|
||||||
|
AttributeKey[A](label.value)(manifest, jsonWriter)
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
|
||||||
|
def expectEq(k1: Scoped, k2: Scoped): Prop =
|
||||||
|
?=(k1, k2) && ?=(k2, k1) map eqLabels(k1, k2)
|
||||||
|
|
||||||
|
def expectNe(k1: Scoped, k2: Scoped): Prop =
|
||||||
|
!=(k1, k2) && !=(k2, k1) map eqLabels(k1, k2)
|
||||||
|
|
||||||
|
def expectNeSameManifest(k1: Scoped, k2: Scoped) = {
|
||||||
|
all(
|
||||||
|
?=(k1.key.manifest, k2.key.manifest), // sanity check the manifests are the same
|
||||||
|
expectNe(k1, k2),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
def eqLabels(k1: Scoped, k2: Scoped): Prop.Result => Prop.Result = r => {
|
||||||
|
val eqLabel = k1.key.label == k2.key.label
|
||||||
|
val eqManifest = k1.key.manifest == k2.key.manifest
|
||||||
|
val eqScope = k1.scope == k2.scope
|
||||||
|
r.label(s"label equality: ${k1.key.label} == ${k2.key.label} : $eqLabel")
|
||||||
|
.label(s"manifest equality: ${k1.key.manifest} == ${k2.key.manifest} : $eqManifest")
|
||||||
|
.label(s"scope equality: ${k1.scope} == ${k2.scope} : $eqScope")
|
||||||
|
}
|
||||||
|
|
||||||
|
def ?=[T](x: T, y: T)(implicit pp: T => Pretty): Prop =
|
||||||
|
if (x == y) proved
|
||||||
|
else
|
||||||
|
falsified :| {
|
||||||
|
val act = Pretty.pretty[T](x, Pretty.Params(0))
|
||||||
|
val exp = Pretty.pretty[T](y, Pretty.Params(0))
|
||||||
|
s"Expected $act to be equal to $exp"
|
||||||
|
}
|
||||||
|
|
||||||
|
def !=[T](x: T, y: T)(implicit pp: T => Pretty): Prop =
|
||||||
|
if (x == y) falsified
|
||||||
|
else
|
||||||
|
proved :| {
|
||||||
|
val act = Pretty.pretty[T](x, Pretty.Params(0))
|
||||||
|
val exp = Pretty.pretty[T](y, Pretty.Params(0))
|
||||||
|
s"Expected $act to NOT be equal to $exp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,130 +7,15 @@
|
||||||
|
|
||||||
package sbt.test
|
package sbt.test
|
||||||
|
|
||||||
import org.scalacheck.{ Test => _, _ }, Arbitrary.arbitrary, Gen._, Prop._
|
import org.scalacheck.{ Test => _, _ }, Prop._
|
||||||
|
|
||||||
import java.io.File
|
|
||||||
import sbt.io.IO
|
|
||||||
import sbt.SlashSyntax
|
import sbt.SlashSyntax
|
||||||
import sbt.{ Scope, ScopeAxis, Scoped, Select, This, Zero }, Scope.{ Global, ThisScope }
|
import sbt.{ Scope, ScopeAxis, Scoped }, Scope.{ Global, ThisScope }
|
||||||
import sbt.{
|
import sbt.Reference
|
||||||
BuildRef,
|
|
||||||
LocalProject,
|
|
||||||
LocalRootProject,
|
|
||||||
ProjectRef,
|
|
||||||
Reference,
|
|
||||||
RootProject,
|
|
||||||
ThisBuild,
|
|
||||||
ThisProject
|
|
||||||
}
|
|
||||||
import sbt.ConfigKey
|
import sbt.ConfigKey
|
||||||
import sbt.librarymanagement.syntax._
|
import sbt.internal.util.AttributeKey
|
||||||
import sbt.{ InputKey, SettingKey, TaskKey }
|
|
||||||
import sbt.internal.util.{ AttributeKey, AttributeMap }
|
|
||||||
|
|
||||||
object BuildDSLInstances {
|
import BuildSettingsInstances._
|
||||||
val genFile: Gen[File] = Gen.oneOf(new File("."), new File("/tmp")) // for now..
|
|
||||||
|
|
||||||
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],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
)
|
|
||||||
|
|
||||||
type Key = K forSome { type K <: Scoped.ScopingSetting[K] with Scoped }
|
|
||||||
|
|
||||||
def genInputKey[A: Manifest]: Gen[InputKey[A]] = Gen.identifier map (InputKey[A](_))
|
|
||||||
def genSettingKey[A: Manifest]: Gen[SettingKey[A]] = Gen.identifier map (SettingKey[A](_))
|
|
||||||
def genTaskKey[A: Manifest]: Gen[TaskKey[A]] = Gen.identifier map (TaskKey[A](_))
|
|
||||||
|
|
||||||
def withScope[K <: Scoped.ScopingSetting[K]](keyGen: Gen[K]): Arbitrary[K] = Arbitrary {
|
|
||||||
Gen.frequency(
|
|
||||||
5 -> keyGen,
|
|
||||||
1 -> (for (key <- keyGen; scope <- arbitrary[Scope]) yield key in 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])
|
|
||||||
|
|
||||||
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 {
|
|
||||||
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])
|
|
||||||
}
|
|
||||||
import BuildDSLInstances._
|
|
||||||
|
|
||||||
object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax {
|
object SlashSyntaxSpec extends Properties("SlashSyntax") with SlashSyntax {
|
||||||
property("Global / key == key in Global") = {
|
property("Global / key == key in Global") = {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
scalaVersion := "2.12.4"
|
scalaVersion := "2.12.4"
|
||||||
scalacOptions ++= Seq("-feature", "-language:postfixOps")
|
scalacOptions ++= Seq("-feature", "-language:postfixOps")
|
||||||
|
|
||||||
|
addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.2.0")
|
||||||
addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.5")
|
addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.5")
|
||||||
addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.4.0")
|
addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.4.0")
|
||||||
addSbtPlugin("de.heikoseeberger" % "sbt-header" % "3.0.2")
|
addSbtPlugin("de.heikoseeberger" % "sbt-header" % "3.0.2")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue