This commit is contained in:
Claudio Maggioni 2024-12-16 20:50:06 +01:00
parent 32f106c61f
commit 536148a0e4
4 changed files with 26 additions and 8 deletions

View file

@ -83,10 +83,16 @@ object GenerativeFluentAssertionsDSL:
)
case '{
(${ typeProvider }: BePropertyTypeProvider[subjectType])
.applyDynamic($propertyNameExpr)($value)
.applyDynamic($propertyNameExpr)($unit)
.$asInstanceOf$[AssertionProperty]
} =>
'{} // placeholder
case '{
(${ typeProvider }: BePropertyTypeProvider[subjectType])
.selectDynamic($propertyNameExpr)
.$asInstanceOf$[AssertionProperty]
} =>
'{} // placeholder
case _ =>
report.errorAndAbort(
"Invalid expression, must be a 'should be' or 'should have' assertion. ",

View file

@ -13,6 +13,7 @@ class DynamicShouldBeProperty extends AssertionProperty with Dynamic:
end DynamicShouldBeProperty
class BePropertyTypeProvider[T](val subject: T) extends Selectable:
def selectDynamic(fieldName: String): AssertionProperty = ???
def applyDynamic(fieldName: String)(foo: Any*): AssertionProperty = ???
end BePropertyTypeProvider
@ -36,7 +37,7 @@ end HavePropertyTypeProvider
sealed trait AssertionDSLVerb
case object be extends AssertionDSLVerb with Dynamic:
def selectDynamic(fieldName: String): AssertionProperty = ???
case object make extends AssertionDSLVerb
case object be_ extends AssertionDSLVerb
case object have extends AssertionDSLVerb
/** Implicit class to add 'should' assertions to a generic type T.
@ -56,7 +57,7 @@ extension [T](subject: T)
*/
def should(property: AssertionProperty) = ???
transparent inline def should(inline verbWord: make.type) = ${
transparent inline def should(inline verbWord: be_.type) = ${
ShouldBeTypeProvider.generateShouldBeTypeProvider[T]('subject)
}

View file

@ -34,12 +34,18 @@ case class Box(label: String, weight: Mass, price: Money)
/* be.property assertions */
// assert(person.adult, ...)
person should make adult true
person should be.adult
// assert(List().isEmpty, ...)
List() should be.empty
// assert(List(1,2,3).nonEmpty)
List(1, 2, 3) should be.nonEmpty
// New syntax for `be` with type provider
// either adult is a method with a dummy Unit parameter
person should be_ adult()
// or adult is a property but braces are needed to resolve the type provider
(person should be_).adult
/* should have assertions */
// assert(List(1).head == 1, ...)
List(1) should have head 1

View file

@ -14,12 +14,17 @@ object ShouldBeTypeProvider:
currentTypeRepr: TypeRepr,
symbol: Symbol
): TypeRepr =
val methodType = MethodType(List("value"))(
_ => List(TypeRepr.of[true]),
// refine both as unary method with unit parameter and as property
// and let client code choose
val methodType = MethodType(List("unit"))(
_ => List(TypeRepr.of[Unit]),
_ => TypeRepr.of[AssertionProperty]
)
// val methodType = TypeRepr.of[AssertionProperty]
Refinement(currentTypeRepr, symbol.name, methodType)
Refinement(
Refinement(currentTypeRepr, symbol.name, TypeRepr.of[AssertionProperty]),
symbol.name,
methodType
)
@tailrec
def refineTypeBySymbols(