diff --git a/modules/converter/src/main/scala/es/weso/shacl/converter/Shacl2ShEx.scala b/modules/converter/src/main/scala/es/weso/shacl/converter/Shacl2ShEx.scala
index 521b6f9b..747a6d3b 100644
--- a/modules/converter/src/main/scala/es/weso/shacl/converter/Shacl2ShEx.scala
+++ b/modules/converter/src/main/scala/es/weso/shacl/converter/Shacl2ShEx.scala
@@ -13,10 +13,14 @@ object Shacl2ShEx extends Converter {
val prefixes = schema.pm
val rs: List[Result[shex.ShapeExpr]] = schema.shapes.map(cnvShape(_)).toList
val r: Result[List[shex.ShapeExpr]] = sequence(rs)
+
r.map(
m => shex.Schema.empty.copy(
prefixes = Some(prefixes),
- shapes = Some(m)
+ shapes = {
+ println(s"@@@Conversion Map: $m")
+ Some(m)
+ }
)
)
}
@@ -32,17 +36,6 @@ object Shacl2ShEx extends Converter {
xs.foldLeft(zero)(comb)
}
- /* def cnvShape(s: shacl.Shape): Result[shex.ShapeExpr] = {
- val id : Id = cnvId(s.id)
- val rs = s.propertyShapes.toList.map(cnvConstraint(id, _)).sequence
- rs.map(ses => ses.size match {
- case 1 => ses.head
- case n if n > 1 => shex.ShapeAnd(id,ses)
- case _ => ??? // TODO
- })
- } */
-
-
def cnvShape(c: shacl.Shape): Result[shex.ShapeExpr] =
c match {
case nc: shacl.NodeShape => cnvNodeShape(nc)
diff --git a/modules/schema/src/test/scala/es/weso/schema/SchemaConversionsTest.scala b/modules/schema/src/test/scala/es/weso/schema/SchemaConversionsTest.scala
index 1f76d4ad..9be3c008 100644
--- a/modules/schema/src/test/scala/es/weso/schema/SchemaConversionsTest.scala
+++ b/modules/schema/src/test/scala/es/weso/schema/SchemaConversionsTest.scala
@@ -1,21 +1,22 @@
package es.weso.schema
import org.scalatest._
-import cats._
import cats.implicits._
+import es.weso.json.JsonCompare.jsonDiff
+import es.weso.rdf.jena.RDFAsJenaModel
+import io.circe.parser._
class SchemaConversionsTest extends FunSpec with Matchers with EitherValues {
- ignore("ShExC -> ShExJ") {
- it("Converts simple ShExC to ShExJ") {
- val strShExC =
- """
+ describe("ShExC -> ShExJ") {
+ val strShExC =
+ """
|prefix :
|:S { :p IRI }
""".stripMargin
- val strShExJ =
- """
+ val strExpected =
+ """
| {
| "type" : "Schema",
| "@context" : "http://www.w3.org/ns/shex.jsonld",
@@ -35,24 +36,126 @@ class SchemaConversionsTest extends FunSpec with Matchers with EitherValues {
| ]
|}
""".stripMargin
+ shouldConvert(strShExC, "ShExC", "ShEx", "ShExJ", "ShEx", strExpected, jsonCompare)
+ }
- val r = for {
- schemaFromShExC <- ShExSchema.fromString(strShExC,"ShExC",None).leftMap(e => s"Error reading ShExC\n$e")
- schemaFromShExJ <- ShExSchema.fromString(strShExJ,"ShExJ",None).leftMap(e => s"Error reading ShExJ\n$e")
- schemaFromConversion <- schemaFromShExC.convert(Some("ShEx"), Some("ShExJ")).leftMap(e => s"Error converting\n$e")
- } yield (schemaFromShExC,schemaFromConversion)
-
- r.fold(e => fail(s"Error: $e"),
- v => {
- val (s1,s2) = v
- if (s1 == s2) {
- info(s"Schema == schema from conversion\nFrom ShExC: $s1\nFrom ShExJ:$s2")
- } else {
- fail(s"Schema != schema from conversion\nFrom ShExC: $s1\nFrom ShExJ:$s2")
- }
- }
- )
- }
+ describe(s"ShExC -> Turtle") {
+ val strShExC =
+ """
+ |prefix :
+ |:S { :p IRI }
+ """.stripMargin
+ val strExpected =
+ """
+ |@prefix : .
+ |@prefix sx: .
+ |
+ |:S a sx:Shape ;
+ | sx:closed false ;
+ | sx:expression [
+ | a sx:TripleConstraint ;
+ | sx:predicate :p ;
+ | sx:valueExpr [
+ | a sx:NodeConstraint ;
+ | sx:nodeKind sx:iri ]
+ | ] .
+ |
+ |[ a sx:Schema ;
+ | sx:shapes :S
+ |] .
+ """.stripMargin
+ shouldConvert(strShExC, "ShExC", "ShEx", "Turtle", "ShEx", strExpected, rdfCompare)
}
+
+ describe(s"SHACL (Turtle) -> SHACL (JSON-LD)") {
+ val strShacl =
+ """
+ |prefix :
+ |prefix sh:
+ |:S a sh:NodeShape ;
+ | sh:nodeKind sh:IRI
+ """.stripMargin
+
+ val strExpected =
+ """
+ | .
+ | "false"^^ .
+ | .
+ """.stripMargin
+ shouldConvert(strShacl, "Turtle", "Shaclex", "N-Triples", "Shaclex", strExpected, rdfCompare)
+ }
+
+ describe(s"SHACL (Turtle) -> ShEx (Turtle)") {
+ val strShacl =
+ """
+ |prefix :
+ |prefix sh:
+ |:S a sh:NodeShape ;
+ | sh:nodeKind sh:IRI
+ """.stripMargin
+
+ val strExpected = """
+ | { "type" : "Schema",
+ | "@context" : "http://www.w3.org/ns/shex.jsonld",
+ | "shapes" : [ {
+ | "type" : "NodeConstraint",
+ | "id" : "http://example.org/S",
+ | "nodeKind" : "iri"
+ | } ] }
+ """.stripMargin
+ shouldConvert(strShacl, "Turtle", "Shaclex", "ShExJ", "ShEx", strExpected, jsonCompare)
+ }
+
+
+ def shouldConvert(str: String, format: String, engine: String,
+ targetFormat: String, targetEngine: String,
+ expected: String,
+ compare: (String,String) => Either[String, Boolean]
+ ): Unit = {
+ it(s"Should convert $str with format $format and engine $engine and obtain $expected") {
+ val r = for {
+ schema <- Schemas.fromString(str, format, engine, None).
+ leftMap(e => s"Error reading Schema ($format/$engine): $str\nError: $e")
+ strConverted <- schema.convert(Some(targetFormat), Some(targetEngine)).
+ leftMap(e => s"Error converting schema(${schema.name}) to ($targetFormat/$targetEngine\n$e")
+ result <- compare(strConverted, expected).
+ leftMap(e => s"Error in comparison: $e")
+ } yield (strConverted, expected, result)
+
+ r.fold(e => fail(s"Error: $e"), v => {
+ val (s1, s2, r) = v
+ if (r) {
+ info(s"Conversion is ok")
+ } else {
+ fail(s"Different results\ns1=$s1\ns2$s2")
+ }
+ })
+ }
+ }
+
+ def jsonCompare(s1: String, s2: String): Either[String, Boolean] = for {
+ json1 <- parse(s1).leftMap(e => s"Error parsing $s1\n$e")
+ json2 <- parse(s2).leftMap(e => s"Error parsing $s2\n$e")
+ b <-
+ if (json1.equals(json2)) { Right(true)}
+ else Left(s"Json's different:\nJson1: $json1\nJson2: $json2. Diff: ${jsonDiff(json1, json2)}")
+ } yield b
+
+ def rdfCompare(s1: String, s2: String): Either[String, Boolean] = for {
+ rdf1 <- RDFAsJenaModel.fromChars(s1,"TURTLE",None)
+ rdf2 <- RDFAsJenaModel.fromChars(s2,"TURTLE",None)
+ b <- rdf1.isIsomorphicWith(rdf2)
+ } yield b
+
+ def shExCompare(s1: String, s2: String): Either[String, Boolean] = for {
+ schema1 <- Schemas.fromString(s1,"ShExC","ShEx",None).
+ leftMap(e => s"Error reading ShEx from string s1: $s1\n$e")
+ schema2 <- Schemas.fromString(s2,"ShExC","ShEx",None).
+ leftMap(e => s"Error reading ShEx from string s1: $s1\n$e")
+ json1 <- schema1.convert(Some("ShExJ"),Some("ShExC"))
+ json2 <- schema2.convert(Some("ShExJ"),Some("ShExC"))
+ b <- jsonCompare(json1,json2)
+ } yield b
+
}
diff --git a/modules/shex/src/main/scala/es/weso/shex/Schema.scala b/modules/shex/src/main/scala/es/weso/shex/Schema.scala
index 6c33c034..33c052a6 100644
--- a/modules/shex/src/main/scala/es/weso/shex/Schema.scala
+++ b/modules/shex/src/main/scala/es/weso/shex/Schema.scala
@@ -71,7 +71,7 @@ case class Schema(prefixes: Option[PrefixMap],
object Schema {
- def rdfDataFormats(rdfReader: RDFReader) = rdfReader.availableParseFormats // RDFAsJenaModel.availableFormats.map(_.toUpperCase)
+ def rdfDataFormats(rdfReader: RDFReader) = rdfReader.availableParseFormats.map(_.toUpperCase) // RDFAsJenaModel.availableFormats.map(_.toUpperCase)
def empty: Schema =
Schema(None, None, None, None, None, None, List())
@@ -105,6 +105,7 @@ object Schema {
format: String,
rdfBuilder: RDFBuilder): Either[String,String] = {
val formatUpperCase = format.toUpperCase
+ println(s"Target format: $formatUpperCase, available: ${rdfDataFormats(rdfBuilder)} ")
formatUpperCase match {
case "SHEXC" => {
import compact.CompactShow._
diff --git a/notes/0.1.0.md b/notes/0.1.0.md
new file mode 100644
index 00000000..d6d311b4
--- /dev/null
+++ b/notes/0.1.0.md
@@ -0,0 +1,18 @@
+# New features
+
+- Passes all SHACL-Core tests
+
+TODOs
+-----
+
+- ShEx: Complete UML generation for ShEx schemas
+
+- ShEx: Complete semantic actions implementation
+
+- ShEx: test-suite with shape maps and update report [Issue ]()
+
+- Shaclex: Conversion from ShEx to SHACL [Issue 114](https://github.com/labra/shaclex/issues/114)
+
+- Shaclex: Conversion from SHACL to ShEx [Issue 113](https://github.com/labra/shaclex/issues/113)
+
+- Shacl: Implement SHACL-Sparql [Issue 112](https://github.com/labra/shaclex/issues/112)
diff --git a/version.sbt b/version.sbt
index e1b8d9ce..e7654440 100644
--- a/version.sbt
+++ b/version.sbt
@@ -1 +1 @@
-version in ThisBuild := "0.0.97"
+version in ThisBuild := "0.1.0"