diff --git a/build.sbt b/build.sbt index 751daaa44..8f680cb4b 100644 --- a/build.sbt +++ b/build.sbt @@ -19,6 +19,7 @@ lazy val license = ALv2(yyyy = "2019-2025", copyrightOwner = "Ossum Inc.", licen def cpDep(cp: CrossProject): CrossClasspathDependency = cp % "compile->compile;test->test" def pDep(p: Project): ClasspathDependency = p % "compile->compile;test->test" +def tkDep(cp: CrossProject): CrossClasspathDependency = cp % "compile->compile;test->test" lazy val riddl: Project = Root("riddl", startYr = startYear /*, license = "Apache-2.0" */ ) .configure(With.noPublishing, With.git, With.dynver, With.noMiMa) @@ -90,7 +91,7 @@ lazy val utilsJS = utils_cp.js val Language = config("language") lazy val language_cp: CrossProject = CrossModule("language", "riddl-language")(JVM, JS) .dependsOn(cpDep(utils_cp)) - .configure(With.typical, With.publishing, With.headerLicense("Apache-2.0")) + .configure(With.typical, With.headerLicense("Apache-2.0")) .settings( description := "Abstract Syntax Tree and basic RIDDL language parser", scalacOptions ++= Seq("-explain", "--explain-types", "--explain-cyclic", "--no-warnings"), @@ -129,7 +130,7 @@ lazy val languageJS = language_cp.js.dependsOn(utilsJS) val Passes = config("passes") lazy val passes_cp = CrossModule("passes", "riddl-passes")(JVM, JS) .dependsOn(cpDep(utils_cp), cpDep(language_cp)) - .configure(With.typical, With.publishing, With.headerLicense("Apache-2.0")) + .configure(With.typical, With.headerLicense("Apache-2.0")) .settings( Test / parallelExecution := false, scalacOptions ++= Seq("-explain", "--explain-types", "--explain-cyclic"), @@ -163,17 +164,22 @@ lazy val testkit_cp = CrossModule("testkit", "riddl-testkit")(JVM, JS) .settings( description := "Testing kit for RIDDL language and passes" ) - .dependsOn(language_cp % "compile->test;test->test", passes_cp % "compile->test;test->test") + .dependsOn(tkDep(utils_cp), tkDep(language_cp), tkDep(passes_cp)) .jvmSettings( libraryDependencies ++= Seq( "org.scalactic" %% "scalactic" % V.scalatest, - "org.scalatest" %% "scalatest" % V.scalatest, - "org.scalactic" %% "scalactic" % V.scalatest % Test, - "org.scalatest" %% "scalatest" % V.scalatest % Test + "org.scalatest" %% "scalatest" % V.scalatest ) ) .jsConfigure(With.js("RIDDL: language", withCommonJSModule = true)) .jsConfigure(With.publishing) + .jsSettings( + // scalacOptions ++= Seq("-rewrite", "-source", "3.4-migration"), + libraryDependencies ++= Seq( + "org.scalactic" %%% "scalactic" % V.scalatest, + "org.scalatest" %%% "scalatest" % V.scalatest + ) + ) val testkit = testkit_cp.jvm val testkitJS = testkit_cp.js @@ -196,7 +202,7 @@ val diagramsJS = diagrams_cp.js lazy val riddlLib_cp: CrossProject = CrossModule("riddlLib", "riddl-lib")(JS, JVM) .dependsOn(cpDep(utils_cp), cpDep(language_cp), cpDep(passes_cp), cpDep(diagrams_cp)) - .configure(With.scala3,With.publishing) + .configure(With.scala3, With.publishing) .settings( description := "Bundling of essential RIDDL libraries" ) @@ -261,7 +267,6 @@ val Riddlc = config("riddlc") lazy val riddlc: Project = Program("riddlc", "riddlc") .configure(With.typical, With.publishing, With.headerLicense("Apache-2.0")) .configure(With.coverage(50.0)) - .configure(With.publishing) .configure(With.noMiMa) .dependsOn( utils, diff --git a/language/shared/src/main/scala/com/ossuminc/riddl/language/Folding.scala b/language/shared/src/main/scala/com/ossuminc/riddl/language/Folding.scala index ac095c1c9..61a591394 100644 --- a/language/shared/src/main/scala/com/ossuminc/riddl/language/Folding.scala +++ b/language/shared/src/main/scala/com/ossuminc/riddl/language/Folding.scala @@ -17,12 +17,12 @@ object Folding { /** Folding with state from an element of type V * - * @param parent - * The parent node of CV which must be its direct container - * @param child - * The node to fold through - * @param state - * Initial value of arbitrary type `S`` that can be used to fold the nodes into and provides the result type + * @param container + * The container node of CV which must be its direct container + * @param empty + * The initial empty state of the result. this is a "fold" after all :) + * @foldIt + * The function that folds eacy entry in `container` * @param f * The folding function which takes 3 arguments and returns an `S` (list the initial `state`) * @tparam S diff --git a/language/shared/src/main/scala/com/ossuminc/riddl/language/parsing/ExtensibleTopLevelParser.scala b/language/shared/src/main/scala/com/ossuminc/riddl/language/parsing/ExtensibleTopLevelParser.scala index 3ddc600ac..d300d7c64 100644 --- a/language/shared/src/main/scala/com/ossuminc/riddl/language/parsing/ExtensibleTopLevelParser.scala +++ b/language/shared/src/main/scala/com/ossuminc/riddl/language/parsing/ExtensibleTopLevelParser.scala @@ -22,27 +22,27 @@ import scala.scalajs.js.annotation.* /** An extensible version of the Top Level Parser. */ trait ExtensibleTopLevelParser(using PlatformContext) - extends ProcessorParser - with DomainParser - with AdaptorParser - with ApplicationParser - with ContextParser - with EntityParser - with EpicParser - with FunctionParser - with ModuleParser - with NebulaParser - with ProjectorParser - with RepositoryParser - with RootParser - with SagaParser - with StreamingParser - with StatementParser - with ParsingContext { + extends ProcessorParser, + AdaptorParser, + ApplicationParser, + ContextParser, + DomainParser, + EntityParser, + EpicParser, + FunctionParser, + ModuleParser, + NebulaParser, + ProjectorParser, + RepositoryParser, + RootParser, + SagaParser, + StreamingParser, + StatementParser, + ParsingContext { def input: RiddlParserInput def withVerboseFailures: Boolean - + private def doParse[E <: Parent: ClassTag](rule: P[?] => P[E]): Either[Messages, E] = { parseRule[E](input, rule, withVerboseFailures) { (result: Either[Messages, E], input: RiddlParserInput, index: Int) => @@ -53,7 +53,7 @@ trait ExtensibleTopLevelParser(using PlatformContext) error(At(input, index), s"Parser could not translate '${input.origin}' after $index characters") end if result - case _ @ Right(wrongNode) => + case _ @Right(wrongNode) => val expected = classTag[E].runtimeClass val actual = wrongNode.getClass error(At(input, index), s"Parser did not yield a ${expected.getSimpleName} but ${actual.getSimpleName}") @@ -71,4 +71,31 @@ trait ExtensibleTopLevelParser(using PlatformContext) case r @ Right(root) => Right(root -> this.getURLs) } } + + protected def parserFor[T <: Definition: ClassTag]: P[?] => P[T] = { + val parser: P[?] => P[?] = classTag[T].runtimeClass match { + case x if x == classOf[Type] => typeDef(_) + case x if x == classOf[Domain] => domain(_) + case x if x == classOf[Context] => context(_) + case x if x == classOf[Entity] => entity(_) + case x if x == classOf[Adaptor] => adaptor(_) + case x if x == classOf[Invariant] => invariant(_) + case x if x == classOf[Function] => function(_) + case x if x == classOf[Streamlet] => streamlet(_) + case x if x == classOf[Saga] => saga(_) + case x if x == classOf[Repository] => repository(_) + case x if x == classOf[Projector] => projector(_) + case x if x == classOf[Epic] => epic(_) + case x if x == classOf[Connector] => connector(_) + case x if x == classOf[Module] => module(_) + case x if x == classOf[Nebula] => nebula(_) + case x if x == classOf[Root] => root(_) + case _ => + throw new RuntimeException( + s"No parser defined for ${classTag[T].runtimeClass}" + ) + } + parser.asInstanceOf[P[?] => P[T]] + } + } diff --git a/language/shared/src/test/scala/com/ossuminc/riddl/language/parsing/AbstractParsingTest.scala b/language/shared/src/test/scala/com/ossuminc/riddl/language/parsing/AbstractParsingTest.scala index 261422675..3ad716b80 100644 --- a/language/shared/src/test/scala/com/ossuminc/riddl/language/parsing/AbstractParsingTest.scala +++ b/language/shared/src/test/scala/com/ossuminc/riddl/language/parsing/AbstractParsingTest.scala @@ -15,7 +15,7 @@ import com.ossuminc.riddl.utils.{AbstractTestingBasisWithTestData, CommonOptions import fastparse.* import scala.annotation.unused -import scala.concurrent.duration.DurationInt + import scala.reflect.* /** A helper class for testing the parser */ @@ -23,7 +23,7 @@ trait AbstractParsingTest(using PlatformContext) extends AbstractTestingBasisWit case class StringParser(content: String, testCase: String = "unknown test case") extends ExtensibleTopLevelParser(): val input: RiddlParserInput = RiddlParserInput(content, testCase) - val withVerboseFailures: Boolean = true + val withVerboseFailures: Boolean = true end StringParser def parse[T <: RiddlValue, U <: RiddlValue]( diff --git a/language/shared/src/test/scala/com/ossuminc/riddl/language/parsing/TestParser.scala b/language/shared/src/test/scala/com/ossuminc/riddl/language/parsing/TestParser.scala index 697ac171b..ed07593f1 100644 --- a/language/shared/src/test/scala/com/ossuminc/riddl/language/parsing/TestParser.scala +++ b/language/shared/src/test/scala/com/ossuminc/riddl/language/parsing/TestParser.scala @@ -22,9 +22,10 @@ case class TestParser( input: RiddlParserInput, throwOnError: Boolean = false, withVerboseFailures: Boolean = true -)(using PlatformContext) extends ExtensibleTopLevelParser +)(using PlatformContext) + extends ExtensibleTopLevelParser with Matchers { - + def expect[CT <: RiddlValue]( parser: P[?] => P[CT], withVerboseFailures: Boolean = false @@ -52,31 +53,6 @@ case class TestParser( expect[T](parser).map(x => extract(x) -> input) } - protected def parserFor[T <: Definition: ClassTag]: P[?] => P[T] = { - val parser: P[?] => P[?] = classTag[T].runtimeClass match { - case x if x == classOf[AST.Type] => typeDef(_) - case x if x == classOf[AST.Domain] => domain(_) - case x if x == classOf[AST.Context] => context(_) - case x if x == classOf[AST.Entity] => entity(_) - case x if x == classOf[AST.Adaptor] => adaptor(_) - case x if x == classOf[AST.Invariant] => invariant(_) - case x if x == classOf[AST.Function] => function(_) - case x if x == classOf[AST.Streamlet] => streamlet(_) - case x if x == classOf[AST.Saga] => saga(_) - case x if x == classOf[AST.Repository] => repository(_) - case x if x == classOf[AST.Projector] => projector(_) - case x if x == classOf[AST.Epic] => epic(_) - case x if x == classOf[AST.Connector] => connector(_) - case x if x == classOf[AST.Module] => module(_) - case x if x == classOf[AST.Root] => root(_) - case _ => - throw new RuntimeException( - s"No parser defined for ${classTag[T].runtimeClass}" - ) - } - parser.asInstanceOf[P[?] => P[T]] - } - def parseTopLevelDomains: Either[Messages, Root] = { parseRoot } @@ -105,12 +81,12 @@ case class TestParser( def parseDomainDefinition[TO <: RiddlValue]( extract: Domain => TO ): Either[Messages, (TO, RiddlParserInput)] = { - parse[Domain, TO](domain(_), extract) + parse[Domain, TO](parserFor[Domain], extract) } def parseContextDefinition[TO <: RiddlValue]( extract: Context => TO ): Either[Messages, (TO, RiddlParserInput)] = { - parse[Context, TO](context(_), extract) + parse[Context, TO](parserFor[Context], extract) } } diff --git a/passes/shared/src/main/scala/com/ossuminc/riddl/passes/validate/StreamingValidation.scala b/passes/shared/src/main/scala/com/ossuminc/riddl/passes/validate/StreamingValidation.scala index 9763e7396..69d4fd14d 100644 --- a/passes/shared/src/main/scala/com/ossuminc/riddl/passes/validate/StreamingValidation.scala +++ b/passes/shared/src/main/scala/com/ossuminc/riddl/passes/validate/StreamingValidation.scala @@ -9,9 +9,8 @@ package com.ossuminc.riddl.passes.validate import com.ossuminc.riddl.language.AST.* import com.ossuminc.riddl.language.At import com.ossuminc.riddl.language.Messages -import com.ossuminc.riddl.utils.{pc, ec} +import com.ossuminc.riddl.utils.pc -import scala.math.abs import scala.collection.mutable trait StreamingValidation extends TypeValidation { diff --git a/project/plugins.sbt b/project/plugins.sbt index de971e64c..c26d2a75d 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,4 +1,4 @@ -addSbtPlugin("com.ossuminc" % "sbt-ossuminc" % "0.16.5") +addSbtPlugin("com.ossuminc" % "sbt-ossuminc" % "0.17.0-1-875cb28e-20241102-1842") // This enables sbt-bloop to create bloop config files for Metals editors // Uncomment locally if you use metals, otherwise don't slow down other diff --git a/testkit/jvm/src/test/scala/com/ossuminc/riddl/testkit/ParsingTestTest.scala b/testkit/jvm/src/test/scala/com/ossuminc/riddl/testkit/ParsingTestTest.scala index 4f1f80364..966614899 100644 --- a/testkit/jvm/src/test/scala/com/ossuminc/riddl/testkit/ParsingTestTest.scala +++ b/testkit/jvm/src/test/scala/com/ossuminc/riddl/testkit/ParsingTestTest.scala @@ -7,10 +7,11 @@ package com.ossuminc.riddl.testkit import com.ossuminc.riddl.language.parsing +import com.ossuminc.riddl.language.parsing.AbstractParsingTest import com.ossuminc.riddl.utils.{pc,ec} import org.scalatest.Suite -class ParsingTestTest extends ParsingTest { +class ParsingTestTest extends AbstractParsingTest { val delegate: Suite = new parsing.ParsingTestTest {} delegate.execute() } diff --git a/testkit/jvm/src/test/scala/com/ossuminc/riddl/testkit/RunPassTestTest.scala b/testkit/jvm/src/test/scala/com/ossuminc/riddl/testkit/RunPassTestTest.scala index d4cc0e5bf..883208626 100644 --- a/testkit/jvm/src/test/scala/com/ossuminc/riddl/testkit/RunPassTestTest.scala +++ b/testkit/jvm/src/test/scala/com/ossuminc/riddl/testkit/RunPassTestTest.scala @@ -8,6 +8,8 @@ package com.ossuminc.riddl.testkit import com.ossuminc.riddl.language.parsing.RiddlParserInput import com.ossuminc.riddl.passes.stats.StatsPass +import com.ossuminc.riddl.passes.AbstractRunPassTest + import com.ossuminc.riddl.utils.{pc, ec} import com.ossuminc.riddl.utils.{Await, URL} import org.scalatest.TestData @@ -15,19 +17,17 @@ import org.scalatest.TestData import java.util.concurrent.TimeUnit import scala.concurrent.duration.FiniteDuration -class RunPassTestTest extends RunPassTest { +class RunPassTestTest extends AbstractRunPassTest { "RunPassTestTest" should { "work for stats pass" in { (td: TestData) => - val url = URL.fromCwdPath("passes/jvm/src/test/input/rbbq.riddl") - val inputFuture = RiddlParserInput.fromURL(url, td) - inputFuture.map { input => - val result = runPassesWith(input, StatsPass.creator()) - if result.messages.hasErrors then - fail(result.messages.justErrors.format) - else - succeed - } - Await.result(inputFuture, 10) + val url = URL.fromCwdPath("passes/jvm/src/test/input/rbbq.riddl") + val inputFuture = RiddlParserInput.fromURL(url, td) + inputFuture.map { input => + val result = runPassesWith(input, StatsPass.creator()) + if result.messages.hasErrors then fail(result.messages.justErrors.format) + else succeed } + Await.result(inputFuture, 10) + } } } diff --git a/testkit/shared/src/main/scala/com/ossuminc/riddl/language/parsing/AbstractParsingTest.scala b/testkit/shared/src/main/scala/com/ossuminc/riddl/language/parsing/AbstractParsingTest.scala new file mode 120000 index 000000000..e0b71fd41 --- /dev/null +++ b/testkit/shared/src/main/scala/com/ossuminc/riddl/language/parsing/AbstractParsingTest.scala @@ -0,0 +1 @@ +../../../../../../../../../../language/shared/src/test/scala/com/ossuminc/riddl/language/parsing/AbstractParsingTest.scala \ No newline at end of file diff --git a/testkit/shared/src/main/scala/com/ossuminc/riddl/language/parsing/TestParser.scala b/testkit/shared/src/main/scala/com/ossuminc/riddl/language/parsing/TestParser.scala new file mode 120000 index 000000000..fb8e7ffad --- /dev/null +++ b/testkit/shared/src/main/scala/com/ossuminc/riddl/language/parsing/TestParser.scala @@ -0,0 +1 @@ +../../../../../../../../../../language/shared/src/test/scala/com/ossuminc/riddl/language/parsing/TestParser.scala \ No newline at end of file diff --git a/testkit/shared/src/main/scala/com/ossuminc/riddl/passes/AbstractRunPassTest.scala b/testkit/shared/src/main/scala/com/ossuminc/riddl/passes/AbstractRunPassTest.scala new file mode 120000 index 000000000..e547d4c5e --- /dev/null +++ b/testkit/shared/src/main/scala/com/ossuminc/riddl/passes/AbstractRunPassTest.scala @@ -0,0 +1 @@ +../../../../../../../../../passes/shared/src/test/scala/com/ossuminc/riddl/passes/AbstractRunPassTest.scala \ No newline at end of file diff --git a/testkit/shared/src/main/scala/com/ossuminc/riddl/passes/validate/AbstractValidatingTest.scala b/testkit/shared/src/main/scala/com/ossuminc/riddl/passes/validate/AbstractValidatingTest.scala new file mode 120000 index 000000000..12d498c23 --- /dev/null +++ b/testkit/shared/src/main/scala/com/ossuminc/riddl/passes/validate/AbstractValidatingTest.scala @@ -0,0 +1 @@ +../../../../../../../../../../passes/shared/src/test/scala/com/ossuminc/riddl/passes/validate/AbstractValidatingTest.scala \ No newline at end of file diff --git a/testkit/shared/src/main/scala/com/ossuminc/riddl/testkit/ParsingTest.scala b/testkit/shared/src/main/scala/com/ossuminc/riddl/testkit/ParsingTest.scala deleted file mode 100644 index edc809bb6..000000000 --- a/testkit/shared/src/main/scala/com/ossuminc/riddl/testkit/ParsingTest.scala +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright 2019 Ossum, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -package com.ossuminc.riddl.testkit - -import com.ossuminc.riddl.utils.PlatformContext - -abstract class ParsingTest(using PlatformContext) extends com.ossuminc.riddl.language.parsing.AbstractParsingTest diff --git a/testkit/shared/src/main/scala/com/ossuminc/riddl/testkit/RunPassTest.scala b/testkit/shared/src/main/scala/com/ossuminc/riddl/testkit/RunPassTest.scala deleted file mode 100644 index 4f349761e..000000000 --- a/testkit/shared/src/main/scala/com/ossuminc/riddl/testkit/RunPassTest.scala +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright 2019 Ossum, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -package com.ossuminc.riddl.testkit - -import com.ossuminc.riddl.utils.PlatformContext - -abstract class RunPassTest(using PlatformContext) extends com.ossuminc.riddl.passes.AbstractRunPassTest diff --git a/testkit/shared/src/main/scala/com/ossuminc/riddl/testkit/TestParser.scala b/testkit/shared/src/main/scala/com/ossuminc/riddl/testkit/TestParser.scala deleted file mode 100644 index 217937534..000000000 --- a/testkit/shared/src/main/scala/com/ossuminc/riddl/testkit/TestParser.scala +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright 2019 Ossum, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -package com.ossuminc.riddl.testkit - -import com.ossuminc.riddl.language.parsing.RiddlParserInput -import com.ossuminc.riddl.language.parsing.{TestParser => LanguageTestParser} -import com.ossuminc.riddl.utils.PlatformContext - -class TestParser(input: RiddlParserInput, throwOnError: Boolean)(using PlatformContext) - extends LanguageTestParser(input, throwOnError) diff --git a/testkit/shared/src/main/scala/com/ossuminc/riddl/testkit/ValidatingTest.scala b/testkit/shared/src/main/scala/com/ossuminc/riddl/testkit/ValidatingTest.scala deleted file mode 100644 index f21747518..000000000 --- a/testkit/shared/src/main/scala/com/ossuminc/riddl/testkit/ValidatingTest.scala +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright 2019 Ossum, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -package com.ossuminc.riddl.testkit - -import com.ossuminc.riddl.passes.validate.AbstractValidatingTest -import com.ossuminc.riddl.utils.PlatformContext - -abstract class ValidatingTest(using PlatformContext) extends AbstractValidatingTest diff --git a/testkit/shared/src/main/scala/com/ossuminc/riddl/utils/AbstractTestingBasis.scala b/testkit/shared/src/main/scala/com/ossuminc/riddl/utils/AbstractTestingBasis.scala new file mode 120000 index 000000000..4f8500a22 --- /dev/null +++ b/testkit/shared/src/main/scala/com/ossuminc/riddl/utils/AbstractTestingBasis.scala @@ -0,0 +1 @@ +../../../../../../../../../utils/shared/src/test/scala/com/ossuminc/riddl/utils/AbstractTestingBasis.scala \ No newline at end of file diff --git a/testkit/shared/src/test/scala/com/ossuminc/riddl/testkit/AbstractTestingBasisTest.scala b/testkit/shared/src/test/scala/com/ossuminc/riddl/testkit/AbstractTestingBasisTest.scala new file mode 100644 index 000000000..0466f5dff --- /dev/null +++ b/testkit/shared/src/test/scala/com/ossuminc/riddl/testkit/AbstractTestingBasisTest.scala @@ -0,0 +1,16 @@ +/* + * Copyright 2019 Ossum, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +package com.ossuminc.riddl.testkit + +import com.ossuminc.riddl.utils.AbstractTestingBasis + +class AbstractTestingBasisTest extends AbstractTestingBasis { + + "AbstractTestingBasisTest" should { + "work" in { succeed } + } +}