From e718ce97f4930ca4f7e1a0890ee9cb475c875ddb Mon Sep 17 00:00:00 2001 From: reidspencer Date: Fri, 17 Nov 2023 13:26:26 -0500 Subject: [PATCH 1/5] Add a test case for issue #480 Signed-off-by: reidspencer --- .../passes/resolve/ResolutionPassTest.scala | 68 +++++++++++++++---- 1 file changed, 56 insertions(+), 12 deletions(-) diff --git a/passes/src/test/scala/com/reactific/riddl/passes/resolve/ResolutionPassTest.scala b/passes/src/test/scala/com/reactific/riddl/passes/resolve/ResolutionPassTest.scala index 792219642..ef771bae8 100644 --- a/passes/src/test/scala/com/reactific/riddl/passes/resolve/ResolutionPassTest.scala +++ b/passes/src/test/scala/com/reactific/riddl/passes/resolve/ResolutionPassTest.scala @@ -91,7 +91,7 @@ class ResolutionPassTest extends ResolvingTest { | } |} |""".stripMargin - parseAndResolve(RiddlParserInput(input)) { (_,_) => succeed } + parseAndResolve(RiddlParserInput(input)) { (_, _) => succeed } } "resolve entity field" in { @@ -373,7 +373,7 @@ class ResolutionPassTest extends ResolvingTest { | } |} |""".stripMargin) - parseAndResolve(input) { (_,_) => succeed } + parseAndResolve(input) { (_, _) => succeed } } "resolve a path identifier" in { val rpi = RiddlParserInput(data = """domain d is { @@ -402,16 +402,60 @@ class ResolutionPassTest extends ResolvingTest { |} |""".stripMargin ) - parseAndResolve(rpi) { - (pi: PassInput, po: PassesOutput) => - val app: Application = pi.root.domains.head.applications.head - val contained: Group = app.groups.head - val container: Group = app.groups(1) - po.refMap.definitionOf[Group]("contained") match - case Some(group: Group) => - group mustBe contained - case _ => - fail("contained group not found") + parseAndResolve(rpi) { (pi: PassInput, po: PassesOutput) => + val app: Application = pi.root.domains.head.applications.head + val contained: Group = app.groups.head + val container: Group = app.groups(1) + po.refMap.definitionOf[Group]("contained") match + case Some(group: Group) => + group mustBe contained + case _ => + fail("contained group not found") + }() + } + + "issue #480" in { + val rpi = RiddlParserInput( + """domain ksoTemplateAppDomain { + | type EmailAddress = String(1,255) + | application ksoTemplateApp { + | type FirstName: String(2,64) + | type LastName: String(2,64) + | type Password: String(8,128) + | + | type SignupParameters is { + | firstName: FirstName, + | lastName: LastName, + | emailAddress: ksoTemplateAppDomain.EmailAddress, + | password: Password + | } + | + | command CreateUser is {user: ksoTemplateAppDomain.ksoTemplateApp.SignupParameters } + | command CreateUserUsingFacebook is {???} + | command CreateUserUsingGitHub is {???} + | command CreateUserUsingGmail is {???} + | command RedirectUserToSigninPage is {???} + | + | page SignupPage { + | + | form NewUserForm accepts ksoTemplateApp.SignupParameters { + | input firstName accepts ksoTemplateApp.FirstName + | input lastName accepts ksoTemplateApp.LastName + | input emailAddress accepts ksoTemplateAppDomain.EmailAddress + | input password accepts ksoTemplateApp.Password + | } + | button SignupButton initiates command ksoTemplateAppDomain.ksoTemplateApp.CreateUser + | button FacebookSignupButton initiates command ksoTemplateAppDomain.ksoTemplateApp.CreateUserUsingFacebook + | button GitHubSignupButton initiates command ksoTemplateAppDomain.ksoTemplateApp.CreateUserUsingGitHub + | button GmailSignupButton initiates command ksoTemplateAppDomain.ksoTemplateApp.CreateUserUsingGmail + | text SigninLink takes command ksoTemplateAppDomain.ksoTemplateApp.RedirectUserToSigninPage + | } + | } + |} + |""".stripMargin + ) + parseAndResolve(rpi) { (pi: PassInput, po: PassesOutput) => + po.messages.justErrors mustBe(empty) }() } } From d1a11831f21b077b4860710d1eda070be700f5da Mon Sep 17 00:00:00 2001 From: reidspencer Date: Fri, 17 Nov 2023 16:03:37 -0500 Subject: [PATCH 2/5] Move a test case to the testkit Signed-off-by: reidspencer --- ...est.scala => PathResolutionPassTest.scala} | 48 +------------------ 1 file changed, 2 insertions(+), 46 deletions(-) rename passes/src/test/scala/com/reactific/riddl/passes/resolve/{ResolutionPassTest.scala => PathResolutionPassTest.scala} (86%) diff --git a/passes/src/test/scala/com/reactific/riddl/passes/resolve/ResolutionPassTest.scala b/passes/src/test/scala/com/reactific/riddl/passes/resolve/PathResolutionPassTest.scala similarity index 86% rename from passes/src/test/scala/com/reactific/riddl/passes/resolve/ResolutionPassTest.scala rename to passes/src/test/scala/com/reactific/riddl/passes/resolve/PathResolutionPassTest.scala index ef771bae8..2b49462af 100644 --- a/passes/src/test/scala/com/reactific/riddl/passes/resolve/ResolutionPassTest.scala +++ b/passes/src/test/scala/com/reactific/riddl/passes/resolve/PathResolutionPassTest.scala @@ -8,9 +8,9 @@ import com.reactific.riddl.passes.{PassInput, PassesOutput} import java.nio.file.Path /** Unit Tests For the ResolutionPass */ -class ResolutionPassTest extends ResolvingTest { +class PathResolutionPassTest extends ResolvingTest { - "PathResolution" must { + "PathResolutionPass" must { "resolve a full path" in { val rpi = """domain A { @@ -414,49 +414,5 @@ class ResolutionPassTest extends ResolvingTest { }() } - "issue #480" in { - val rpi = RiddlParserInput( - """domain ksoTemplateAppDomain { - | type EmailAddress = String(1,255) - | application ksoTemplateApp { - | type FirstName: String(2,64) - | type LastName: String(2,64) - | type Password: String(8,128) - | - | type SignupParameters is { - | firstName: FirstName, - | lastName: LastName, - | emailAddress: ksoTemplateAppDomain.EmailAddress, - | password: Password - | } - | - | command CreateUser is {user: ksoTemplateAppDomain.ksoTemplateApp.SignupParameters } - | command CreateUserUsingFacebook is {???} - | command CreateUserUsingGitHub is {???} - | command CreateUserUsingGmail is {???} - | command RedirectUserToSigninPage is {???} - | - | page SignupPage { - | - | form NewUserForm accepts ksoTemplateApp.SignupParameters { - | input firstName accepts ksoTemplateApp.FirstName - | input lastName accepts ksoTemplateApp.LastName - | input emailAddress accepts ksoTemplateAppDomain.EmailAddress - | input password accepts ksoTemplateApp.Password - | } - | button SignupButton initiates command ksoTemplateAppDomain.ksoTemplateApp.CreateUser - | button FacebookSignupButton initiates command ksoTemplateAppDomain.ksoTemplateApp.CreateUserUsingFacebook - | button GitHubSignupButton initiates command ksoTemplateAppDomain.ksoTemplateApp.CreateUserUsingGitHub - | button GmailSignupButton initiates command ksoTemplateAppDomain.ksoTemplateApp.CreateUserUsingGmail - | text SigninLink takes command ksoTemplateAppDomain.ksoTemplateApp.RedirectUserToSigninPage - | } - | } - |} - |""".stripMargin - ) - parseAndResolve(rpi) { (pi: PassInput, po: PassesOutput) => - po.messages.justErrors mustBe(empty) - }() - } } } From 0ee3e5ce01b7b1e982b3ba3107343827eece8781 Mon Sep 17 00:00:00 2001 From: reidspencer Date: Fri, 17 Nov 2023 16:53:04 -0500 Subject: [PATCH 3/5] Add a test case for issue #480 Signed-off-by: reidspencer --- .../language/parsing/ApplicationParser.scala | 6 +-- testkit/src/test/input/issues/480.riddl | 38 +++++++++++++++++++ .../riddl/testkit/ReportedIssuesTest.scala | 33 ++++++++-------- 3 files changed, 56 insertions(+), 21 deletions(-) create mode 100644 testkit/src/test/input/issues/480.riddl diff --git a/language/src/main/scala/com/reactific/riddl/language/parsing/ApplicationParser.scala b/language/src/main/scala/com/reactific/riddl/language/parsing/ApplicationParser.scala index f5b27b645..8bb34c28c 100644 --- a/language/src/main/scala/com/reactific/riddl/language/parsing/ApplicationParser.scala +++ b/language/src/main/scala/com/reactific/riddl/language/parsing/ApplicationParser.scala @@ -87,17 +87,17 @@ private[parsing] trait ApplicationParser { ).?.map { case Some(definitions) => definitions case None => Seq.empty[InputDefinition] - } + }.log } private def acquisitionAliases[u: P]: P[String] = { StringIn("acquires", "reads", "takes", "accepts", "admits", - "initiates", "submits", "triggers", "activates", "starts").! + "initiates", "submits", "triggers", "activates", "starts").!.log } private def appInput[u: P]: P[Input] = { P( - location ~ inputAliases ~/ identifier ~ acquisitionAliases ~ typeRef ~ + location ~ inputAliases ~/ identifier ~/ acquisitionAliases ~/ typeRef ~ inputDefinitions ~ briefly ~ description ).map { case (loc, inputAlias, id, acquisitionAlias, putIn, inputs, brief, description) => Input(loc, inputAlias, id, acquisitionAlias, putIn, inputs, brief, description) diff --git a/testkit/src/test/input/issues/480.riddl b/testkit/src/test/input/issues/480.riddl new file mode 100644 index 000000000..05a162cff --- /dev/null +++ b/testkit/src/test/input/issues/480.riddl @@ -0,0 +1,38 @@ +domain ksoTemplateAppDomain { + + type EmailAddress = String(1,255) + + application ksoTemplateApp { + type FirstName: String(2,64) + type LastName: String(2,64) + type Password: String(8,128) + + record SignupParameters is { + firstName: FirstName, + lastName: LastName, + emailAddress: ksoTemplateAppDomain.EmailAddress, + password: Password + } + + command CreateUser is {user: SignupParameters } + command CreateUserUsingFacebook is {???} + command CreateUserUsingGitHub is {???} + command CreateUserUsingGmail is {???} + command RedirectUserToSigninPage is {???} + + page SignupPage { + + form NewUserForm acquires record ksoTemplateApp.SignupParameters is { + input firstName accepts ksoTemplateApp.FirstName + input lastName accepts ksoTemplateApp.LastName + input emailAddress accepts ksoTemplateAppDomain.EmailAddress + input password accepts ksoTemplateApp.Password + } + button SignupButton initiates command ksoTemplateAppDomain.ksoTemplateApp.CreateUser + button FacebookSignupButton initiates command ksoTemplateAppDomain.ksoTemplateApp.CreateUserUsingFacebook + button GitHubSignupButton initiates command ksoTemplateAppDomain.ksoTemplateApp.CreateUserUsingGitHub + button GmailSignupButton initiates command ksoTemplateAppDomain.ksoTemplateApp.CreateUserUsingGmail + text SigninLink takes command ksoTemplateAppDomain.ksoTemplateApp.RedirectUserToSigninPage + } + } +} diff --git a/testkit/src/test/scala/com/reactific/riddl/testkit/ReportedIssuesTest.scala b/testkit/src/test/scala/com/reactific/riddl/testkit/ReportedIssuesTest.scala index 572cfed70..2ad2c159f 100644 --- a/testkit/src/test/scala/com/reactific/riddl/testkit/ReportedIssuesTest.scala +++ b/testkit/src/test/scala/com/reactific/riddl/testkit/ReportedIssuesTest.scala @@ -15,6 +15,15 @@ class ReportedIssuesTest extends ValidatingTest { showWarnings = false ) + def checkOne(fileName: String): Assertion = { + checkOne(fileName){ + case Left(messages) => + fail(messages.format) + case Right(result) => + succeed + } + } + def checkOne(fileName: String)(checkResult: Either[Messages.Messages, PassesResult] => Assertion): Assertion = { val file = Path.of(dir, fileName).toFile val either = Riddl.parseAndValidate(file, options) @@ -75,28 +84,16 @@ class ReportedIssuesTest extends ValidatingTest { } } "406" in { - checkOne("406.riddl") { - case Left(messages) => - fail(messages.format) - case Right(result) => - succeed - } + checkOne("406.riddl") } "445" in { - checkOne("445.riddl") { - case Left(messages) => - fail(messages.format) - case Right(result) => - succeed - } + checkOne("445.riddl") } "447" in { - checkOne("447.riddl") { - case Left(messages) => - fail(messages.format) - case Right(result) => - succeed - } + checkOne("447.riddl") + } + "480" in { + checkOne("480.riddl") } } } From 58d9aa0c1a0606fb0bda1cf15540cd8f3d243254 Mon Sep 17 00:00:00 2001 From: reidspencer Date: Fri, 17 Nov 2023 17:17:40 -0500 Subject: [PATCH 4/5] Remove irrelevant test, cleanup code syntax Signed-off-by: reidspencer --- .../resolve/PathResolutionPassTest.scala | 73 ++++--------------- 1 file changed, 13 insertions(+), 60 deletions(-) diff --git a/passes/src/test/scala/com/reactific/riddl/passes/resolve/PathResolutionPassTest.scala b/passes/src/test/scala/com/reactific/riddl/passes/resolve/PathResolutionPassTest.scala index 983a8da78..c693c18ba 100644 --- a/passes/src/test/scala/com/reactific/riddl/passes/resolve/PathResolutionPassTest.scala +++ b/passes/src/test/scala/com/reactific/riddl/passes/resolve/PathResolutionPassTest.scala @@ -47,14 +47,14 @@ class PathResolutionPassTest extends ResolvingTest { | |}""".stripMargin parseAndResolve(RiddlParserInput(rpi)) { (in, outs) => - val target = in.root.domains.head.domains.head.domains.head.types.head + val target: Type = in.root.domains.head.domains.head.domains.head.types.head val parent = in.root.domains.head.domains.head.types.head val pid = parent.typ.asInstanceOf[AliasedTypeExpression].pathId val resolution = outs.outputOf[ResolutionOutput](ResolutionPass.name).get resolution.refMap.definitionOf[Type](pid, parent) match { case Some(resolved) => - resolved mustBe (target) - case None => fail(s"${pid} not resolved") + resolved mustBe target + case None => fail(s"$pid not resolved") } } } @@ -67,13 +67,13 @@ class PathResolutionPassTest extends ResolvingTest { |} |""".stripMargin parseAndResolve(RiddlParserInput(input)) { (in, outs) => - val target = in.root.domains.head.types.find(_.id.value == "Top").get - val parent = in.root.domains.head.types.find(_.id.value == "aTop").get + val target: Type = in.root.domains.head.types.find(_.id.value == "Top").get + val parent: Type = in.root.domains.head.types.find(_.id.value == "aTop").get val pid = parent.typ.asInstanceOf[AliasedTypeExpression].pathId val resolution = outs.outputOf[ResolutionOutput](ResolutionPass.name).get resolution.refMap.definitionOf[Type](pid, parent) match { case Some(resolvedDef) => - resolvedDef mustBe (target) + resolvedDef mustBe target case None => fail(s"${pid.format} not resolved") } @@ -188,15 +188,15 @@ class PathResolutionPassTest extends ResolvingTest { |} |""".stripMargin parseAndResolve(RiddlParserInput(input)) { (in, outs) => - outs.getAllMessages mustBe (Messages.empty) + outs.getAllMessages mustBe Messages.empty val Top = in.root.domains.head.types.head val D = in.root.domains.head.domains.head.contexts.find(_.id.value == "D").get val ATop = D.types.find(_.id.value == "ATop").get val pid = ATop.typ.asInstanceOf[AliasedTypeExpression].pathId val resolution = outs.outputOf[ResolutionOutput](ResolutionPass.name).get resolution.refMap.definitionOf[Type](pid, ATop) match { - case Some(resolved) => resolved mustBe (Top) - case None => fail(s"${pid} not resolved") + case Some(resolved) => resolved mustBe Top + case None => fail(s"$pid not resolved") } } } @@ -331,12 +331,12 @@ class PathResolutionPassTest extends ResolvingTest { ) parseAndResolve(input) { (in, outs) => val entity = in.root.domains.head.contexts.head.entities.head - entity.getClass mustBe (classOf[Entity]) + entity.getClass mustBe classOf[Entity] val cid = in.root.domains.head.types.head - cid.getClass mustBe (classOf[Type]) - cid.typ.getClass mustBe (classOf[UniqueId]) + cid.getClass mustBe classOf[Type] + cid.typ.getClass mustBe classOf[UniqueId] val pid = cid.typ.asInstanceOf[UniqueId].entityPath - pid.value mustBe (Seq("ReactiveBBQ", "Customer", "Customer")) + pid.value mustBe Seq("ReactiveBBQ", "Customer", "Customer") val resolution = outs.outputOf[ResolutionOutput](ResolutionPass.name).get resolution.refMap.definitionOf[Entity](pid, cid) match { case Some(definition) => @@ -413,52 +413,5 @@ class PathResolutionPassTest extends ResolvingTest { fail("contained group not found") }() } - - "handle issue #480" in { - pending - val rpi = RiddlParserInput( - """domain ksoTemplateAppDomain { - | type EmailAddress = String(1,255) - | application ksoTemplateApp { - | type FirstName: String(2,64) - | type LastName: String(2,64) - | type Password: String(8,128) - | - | type SignupParameters is { - | firstName: FirstName, - | lastName: LastName, - | emailAddress: ksoTemplateAppDomain.EmailAddress, - | password: Password - | } - | - | command CreateUser is {user: ksoTemplateAppDomain.ksoTemplateApp.SignupParameters } - | command CreateUserUsingFacebook is {???} - | command CreateUserUsingGitHub is {???} - | command CreateUserUsingGmail is {???} - | command RedirectUserToSigninPage is {???} - | - | page SignupPage { - | - | form NewUserForm accepts ksoTemplateApp.SignupParameters { - | input firstName accepts ksoTemplateApp.FirstName - | input lastName accepts ksoTemplateApp.LastName - | input emailAddress accepts ksoTemplateAppDomain.EmailAddress - | input password accepts ksoTemplateApp.Password - | } - | button SignupButton initiates command ksoTemplateAppDomain.ksoTemplateApp.CreateUser - | button FacebookSignupButton initiates command ksoTemplateAppDomain.ksoTemplateApp.CreateUserUsingFacebook - | button GitHubSignupButton initiates command ksoTemplateAppDomain.ksoTemplateApp.CreateUserUsingGitHub - | button GmailSignupButton initiates command ksoTemplateAppDomain.ksoTemplateApp.CreateUserUsingGmail - | text SigninLink takes command ksoTemplateAppDomain.ksoTemplateApp.RedirectUserToSigninPage - | } - | } - |} - |""".stripMargin - ) - parseAndResolve(rpi) { (pi: PassInput, po: PassesOutput) => - po.messages.justErrors mustBe(empty) - }() - } - } } From cfe97f280dab60c88cb38bbcc473062ce9085ac4 Mon Sep 17 00:00:00 2001 From: reidspencer Date: Fri, 17 Nov 2023 17:26:20 -0500 Subject: [PATCH 5/5] Remove reuse of "form" alias Forms are inputs not groups. It was used in both those cases. Signed-off-by: reidspencer --- .../riddl/language/parsing/ApplicationParser.scala | 4 ++-- .../riddl/language/parsing/CommonParser.scala | 13 ++++++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/language/src/main/scala/com/reactific/riddl/language/parsing/ApplicationParser.scala b/language/src/main/scala/com/reactific/riddl/language/parsing/ApplicationParser.scala index 8bb34c28c..9207f51a2 100644 --- a/language/src/main/scala/com/reactific/riddl/language/parsing/ApplicationParser.scala +++ b/language/src/main/scala/com/reactific/riddl/language/parsing/ApplicationParser.scala @@ -87,12 +87,12 @@ private[parsing] trait ApplicationParser { ).?.map { case Some(definitions) => definitions case None => Seq.empty[InputDefinition] - }.log + } } private def acquisitionAliases[u: P]: P[String] = { StringIn("acquires", "reads", "takes", "accepts", "admits", - "initiates", "submits", "triggers", "activates", "starts").!.log + "initiates", "submits", "triggers", "activates", "starts").! } private def appInput[u: P]: P[Input] = { diff --git a/language/src/main/scala/com/reactific/riddl/language/parsing/CommonParser.scala b/language/src/main/scala/com/reactific/riddl/language/parsing/CommonParser.scala index 9228a77b0..2efb71d54 100644 --- a/language/src/main/scala/com/reactific/riddl/language/parsing/CommonParser.scala +++ b/language/src/main/scala/com/reactific/riddl/language/parsing/CommonParser.scala @@ -240,8 +240,7 @@ private[parsing] trait CommonParser extends NoWhiteSpaceParsers { "window", "section", "tab", - "flow", - "form" + "flow" ).! ) } @@ -262,7 +261,15 @@ private[parsing] trait CommonParser extends NoWhiteSpaceParsers { def inputAliases[u: P]: P[String] = { P( - StringIn(Keywords.input, "form", "text", "button", "picklist", "selector", "menu").! + StringIn( + Keywords.input, + "form", + "text", + "button", + "picklist", + "selector", + "menu" + ).! ) }