From 536148a0e4f8421ea99a852a905d2b7c27165309 Mon Sep 17 00:00:00 2001 From: Claudio Maggioni Date: Mon, 16 Dec 2024 20:50:06 +0100 Subject: [PATCH] 1 done --- .../lecture10/GenerativeFluentAssertionsDSL.scala | 8 +++++++- .../GenerativeFluentAssertionsDSLSyntax.scala | 5 +++-- .../scala/ch/usi/si/msde/edsl/lecture10/Main.scala | 8 +++++++- .../msde/edsl/lecture10/ShouldBeTypeProvider.scala | 13 +++++++++---- 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/main/scala/ch/usi/si/msde/edsl/lecture10/GenerativeFluentAssertionsDSL.scala b/src/main/scala/ch/usi/si/msde/edsl/lecture10/GenerativeFluentAssertionsDSL.scala index deb6d18..2c252d3 100644 --- a/src/main/scala/ch/usi/si/msde/edsl/lecture10/GenerativeFluentAssertionsDSL.scala +++ b/src/main/scala/ch/usi/si/msde/edsl/lecture10/GenerativeFluentAssertionsDSL.scala @@ -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. ", diff --git a/src/main/scala/ch/usi/si/msde/edsl/lecture10/GenerativeFluentAssertionsDSLSyntax.scala b/src/main/scala/ch/usi/si/msde/edsl/lecture10/GenerativeFluentAssertionsDSLSyntax.scala index 6241edd..6cbfcaa 100644 --- a/src/main/scala/ch/usi/si/msde/edsl/lecture10/GenerativeFluentAssertionsDSLSyntax.scala +++ b/src/main/scala/ch/usi/si/msde/edsl/lecture10/GenerativeFluentAssertionsDSLSyntax.scala @@ -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) } diff --git a/src/main/scala/ch/usi/si/msde/edsl/lecture10/Main.scala b/src/main/scala/ch/usi/si/msde/edsl/lecture10/Main.scala index 4b3b853..dfb343d 100644 --- a/src/main/scala/ch/usi/si/msde/edsl/lecture10/Main.scala +++ b/src/main/scala/ch/usi/si/msde/edsl/lecture10/Main.scala @@ -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 diff --git a/src/main/scala/ch/usi/si/msde/edsl/lecture10/ShouldBeTypeProvider.scala b/src/main/scala/ch/usi/si/msde/edsl/lecture10/ShouldBeTypeProvider.scala index 0efb761..dab5632 100644 --- a/src/main/scala/ch/usi/si/msde/edsl/lecture10/ShouldBeTypeProvider.scala +++ b/src/main/scala/ch/usi/si/msde/edsl/lecture10/ShouldBeTypeProvider.scala @@ -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(