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,7 +83,13 @@ object GenerativeFluentAssertionsDSL:
) )
case '{ case '{
(${ typeProvider }: BePropertyTypeProvider[subjectType]) (${ typeProvider }: BePropertyTypeProvider[subjectType])
.applyDynamic($propertyNameExpr)($value) .applyDynamic($propertyNameExpr)($unit)
.$asInstanceOf$[AssertionProperty]
} =>
'{} // placeholder
case '{
(${ typeProvider }: BePropertyTypeProvider[subjectType])
.selectDynamic($propertyNameExpr)
.$asInstanceOf$[AssertionProperty] .$asInstanceOf$[AssertionProperty]
} => } =>
'{} // placeholder '{} // placeholder

View file

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

View file

@ -34,12 +34,18 @@ case class Box(label: String, weight: Mass, price: Money)
/* be.property assertions */ /* be.property assertions */
// assert(person.adult, ...) // assert(person.adult, ...)
person should make adult true person should be.adult
// assert(List().isEmpty, ...) // assert(List().isEmpty, ...)
List() should be.empty List() should be.empty
// assert(List(1,2,3).nonEmpty) // assert(List(1,2,3).nonEmpty)
List(1, 2, 3) should be.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 */ /* should have assertions */
// assert(List(1).head == 1, ...) // assert(List(1).head == 1, ...)
List(1) should have head 1 List(1) should have head 1

View file

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