From 2f8a3caa60137e4c321249aeab8d82f6bfb6a454 Mon Sep 17 00:00:00 2001 From: Sergei Winitzki Date: Fri, 5 Jul 2024 22:53:09 +0200 Subject: [PATCH] yaml / json support (#32) * support union types * wip * wip json support * implement json * wip json and tests * add failing tests * full yaml implementation * all yaml test cases pass * json export is now valid but ill-formatted * all tests pass for json and yaml * correct json format with variable indentation * fix readme * fix last test --- README.md | 32 ++- .../main/scala/io/chymyst/dhall/Main.scala | 30 +- .../test/resources/yaml-main-cases/01.dhall | 1 + .../test/resources/yaml-main-cases/01.json | 3 + .../test/resources/yaml-main-cases/01.yaml | 1 + .../test/resources/yaml-main-cases/02.dhall | 1 + .../test/resources/yaml-main-cases/02.json | 3 + .../test/resources/yaml-main-cases/02.yaml | 1 + .../test/resources/yaml-main-cases/03.dhall | 1 + .../test/resources/yaml-main-cases/03.json | 5 + .../test/resources/yaml-main-cases/03.yaml | 2 + .../test/resources/yaml-main-cases/04.dhall | 1 + .../test/resources/yaml-main-cases/04.json | 5 + .../test/resources/yaml-main-cases/04.yaml | 2 + .../test/resources/yaml-main-cases/05.dhall | 1 + .../test/resources/yaml-main-cases/05.json | 5 + .../test/resources/yaml-main-cases/05.yaml | 2 + .../test/resources/yaml-main-cases/06.dhall | 1 + .../test/resources/yaml-main-cases/06.json | 6 + .../test/resources/yaml-main-cases/06.yaml | 3 + .../test/resources/yaml-main-cases/07.dhall | 1 + .../test/resources/yaml-main-cases/07.json | 5 + .../test/resources/yaml-main-cases/07.yaml | 2 + .../test/resources/yaml-main-cases/08.dhall | 1 + .../test/resources/yaml-main-cases/08.json | 7 + .../test/resources/yaml-main-cases/08.yaml | 4 + .../test/resources/yaml-main-cases/09.dhall | 1 + .../test/resources/yaml-main-cases/09.json | 3 + .../test/resources/yaml-main-cases/09.yaml | 1 + .../test/resources/yaml-main-cases/10.dhall | 1 + .../test/resources/yaml-main-cases/10.json | 7 + .../test/resources/yaml-main-cases/10.yaml | 6 + .../test/resources/yaml-main-cases/11.dhall | 1 + .../test/resources/yaml-main-cases/11.json | 5 + .../test/resources/yaml-main-cases/11.yaml | 5 + .../test/resources/yaml-main-cases/12.dhall | 1 + .../test/resources/yaml-main-cases/12.json | 3 + .../test/resources/yaml-main-cases/12.yaml | 3 + .../test/resources/yaml-main-cases/13.dhall | 1 + .../test/resources/yaml-main-cases/13.json | 3 + .../test/resources/yaml-main-cases/13.yaml | 1 + .../test/resources/yaml-main-cases/14.dhall | 1 + .../test/resources/yaml-main-cases/14.json | 3 + .../test/resources/yaml-main-cases/14.yaml | 1 + .../test/resources/yaml-main-cases/15.dhall | 1 + .../test/resources/yaml-main-cases/15.json | 3 + .../test/resources/yaml-main-cases/15.yaml | 1 + .../test/resources/yaml-main-cases/16.dhall | 1 + .../test/resources/yaml-main-cases/16.json | 11 + .../test/resources/yaml-main-cases/16.yaml | 7 + .../test/resources/yaml-main-cases/17.dhall | 1 + .../test/resources/yaml-main-cases/17.json | 4 + .../test/resources/yaml-main-cases/17.yaml | 2 + .../test/resources/yaml-main-cases/18.dhall | 1 + .../test/resources/yaml-main-cases/18.json | 10 + .../test/resources/yaml-main-cases/18.yaml | 6 + .../test/resources/yaml-main-cases/19.dhall | 1 + .../test/resources/yaml-main-cases/19.json | 10 + .../test/resources/yaml-main-cases/19.yaml | 6 + .../test/resources/yaml-main-cases/20.dhall | 1 + .../test/resources/yaml-main-cases/20.json | 11 + .../test/resources/yaml-main-cases/20.yaml | 5 + .../test/resources/yaml-main-cases/21.dhall | 1 + .../test/resources/yaml-main-cases/21.json | 11 + .../test/resources/yaml-main-cases/21.yaml | 5 + .../test/resources/yaml-main-cases/22.dhall | 1 + .../test/resources/yaml-main-cases/22.json | 5 + .../test/resources/yaml-main-cases/22.yaml | 3 + .../test/resources/yaml-main-cases/23.dhall | 1 + .../test/resources/yaml-main-cases/23.json | 5 + .../test/resources/yaml-main-cases/23.yaml | 3 + .../test/resources/yaml-main-cases/24.dhall | 9 + .../test/resources/yaml-main-cases/24.json | 15 + .../test/resources/yaml-main-cases/24.yaml | 12 + .../test/resources/yaml-main-cases/25.dhall | 61 ++++ .../test/resources/yaml-main-cases/25.json | 88 ++++++ .../test/resources/yaml-main-cases/25.yaml | 69 +++++ .../test/resources/yaml-main-cases/26.dhall | 160 +++++++++++ .../test/resources/yaml-main-cases/26.json | 227 +++++++++++++++ .../test/resources/yaml-main-cases/26.yaml | 180 ++++++++++++ .../io/chymyst/dhall/unit/MainSpec.scala | 111 +++---- .../main/scala/io/chymyst/dhall/Yaml.scala | 270 ++++++++++++++---- .../io/chymyst/dhall/unit/JsonTest.scala | 34 +++ .../io/chymyst/dhall/unit/YamlTest.scala | 164 +++-------- 84 files changed, 1425 insertions(+), 265 deletions(-) create mode 100644 scall-cli/src/test/resources/yaml-main-cases/01.dhall create mode 100644 scall-cli/src/test/resources/yaml-main-cases/01.json create mode 100644 scall-cli/src/test/resources/yaml-main-cases/01.yaml create mode 100644 scall-cli/src/test/resources/yaml-main-cases/02.dhall create mode 100644 scall-cli/src/test/resources/yaml-main-cases/02.json create mode 100644 scall-cli/src/test/resources/yaml-main-cases/02.yaml create mode 100644 scall-cli/src/test/resources/yaml-main-cases/03.dhall create mode 100644 scall-cli/src/test/resources/yaml-main-cases/03.json create mode 100644 scall-cli/src/test/resources/yaml-main-cases/03.yaml create mode 100644 scall-cli/src/test/resources/yaml-main-cases/04.dhall create mode 100644 scall-cli/src/test/resources/yaml-main-cases/04.json create mode 100644 scall-cli/src/test/resources/yaml-main-cases/04.yaml create mode 100644 scall-cli/src/test/resources/yaml-main-cases/05.dhall create mode 100644 scall-cli/src/test/resources/yaml-main-cases/05.json create mode 100644 scall-cli/src/test/resources/yaml-main-cases/05.yaml create mode 100644 scall-cli/src/test/resources/yaml-main-cases/06.dhall create mode 100644 scall-cli/src/test/resources/yaml-main-cases/06.json create mode 100644 scall-cli/src/test/resources/yaml-main-cases/06.yaml create mode 100644 scall-cli/src/test/resources/yaml-main-cases/07.dhall create mode 100644 scall-cli/src/test/resources/yaml-main-cases/07.json create mode 100644 scall-cli/src/test/resources/yaml-main-cases/07.yaml create mode 100644 scall-cli/src/test/resources/yaml-main-cases/08.dhall create mode 100644 scall-cli/src/test/resources/yaml-main-cases/08.json create mode 100644 scall-cli/src/test/resources/yaml-main-cases/08.yaml create mode 100644 scall-cli/src/test/resources/yaml-main-cases/09.dhall create mode 100644 scall-cli/src/test/resources/yaml-main-cases/09.json create mode 100644 scall-cli/src/test/resources/yaml-main-cases/09.yaml create mode 100644 scall-cli/src/test/resources/yaml-main-cases/10.dhall create mode 100644 scall-cli/src/test/resources/yaml-main-cases/10.json create mode 100644 scall-cli/src/test/resources/yaml-main-cases/10.yaml create mode 100644 scall-cli/src/test/resources/yaml-main-cases/11.dhall create mode 100644 scall-cli/src/test/resources/yaml-main-cases/11.json create mode 100644 scall-cli/src/test/resources/yaml-main-cases/11.yaml create mode 100644 scall-cli/src/test/resources/yaml-main-cases/12.dhall create mode 100644 scall-cli/src/test/resources/yaml-main-cases/12.json create mode 100644 scall-cli/src/test/resources/yaml-main-cases/12.yaml create mode 100644 scall-cli/src/test/resources/yaml-main-cases/13.dhall create mode 100644 scall-cli/src/test/resources/yaml-main-cases/13.json create mode 100644 scall-cli/src/test/resources/yaml-main-cases/13.yaml create mode 100644 scall-cli/src/test/resources/yaml-main-cases/14.dhall create mode 100644 scall-cli/src/test/resources/yaml-main-cases/14.json create mode 100644 scall-cli/src/test/resources/yaml-main-cases/14.yaml create mode 100644 scall-cli/src/test/resources/yaml-main-cases/15.dhall create mode 100644 scall-cli/src/test/resources/yaml-main-cases/15.json create mode 100644 scall-cli/src/test/resources/yaml-main-cases/15.yaml create mode 100644 scall-cli/src/test/resources/yaml-main-cases/16.dhall create mode 100644 scall-cli/src/test/resources/yaml-main-cases/16.json create mode 100644 scall-cli/src/test/resources/yaml-main-cases/16.yaml create mode 100644 scall-cli/src/test/resources/yaml-main-cases/17.dhall create mode 100644 scall-cli/src/test/resources/yaml-main-cases/17.json create mode 100644 scall-cli/src/test/resources/yaml-main-cases/17.yaml create mode 100644 scall-cli/src/test/resources/yaml-main-cases/18.dhall create mode 100644 scall-cli/src/test/resources/yaml-main-cases/18.json create mode 100644 scall-cli/src/test/resources/yaml-main-cases/18.yaml create mode 100644 scall-cli/src/test/resources/yaml-main-cases/19.dhall create mode 100644 scall-cli/src/test/resources/yaml-main-cases/19.json create mode 100644 scall-cli/src/test/resources/yaml-main-cases/19.yaml create mode 100644 scall-cli/src/test/resources/yaml-main-cases/20.dhall create mode 100644 scall-cli/src/test/resources/yaml-main-cases/20.json create mode 100644 scall-cli/src/test/resources/yaml-main-cases/20.yaml create mode 100644 scall-cli/src/test/resources/yaml-main-cases/21.dhall create mode 100644 scall-cli/src/test/resources/yaml-main-cases/21.json create mode 100644 scall-cli/src/test/resources/yaml-main-cases/21.yaml create mode 100644 scall-cli/src/test/resources/yaml-main-cases/22.dhall create mode 100644 scall-cli/src/test/resources/yaml-main-cases/22.json create mode 100644 scall-cli/src/test/resources/yaml-main-cases/22.yaml create mode 100644 scall-cli/src/test/resources/yaml-main-cases/23.dhall create mode 100644 scall-cli/src/test/resources/yaml-main-cases/23.json create mode 100644 scall-cli/src/test/resources/yaml-main-cases/23.yaml create mode 100644 scall-cli/src/test/resources/yaml-main-cases/24.dhall create mode 100644 scall-cli/src/test/resources/yaml-main-cases/24.json create mode 100644 scall-cli/src/test/resources/yaml-main-cases/24.yaml create mode 100644 scall-cli/src/test/resources/yaml-main-cases/25.dhall create mode 100644 scall-cli/src/test/resources/yaml-main-cases/25.json create mode 100644 scall-cli/src/test/resources/yaml-main-cases/25.yaml create mode 100644 scall-cli/src/test/resources/yaml-main-cases/26.dhall create mode 100644 scall-cli/src/test/resources/yaml-main-cases/26.json create mode 100644 scall-cli/src/test/resources/yaml-main-cases/26.yaml create mode 100644 scall-core/src/test/scala/io/chymyst/dhall/unit/JsonTest.scala diff --git a/README.md b/README.md index 5392d652..d830fd5a 100644 --- a/README.md +++ b/README.md @@ -246,14 +246,14 @@ The test script should print "Tests successful." at the end. If it does not prin ```bash $ java -jar ./dhall.jar --help -dhall.jar +java -jar dhall.jar --flags... command -f --file Path to the input Dhall file (default: stdin) + -o --output Path to the output file (default: stdout) -q --quoted Quote all strings (for Yaml output only; default is false) -d --documents Create a Yaml file with document separators (for Yaml output only; default is false) -i --indent Indentation depth for JSON and Yaml (default: 2) - -o --output Path to the output file (default: stdout) - command ... Optional command: decode, encode, hash, text, type, yaml + command ... Optional command: decode, encode, hash, text, type, yaml, json ``` Examples: @@ -264,13 +264,19 @@ $ java -jar ./dhall.jar --file ./scall-cli/src/test/resources/jar-tests/3.dhall { True = [1.23, 4.56], a = 2, b = None Bool, c = Some "abc", y = True } ``` -Compute the type of a Dhall expression. +Print the inferred type of a Dhall expression. ```bash $ java -jar ./dhall.jar --file ./scall-cli/src/test/resources/jar-tests/3.dhall type { True : List Double, a : Natural, b : Optional Bool, c : Optional Text, y : Bool } ``` -Export a Dhall expression to Yaml format. +Compute the SHA256 hash of a Dhall expression. +```bash +$ java -jar ./dhall.jar --file ./scall-cli/src/test/resources/jar-tests/3.dhall hash +sha256:e06ccdb4df3721dba87291eb49754c87955462d73df626e5e4c77de3af06e87f +``` + +Export a Dhall expression to Yaml format. Default indentation is 2 spaces. ```bash $ java -jar ./dhall.jar --file ./scall-cli/src/test/resources/jar-tests/3.dhall yaml 'True': @@ -281,8 +287,18 @@ c: abc 'y': true ``` -Compute the SHA256 hash of a Dhall expression. + +Export a Dhall expression to JSON format, with 4 spaces of indentation. ```bash -$ java -jar ./dhall.jar --file ./scall-cli/src/test/resources/jar-tests/3.dhall hash -sha256:e06ccdb4df3721dba87291eb49754c87955462d73df626e5e4c77de3af06e87f +$ java -jar ./dhall.jar --file ./scall-cli/src/test/resources/jar-tests/3.dhall --indent 4 json +{ + "True": [ + 1.23, + 4.56 + ], + "a": 2, + "c": "abc", + "y": true +} ``` + diff --git a/scall-cli/src/main/scala/io/chymyst/dhall/Main.scala b/scall-cli/src/main/scala/io/chymyst/dhall/Main.scala index 0eca3456..e89b40c5 100644 --- a/scall-cli/src/main/scala/io/chymyst/dhall/Main.scala +++ b/scall-cli/src/main/scala/io/chymyst/dhall/Main.scala @@ -15,6 +15,7 @@ object Main { case object Dhall extends OutputMode case object Text extends OutputMode case object Yaml extends OutputMode + case object Json extends OutputMode case object Decode extends OutputMode case object Encode extends OutputMode case object GetType extends OutputMode @@ -34,22 +35,22 @@ object Main { val result: Array[Byte] = valueType match { case TypecheckResult.Valid((tpe: Expression, expr: Expression)) => outputMode match { - case OutputMode.Dhall => (expr.print + "\n").getBytes("UTF-8") - case OutputMode.Text => + case OutputMode.Dhall => (expr.print + "\n").getBytes("UTF-8") + case OutputMode.Text => (expr.scheme match { case ExpressionScheme.TextLiteral(List(), trailing) => trailing + "\n" case s => s"Error: Dhall expression should have type Text but is instead: $s\n" }).getBytes("UTF-8") - case OutputMode.Yaml => + case OutputMode.Yaml | OutputMode.Json => (Yaml.toYaml(dhallFile.copy(value = expr), options) match { case Left(value) => value + "\n" case Right(value) => value }).getBytes("UTF-8") - case OutputMode.Encode => + case OutputMode.Encode => expr.toCBORmodel.encodeCbor2 - case OutputMode.GetType => + case OutputMode.GetType => (tpe.print + "\n").getBytes("UTF-8") - case OutputMode.GetHash => + case OutputMode.GetHash => ("sha256:" + Semantics.semanticHash(expr, Paths.get(".")) + "\n").getBytes("UTF-8") } @@ -67,6 +68,7 @@ object Main { def parseArgs(args: Array[String]): OutputMode = args.lastOption match { case Some("text") => OutputMode.Text case Some("yaml") => OutputMode.Yaml + case Some("json") => OutputMode.Json case Some("decode") => OutputMode.Decode case Some("encode") => OutputMode.Encode case Some("type") => OutputMode.GetType @@ -77,8 +79,8 @@ object Main { val defaultIndent = 2 // $COVERAGE-OFF$ - @main // This method will be called by `ParserForMethods.runOrExist()` automatically. - def `dhall.jar`( + @main // This method will be called by `ParserForMethods.runOrExist()` automatically. + def `java -jar dhall.jar --flags... command`( // The name `dhall.jar` will be printed at the top of the help text. @arg(short = 'f', doc = "Path to the input Dhall file (default: stdin)") file: Option[String], @arg(short = 'o', doc = "Path to the output file (default: stdout)") @@ -89,7 +91,7 @@ object Main { documents: Flag, @arg(short = 'i', doc = "Indentation depth for JSON and Yaml (default: 2)") indent: Option[Int], - @arg(doc = "Optional command: decode, encode, hash, text, type, yaml") + @arg(doc = "Optional command: decode, encode, hash, text, type, yaml, json") command: Leftover[String], ): Unit = { val (inputPath, inputStream) = file match { @@ -102,12 +104,18 @@ object Main { case Some(outputFile) => new FileOutputStream(outputFile) case None => System.out } + val outputMode = parseArgs(command.value.toArray) process( inputPath, inputStream, outputStream, - parseArgs(command.value.toArray), - YamlOptions(quoteAllStrings = quoted.value, createDocuments = documents.value, indent = indent.getOrElse(defaultIndent)), + outputMode, + YamlOptions( + quoteAllStrings = quoted.value, + createDocuments = documents.value, + indent = indent.getOrElse(defaultIndent), + jsonFormat = outputMode == OutputMode.Json, + ), ) } def main(args: Array[String]): Unit = ParserForMethods(this).runOrExit(args) diff --git a/scall-cli/src/test/resources/yaml-main-cases/01.dhall b/scall-cli/src/test/resources/yaml-main-cases/01.dhall new file mode 100644 index 00000000..c7d6764c --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/01.dhall @@ -0,0 +1 @@ +{a = < A | B>.A } diff --git a/scall-cli/src/test/resources/yaml-main-cases/01.json b/scall-cli/src/test/resources/yaml-main-cases/01.json new file mode 100644 index 00000000..19a786f7 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/01.json @@ -0,0 +1,3 @@ +{ + "a": "A" +} diff --git a/scall-cli/src/test/resources/yaml-main-cases/01.yaml b/scall-cli/src/test/resources/yaml-main-cases/01.yaml new file mode 100644 index 00000000..2b7e2fa8 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/01.yaml @@ -0,0 +1 @@ +a: A diff --git a/scall-cli/src/test/resources/yaml-main-cases/02.dhall b/scall-cli/src/test/resources/yaml-main-cases/02.dhall new file mode 100644 index 00000000..fe3515f7 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/02.dhall @@ -0,0 +1 @@ +{a = < A | B : Natural>.B 123 } diff --git a/scall-cli/src/test/resources/yaml-main-cases/02.json b/scall-cli/src/test/resources/yaml-main-cases/02.json new file mode 100644 index 00000000..83af786d --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/02.json @@ -0,0 +1,3 @@ +{ + "a": 123 +} diff --git a/scall-cli/src/test/resources/yaml-main-cases/02.yaml b/scall-cli/src/test/resources/yaml-main-cases/02.yaml new file mode 100644 index 00000000..b70158fc --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/02.yaml @@ -0,0 +1 @@ +a: 123 diff --git a/scall-cli/src/test/resources/yaml-main-cases/03.dhall b/scall-cli/src/test/resources/yaml-main-cases/03.dhall new file mode 100644 index 00000000..e56e39e2 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/03.dhall @@ -0,0 +1 @@ +{a.b = [] : List Bool } diff --git a/scall-cli/src/test/resources/yaml-main-cases/03.json b/scall-cli/src/test/resources/yaml-main-cases/03.json new file mode 100644 index 00000000..a5dc0ee6 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/03.json @@ -0,0 +1,5 @@ +{ + "a": { + "b": [] + } +} diff --git a/scall-cli/src/test/resources/yaml-main-cases/03.yaml b/scall-cli/src/test/resources/yaml-main-cases/03.yaml new file mode 100644 index 00000000..bb98fa18 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/03.yaml @@ -0,0 +1,2 @@ +a: + b: [] diff --git a/scall-cli/src/test/resources/yaml-main-cases/04.dhall b/scall-cli/src/test/resources/yaml-main-cases/04.dhall new file mode 100644 index 00000000..6c1a1dc1 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/04.dhall @@ -0,0 +1 @@ +{a.b = {=} } diff --git a/scall-cli/src/test/resources/yaml-main-cases/04.json b/scall-cli/src/test/resources/yaml-main-cases/04.json new file mode 100644 index 00000000..ed10cd23 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/04.json @@ -0,0 +1,5 @@ +{ + "a": { + "b": {} + } +} diff --git a/scall-cli/src/test/resources/yaml-main-cases/04.yaml b/scall-cli/src/test/resources/yaml-main-cases/04.yaml new file mode 100644 index 00000000..631a2ed0 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/04.yaml @@ -0,0 +1,2 @@ +a: + b: {} diff --git a/scall-cli/src/test/resources/yaml-main-cases/05.dhall b/scall-cli/src/test/resources/yaml-main-cases/05.dhall new file mode 100644 index 00000000..0a799dcf --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/05.dhall @@ -0,0 +1 @@ +{a.b ="e" } diff --git a/scall-cli/src/test/resources/yaml-main-cases/05.json b/scall-cli/src/test/resources/yaml-main-cases/05.json new file mode 100644 index 00000000..e59d1b4f --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/05.json @@ -0,0 +1,5 @@ +{ + "a": { + "b": "e" + } +} diff --git a/scall-cli/src/test/resources/yaml-main-cases/05.yaml b/scall-cli/src/test/resources/yaml-main-cases/05.yaml new file mode 100644 index 00000000..4adb402a --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/05.yaml @@ -0,0 +1,2 @@ +a: + b: 'e' diff --git a/scall-cli/src/test/resources/yaml-main-cases/06.dhall b/scall-cli/src/test/resources/yaml-main-cases/06.dhall new file mode 100644 index 00000000..30e5649a --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/06.dhall @@ -0,0 +1 @@ +{a.b ="e", a.c = "f" } diff --git a/scall-cli/src/test/resources/yaml-main-cases/06.json b/scall-cli/src/test/resources/yaml-main-cases/06.json new file mode 100644 index 00000000..7fc0d32b --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/06.json @@ -0,0 +1,6 @@ +{ + "a": { + "b": "e", + "c": "f" + } +} diff --git a/scall-cli/src/test/resources/yaml-main-cases/06.yaml b/scall-cli/src/test/resources/yaml-main-cases/06.yaml new file mode 100644 index 00000000..a165cb55 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/06.yaml @@ -0,0 +1,3 @@ +a: + b: 'e' + c: f diff --git a/scall-cli/src/test/resources/yaml-main-cases/07.dhall b/scall-cli/src/test/resources/yaml-main-cases/07.dhall new file mode 100644 index 00000000..c9e160da --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/07.dhall @@ -0,0 +1 @@ +{a = ["e"]} diff --git a/scall-cli/src/test/resources/yaml-main-cases/07.json b/scall-cli/src/test/resources/yaml-main-cases/07.json new file mode 100644 index 00000000..937a81b4 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/07.json @@ -0,0 +1,5 @@ +{ + "a": [ + "e" + ] +} diff --git a/scall-cli/src/test/resources/yaml-main-cases/07.yaml b/scall-cli/src/test/resources/yaml-main-cases/07.yaml new file mode 100644 index 00000000..173f9300 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/07.yaml @@ -0,0 +1,2 @@ +a: + - 'e' diff --git a/scall-cli/src/test/resources/yaml-main-cases/08.dhall b/scall-cli/src/test/resources/yaml-main-cases/08.dhall new file mode 100644 index 00000000..f372e575 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/08.dhall @@ -0,0 +1 @@ +{a = [" - c","d","e"]} diff --git a/scall-cli/src/test/resources/yaml-main-cases/08.json b/scall-cli/src/test/resources/yaml-main-cases/08.json new file mode 100644 index 00000000..9240076f --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/08.json @@ -0,0 +1,7 @@ +{ + "a": [ + " - c", + "d", + "e" + ] +} diff --git a/scall-cli/src/test/resources/yaml-main-cases/08.yaml b/scall-cli/src/test/resources/yaml-main-cases/08.yaml new file mode 100644 index 00000000..bd5d7de2 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/08.yaml @@ -0,0 +1,4 @@ +a: + - " - c" + - d + - 'e' diff --git a/scall-cli/src/test/resources/yaml-main-cases/09.dhall b/scall-cli/src/test/resources/yaml-main-cases/09.dhall new file mode 100644 index 00000000..470e8253 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/09.dhall @@ -0,0 +1 @@ +{a = "a-b: c"} diff --git a/scall-cli/src/test/resources/yaml-main-cases/09.json b/scall-cli/src/test/resources/yaml-main-cases/09.json new file mode 100644 index 00000000..18205681 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/09.json @@ -0,0 +1,3 @@ +{ + "a": "a-b: c" +} diff --git a/scall-cli/src/test/resources/yaml-main-cases/09.yaml b/scall-cli/src/test/resources/yaml-main-cases/09.yaml new file mode 100644 index 00000000..c85b26b3 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/09.yaml @@ -0,0 +1 @@ +a: "a-b: c" diff --git a/scall-cli/src/test/resources/yaml-main-cases/10.dhall b/scall-cli/src/test/resources/yaml-main-cases/10.dhall new file mode 100644 index 00000000..41e52e81 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/10.dhall @@ -0,0 +1 @@ +{a = ["-\n\"-\"", "a", "b"]} diff --git a/scall-cli/src/test/resources/yaml-main-cases/10.json b/scall-cli/src/test/resources/yaml-main-cases/10.json new file mode 100644 index 00000000..6e33637b --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/10.json @@ -0,0 +1,7 @@ +{ + "a": [ + "-\n\"-\"", + "a", + "b" + ] +} diff --git a/scall-cli/src/test/resources/yaml-main-cases/10.yaml b/scall-cli/src/test/resources/yaml-main-cases/10.yaml new file mode 100644 index 00000000..97150209 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/10.yaml @@ -0,0 +1,6 @@ +a: + - | + - + "-" + - a + - b diff --git a/scall-cli/src/test/resources/yaml-main-cases/11.dhall b/scall-cli/src/test/resources/yaml-main-cases/11.dhall new file mode 100644 index 00000000..9d88ffb8 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/11.dhall @@ -0,0 +1 @@ +[ "-\n\"-\"", "a", "b"] diff --git a/scall-cli/src/test/resources/yaml-main-cases/11.json b/scall-cli/src/test/resources/yaml-main-cases/11.json new file mode 100644 index 00000000..1e50c186 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/11.json @@ -0,0 +1,5 @@ +[ + "-\n\"-\"", + "a", + "b" +] diff --git a/scall-cli/src/test/resources/yaml-main-cases/11.yaml b/scall-cli/src/test/resources/yaml-main-cases/11.yaml new file mode 100644 index 00000000..dedd935e --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/11.yaml @@ -0,0 +1,5 @@ +- | + - + "-" +- a +- b diff --git a/scall-cli/src/test/resources/yaml-main-cases/12.dhall b/scall-cli/src/test/resources/yaml-main-cases/12.dhall new file mode 100644 index 00000000..4f49db92 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/12.dhall @@ -0,0 +1 @@ +{a = "-\n\"-\""} diff --git a/scall-cli/src/test/resources/yaml-main-cases/12.json b/scall-cli/src/test/resources/yaml-main-cases/12.json new file mode 100644 index 00000000..ec0027ce --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/12.json @@ -0,0 +1,3 @@ +{ + "a": "-\n\"-\"" +} diff --git a/scall-cli/src/test/resources/yaml-main-cases/12.yaml b/scall-cli/src/test/resources/yaml-main-cases/12.yaml new file mode 100644 index 00000000..e9dd97cc --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/12.yaml @@ -0,0 +1,3 @@ +a: | + - + "-" diff --git a/scall-cli/src/test/resources/yaml-main-cases/13.dhall b/scall-cli/src/test/resources/yaml-main-cases/13.dhall new file mode 100644 index 00000000..65c37ffb --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/13.dhall @@ -0,0 +1 @@ +{a = "\"abc\""} diff --git a/scall-cli/src/test/resources/yaml-main-cases/13.json b/scall-cli/src/test/resources/yaml-main-cases/13.json new file mode 100644 index 00000000..e943d835 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/13.json @@ -0,0 +1,3 @@ +{ + "a": "\"abc\"" +} diff --git a/scall-cli/src/test/resources/yaml-main-cases/13.yaml b/scall-cli/src/test/resources/yaml-main-cases/13.yaml new file mode 100644 index 00000000..15744e2a --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/13.yaml @@ -0,0 +1 @@ +a: "\"abc\"" diff --git a/scall-cli/src/test/resources/yaml-main-cases/14.dhall b/scall-cli/src/test/resources/yaml-main-cases/14.dhall new file mode 100644 index 00000000..4de48147 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/14.dhall @@ -0,0 +1 @@ +{a = "a-b"} diff --git a/scall-cli/src/test/resources/yaml-main-cases/14.json b/scall-cli/src/test/resources/yaml-main-cases/14.json new file mode 100644 index 00000000..d65dcc88 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/14.json @@ -0,0 +1,3 @@ +{ + "a": "a-b" +} diff --git a/scall-cli/src/test/resources/yaml-main-cases/14.yaml b/scall-cli/src/test/resources/yaml-main-cases/14.yaml new file mode 100644 index 00000000..a13b8b71 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/14.yaml @@ -0,0 +1 @@ +a: a-b diff --git a/scall-cli/src/test/resources/yaml-main-cases/15.dhall b/scall-cli/src/test/resources/yaml-main-cases/15.dhall new file mode 100644 index 00000000..9b6bbb13 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/15.dhall @@ -0,0 +1 @@ +{a = "-"} diff --git a/scall-cli/src/test/resources/yaml-main-cases/15.json b/scall-cli/src/test/resources/yaml-main-cases/15.json new file mode 100644 index 00000000..abf658e8 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/15.json @@ -0,0 +1,3 @@ +{ + "a": "-" +} diff --git a/scall-cli/src/test/resources/yaml-main-cases/15.yaml b/scall-cli/src/test/resources/yaml-main-cases/15.yaml new file mode 100644 index 00000000..1746b8aa --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/15.yaml @@ -0,0 +1 @@ +a: "-" diff --git a/scall-cli/src/test/resources/yaml-main-cases/16.dhall b/scall-cli/src/test/resources/yaml-main-cases/16.dhall new file mode 100644 index 00000000..454a9081 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/16.dhall @@ -0,0 +1 @@ +{a = [1, 2, 3], b= [4, 5]} diff --git a/scall-cli/src/test/resources/yaml-main-cases/16.json b/scall-cli/src/test/resources/yaml-main-cases/16.json new file mode 100644 index 00000000..53f34d22 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/16.json @@ -0,0 +1,11 @@ +{ + "a": [ + 1, + 2, + 3 + ], + "b": [ + 4, + 5 + ] +} diff --git a/scall-cli/src/test/resources/yaml-main-cases/16.yaml b/scall-cli/src/test/resources/yaml-main-cases/16.yaml new file mode 100644 index 00000000..feaf652b --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/16.yaml @@ -0,0 +1,7 @@ +a: + - 1 + - 2 + - 3 +b: + - 4 + - 5 diff --git a/scall-cli/src/test/resources/yaml-main-cases/17.dhall b/scall-cli/src/test/resources/yaml-main-cases/17.dhall new file mode 100644 index 00000000..4ac9ee4f --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/17.dhall @@ -0,0 +1 @@ +[{mapKey="a",mapValue=123},{mapKey="b",mapValue=456}] diff --git a/scall-cli/src/test/resources/yaml-main-cases/17.json b/scall-cli/src/test/resources/yaml-main-cases/17.json new file mode 100644 index 00000000..f95f8246 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/17.json @@ -0,0 +1,4 @@ +{ + "a": 123, + "b": 456 +} diff --git a/scall-cli/src/test/resources/yaml-main-cases/17.yaml b/scall-cli/src/test/resources/yaml-main-cases/17.yaml new file mode 100644 index 00000000..d0725028 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/17.yaml @@ -0,0 +1,2 @@ +a: 123 +b: 456 diff --git a/scall-cli/src/test/resources/yaml-main-cases/18.dhall b/scall-cli/src/test/resources/yaml-main-cases/18.dhall new file mode 100644 index 00000000..82d6118c --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/18.dhall @@ -0,0 +1 @@ +{x = Some {a = 1, b = Some 2, c = None Natural}, z = None Bool, y = {c = Some 3, d = 4}} diff --git a/scall-cli/src/test/resources/yaml-main-cases/18.json b/scall-cli/src/test/resources/yaml-main-cases/18.json new file mode 100644 index 00000000..0e91faaf --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/18.json @@ -0,0 +1,10 @@ +{ + "x": { + "a": 1, + "b": 2 + }, + "y": { + "c": 3, + "d": 4 + } +} diff --git a/scall-cli/src/test/resources/yaml-main-cases/18.yaml b/scall-cli/src/test/resources/yaml-main-cases/18.yaml new file mode 100644 index 00000000..65c4235e --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/18.yaml @@ -0,0 +1,6 @@ +x: + a: 1 + b: 2 +'y': + c: 3 + d: 4 diff --git a/scall-cli/src/test/resources/yaml-main-cases/19.dhall b/scall-cli/src/test/resources/yaml-main-cases/19.dhall new file mode 100644 index 00000000..d10ec655 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/19.dhall @@ -0,0 +1 @@ +{x = {a = 1, b = 2}, y = {c = 3, d = 4}} diff --git a/scall-cli/src/test/resources/yaml-main-cases/19.json b/scall-cli/src/test/resources/yaml-main-cases/19.json new file mode 100644 index 00000000..0e91faaf --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/19.json @@ -0,0 +1,10 @@ +{ + "x": { + "a": 1, + "b": 2 + }, + "y": { + "c": 3, + "d": 4 + } +} diff --git a/scall-cli/src/test/resources/yaml-main-cases/19.yaml b/scall-cli/src/test/resources/yaml-main-cases/19.yaml new file mode 100644 index 00000000..65c4235e --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/19.yaml @@ -0,0 +1,6 @@ +x: + a: 1 + b: 2 +'y': + c: 3 + d: 4 diff --git a/scall-cli/src/test/resources/yaml-main-cases/20.dhall b/scall-cli/src/test/resources/yaml-main-cases/20.dhall new file mode 100644 index 00000000..13d4c652 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/20.dhall @@ -0,0 +1 @@ +[Some {a = 1, b = 2}, None { a : Natural, b : Natural }, Some {a = 3, b = 4}] diff --git a/scall-cli/src/test/resources/yaml-main-cases/20.json b/scall-cli/src/test/resources/yaml-main-cases/20.json new file mode 100644 index 00000000..88c48a49 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/20.json @@ -0,0 +1,11 @@ +[ + { + "a": 1, + "b": 2 + }, + null, + { + "a": 3, + "b": 4 + } +] diff --git a/scall-cli/src/test/resources/yaml-main-cases/20.yaml b/scall-cli/src/test/resources/yaml-main-cases/20.yaml new file mode 100644 index 00000000..50b8ab56 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/20.yaml @@ -0,0 +1,5 @@ +- a: 1 + b: 2 +- null +- a: 3 + b: 4 diff --git a/scall-cli/src/test/resources/yaml-main-cases/21.dhall b/scall-cli/src/test/resources/yaml-main-cases/21.dhall new file mode 100644 index 00000000..2be9aef3 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/21.dhall @@ -0,0 +1 @@ +[[1, 2, 3], [4, 5]] diff --git a/scall-cli/src/test/resources/yaml-main-cases/21.json b/scall-cli/src/test/resources/yaml-main-cases/21.json new file mode 100644 index 00000000..c5384291 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/21.json @@ -0,0 +1,11 @@ +[ + [ + 1, + 2, + 3 + ], + [ + 4, + 5 + ] +] diff --git a/scall-cli/src/test/resources/yaml-main-cases/21.yaml b/scall-cli/src/test/resources/yaml-main-cases/21.yaml new file mode 100644 index 00000000..249c46ac --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/21.yaml @@ -0,0 +1,5 @@ +- - 1 + - 2 + - 3 +- - 4 + - 5 diff --git a/scall-cli/src/test/resources/yaml-main-cases/22.dhall b/scall-cli/src/test/resources/yaml-main-cases/22.dhall new file mode 100644 index 00000000..c6ade205 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/22.dhall @@ -0,0 +1 @@ +{ a = 1, b = 2, c = 3 } diff --git a/scall-cli/src/test/resources/yaml-main-cases/22.json b/scall-cli/src/test/resources/yaml-main-cases/22.json new file mode 100644 index 00000000..d1f6dac4 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/22.json @@ -0,0 +1,5 @@ +{ + "a": 1, + "b": 2, + "c": 3 +} diff --git a/scall-cli/src/test/resources/yaml-main-cases/22.yaml b/scall-cli/src/test/resources/yaml-main-cases/22.yaml new file mode 100644 index 00000000..894c6553 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/22.yaml @@ -0,0 +1,3 @@ +a: 1 +b: 2 +c: 3 diff --git a/scall-cli/src/test/resources/yaml-main-cases/23.dhall b/scall-cli/src/test/resources/yaml-main-cases/23.dhall new file mode 100644 index 00000000..b5d8bb58 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/23.dhall @@ -0,0 +1 @@ +[1, 2, 3] diff --git a/scall-cli/src/test/resources/yaml-main-cases/23.json b/scall-cli/src/test/resources/yaml-main-cases/23.json new file mode 100644 index 00000000..a85b7c92 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/23.json @@ -0,0 +1,5 @@ +[ + 1, + 2, + 3 +] diff --git a/scall-cli/src/test/resources/yaml-main-cases/23.yaml b/scall-cli/src/test/resources/yaml-main-cases/23.yaml new file mode 100644 index 00000000..a0cd6f38 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/23.yaml @@ -0,0 +1,3 @@ +- 1 +- 2 +- 3 diff --git a/scall-cli/src/test/resources/yaml-main-cases/24.dhall b/scall-cli/src/test/resources/yaml-main-cases/24.dhall new file mode 100644 index 00000000..6f50c98a --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/24.dhall @@ -0,0 +1,9 @@ +{ a = 12:00:00 +, b = 2020-04-08 +, c = 2020-04-08T12:00:00 +, d = 2020-04-08T12:00:00+00:00 +, e = 2020-04-08T12:00:00+03:00 +, f = { date = 2020-04-08, time = 12:00:00 } +, g = { date = 2020-04-08, time = 12:00:00, timeZone = +03:00 } +, h = { x = 0, date = 2020-04-08, time = 12:00:00, timeZone = +03:00 } +} diff --git a/scall-cli/src/test/resources/yaml-main-cases/24.json b/scall-cli/src/test/resources/yaml-main-cases/24.json new file mode 100644 index 00000000..27fffe9a --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/24.json @@ -0,0 +1,15 @@ +{ + "a": "12:00:00", + "b": "2020-04-08", + "c": "2020-04-08T12:00:00", + "d": "2020-04-08T12:00:00+00:00", + "e": "2020-04-08T12:00:00+03:00", + "f": "2020-04-08T12:00:00", + "g": "2020-04-08T12:00:00+03:00", + "h": { + "date": "2020-04-08", + "time": "12:00:00", + "timeZone": "+03:00", + "x": 0 + } +} diff --git a/scall-cli/src/test/resources/yaml-main-cases/24.yaml b/scall-cli/src/test/resources/yaml-main-cases/24.yaml new file mode 100644 index 00000000..b6f971f4 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/24.yaml @@ -0,0 +1,12 @@ +a: "12:00:00" +b: '2020-04-08' +c: "2020-04-08T12:00:00" +d: "2020-04-08T12:00:00+00:00" +'e': "2020-04-08T12:00:00+03:00" +f: "2020-04-08T12:00:00" +g: "2020-04-08T12:00:00+03:00" +h: + date: '2020-04-08' + time: "12:00:00" + timeZone: "+03:00" + x: 0 diff --git a/scall-cli/src/test/resources/yaml-main-cases/25.dhall b/scall-cli/src/test/resources/yaml-main-cases/25.dhall new file mode 100644 index 00000000..b3a180b8 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/25.dhall @@ -0,0 +1,61 @@ +{ result = + [ { creditCard = + { cvv = "837", issuer = "jcb", number = "6548-0256-1216-2209" } + , domain = "judicious-desire.biz" + , emails = + [ "Ernestine.Rosenbaum80@example.com", "Madelynn_Mraz76@gmail.com" ] + , job = + { area = "Branding" + , company = "Torp, Simonis and Reichel" + , descriptor = "District" + , title = "Future Security Engineer" + , type = "Agent" + } + , location = + { city = "Antoinettestead" + , coordinates = { latitude = -66.4104, longitude = 33.9564 } + , country = "Iran" + , state = "Maryland" + , street = "1095 Americo Stream" + , zip = "43361" + } + , name = { first = "Zoe", last = "Romaguera", middle = "Jules" } + , objectId = "66883637cf0a131df415615b" + , password = "SDqLs14PtnO3yXV" + , phoneNumber = "(524) 632-5365 x87044" + , status = "active" + , username = "Zoe-Romaguera" + , uuid = "4bba840a-c832-4d3e-945e-56af162c3939" + , website = "https://low-peer.name/" + } + , { creditCard = + { cvv = "695", issuer = "mastercard", number = "5020-6724-8679-8003" } + , domain = "grumpy-lie.net" + , emails = + [ "Vincent_Dietrich90@example.com", "Sydni_Schuster61@gmail.com" ] + , job = + { area = "Communications" + , company = "Lowe, Rippin and Fay" + , descriptor = "Lead" + , title = "Lead Infrastructure Assistant" + , type = "Supervisor" + } + , location = + { city = "Kshlerinstad" + , coordinates = { latitude = 62.1285, longitude = 10.4132 } + , country = "Romania" + , state = "Texas" + , street = "19947 Tyrel Branch" + , zip = "84523" + } + , name = { first = "Alessia", last = "Willms", middle = "Noah" } + , objectId = "66883637cf0a131df415615c" + , password = "Td7sl82XR1iaSQz" + , phoneNumber = "791.867.5148" + , status = "active" + , username = "Alessia-Willms" + , uuid = "6140ff80-e9e1-4791-8bd6-4de671d92c15" + , website = "https://puny-shearling.info/" + } + ] +} diff --git a/scall-cli/src/test/resources/yaml-main-cases/25.json b/scall-cli/src/test/resources/yaml-main-cases/25.json new file mode 100644 index 00000000..22724167 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/25.json @@ -0,0 +1,88 @@ +{ + "result": [ + { + "creditCard": { + "cvv": "837", + "issuer": "jcb", + "number": "6548-0256-1216-2209" + }, + "domain": "judicious-desire.biz", + "emails": [ + "Ernestine.Rosenbaum80@example.com", + "Madelynn_Mraz76@gmail.com" + ], + "job": { + "area": "Branding", + "company": "Torp, Simonis and Reichel", + "descriptor": "District", + "title": "Future Security Engineer", + "type": "Agent" + }, + "location": { + "city": "Antoinettestead", + "coordinates": { + "latitude": -66.4104, + "longitude": 33.9564 + }, + "country": "Iran", + "state": "Maryland", + "street": "1095 Americo Stream", + "zip": "43361" + }, + "name": { + "first": "Zoe", + "last": "Romaguera", + "middle": "Jules" + }, + "objectId": "66883637cf0a131df415615b", + "password": "SDqLs14PtnO3yXV", + "phoneNumber": "(524) 632-5365 x87044", + "status": "active", + "username": "Zoe-Romaguera", + "uuid": "4bba840a-c832-4d3e-945e-56af162c3939", + "website": "https://low-peer.name/" + }, + { + "creditCard": { + "cvv": "695", + "issuer": "mastercard", + "number": "5020-6724-8679-8003" + }, + "domain": "grumpy-lie.net", + "emails": [ + "Vincent_Dietrich90@example.com", + "Sydni_Schuster61@gmail.com" + ], + "job": { + "area": "Communications", + "company": "Lowe, Rippin and Fay", + "descriptor": "Lead", + "title": "Lead Infrastructure Assistant", + "type": "Supervisor" + }, + "location": { + "city": "Kshlerinstad", + "coordinates": { + "latitude": 62.1285, + "longitude": 10.4132 + }, + "country": "Romania", + "state": "Texas", + "street": "19947 Tyrel Branch", + "zip": "84523" + }, + "name": { + "first": "Alessia", + "last": "Willms", + "middle": "Noah" + }, + "objectId": "66883637cf0a131df415615c", + "password": "Td7sl82XR1iaSQz", + "phoneNumber": "791.867.5148", + "status": "active", + "username": "Alessia-Willms", + "uuid": "6140ff80-e9e1-4791-8bd6-4de671d92c15", + "website": "https://puny-shearling.info/" + } + ] +} diff --git a/scall-cli/src/test/resources/yaml-main-cases/25.yaml b/scall-cli/src/test/resources/yaml-main-cases/25.yaml new file mode 100644 index 00000000..027ac42a --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/25.yaml @@ -0,0 +1,69 @@ +result: + - creditCard: + cvv: '837' + issuer: jcb + number: 6548-0256-1216-2209 + domain: judicious-desire.biz + emails: + - Ernestine.Rosenbaum80@example.com + - Madelynn_Mraz76@gmail.com + job: + area: Branding + company: Torp, Simonis and Reichel + descriptor: District + title: Future Security Engineer + type: Agent + location: + city: Antoinettestead + coordinates: + latitude: -66.4104 + longitude: 33.9564 + country: Iran + state: Maryland + street: 1095 Americo Stream + zip: '43361' + name: + first: Zoe + last: Romaguera + middle: Jules + objectId: 66883637cf0a131df415615b + password: SDqLs14PtnO3yXV + phoneNumber: (524) 632-5365 x87044 + status: active + username: Zoe-Romaguera + uuid: 4bba840a-c832-4d3e-945e-56af162c3939 + website: "https://low-peer.name/" + - creditCard: + cvv: '695' + issuer: mastercard + number: 5020-6724-8679-8003 + domain: grumpy-lie.net + emails: + - Vincent_Dietrich90@example.com + - Sydni_Schuster61@gmail.com + job: + area: Communications + company: Lowe, Rippin and Fay + descriptor: Lead + title: Lead Infrastructure Assistant + type: Supervisor + location: + city: Kshlerinstad + coordinates: + latitude: 62.1285 + longitude: 10.4132 + country: Romania + state: Texas + street: 19947 Tyrel Branch + zip: '84523' + name: + first: Alessia + last: Willms + middle: Noah + objectId: 66883637cf0a131df415615c + password: Td7sl82XR1iaSQz + phoneNumber: 791.867.5148 + status: active + username: Alessia-Willms + uuid: 6140ff80-e9e1-4791-8bd6-4de671d92c15 + website: "https://puny-shearling.info/" diff --git a/scall-cli/src/test/resources/yaml-main-cases/26.dhall b/scall-cli/src/test/resources/yaml-main-cases/26.dhall new file mode 100644 index 00000000..c77a6951 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/26.dhall @@ -0,0 +1,160 @@ +[ { _id = "6688361bcf9046f8f01af25a" + , about = + '' + Dolor officia dolor veniam aliqua veniam velit qui in anim officia incididunt in laborum. Incididunt enim magna id nulla est minim enim proident Lorem minim. Consequat do aute exercitation est laborum deserunt tempor cillum dolor ullamco ullamco reprehenderit. + '' + , address = "807 Joralemon Street, Harviell, Wisconsin, 117" + , age = 39 + , balance = "\$3,886.85" + , company = "MEDIOT" + , email = "sandovalbowen@mediot.com" + , eyeColor = "brown" + , favoriteFruit = "strawberry" + , friends = + [ { id = 0, name = "Fitzpatrick Coleman" } + , { id = 1, name = "Gaines Newton" } + , { id = 2, name = "Trisha Lynch" } + ] + , gender = "male" + , greeting = "Hello, Sandoval Bowen! You have 8 unread messages." + , guid = "f45219c1-298e-4d3d-8c13-24460f9f711a" + , index = 0 + , isActive = True + , latitude = -61.954654 + , longitude = 96.530764 + , name = "Sandoval Bowen" + , phone = "+1 (905) 450-2186" + , picture = "http://placehold.it/32x32" + , registered = "2017-06-04T04:42:19 -02:00" + , tags = + [ "deserunt", "duis", "incididunt", "Lorem", "aliqua", "minim", "laboris" ] + } +, { _id = "6688361bcc7a77bb3c0d6607" + , about = + '' + Laborum laboris eu enim enim. Magna pariatur ea nostrud commodo eu sit cupidatat magna laborum nostrud qui. Ea qui dolore enim eiusmod laboris consequat qui ut proident. Eiusmod ad dolore proident minim magna ex irure incididunt labore non est elit. Culpa incididunt elit id veniam exercitation. + '' + , address = "783 Dooley Street, Englevale, Montana, 5479" + , age = 36 + , balance = "\$2,707.82" + , company = "ENERFORCE" + , email = "hansenwynn@enerforce.com" + , eyeColor = "green" + , favoriteFruit = "banana" + , friends = + [ { id = 0, name = "Vega Everett" } + , { id = 1, name = "Deana Hood" } + , { id = 2, name = "Barton Eaton" } + ] + , gender = "male" + , greeting = "Hello, Hansen Wynn! You have 6 unread messages." + , guid = "78f46526-f4d0-49e9-9e26-964eefc61335" + , index = 1 + , isActive = False + , latitude = 78.498411 + , longitude = -51.089063 + , name = "Hansen Wynn" + , phone = "+1 (910) 424-3850" + , picture = "http://placehold.it/32x32" + , registered = "2015-01-28T07:19:02 -01:00" + , tags = [ "dolor", "elit", "fugiat", "in", "commodo", "quis", "commodo" ] + } +, { _id = "6688361b8a40be2e059cc06d" + , about = + '' + Non incididunt laboris cillum quis in anim occaecat voluptate ad aliqua consectetur velit dolore. Id ad est et magna irure eu. Consequat exercitation aute ad anim esse velit est tempor esse occaecat commodo. Eu ut nostrud nisi occaecat tempor deserunt dolor. Fugiat irure et duis nisi reprehenderit ipsum exercitation nostrud excepteur incididunt eu ullamco consectetur. Occaecat veniam elit esse officia dolor ea laboris elit reprehenderit anim irure officia dolore ut. Velit consequat nulla adipisicing fugiat ullamco nulla. + '' + , address = "966 Stockton Street, Lydia, Florida, 9300" + , age = 23 + , balance = "\$3,569.95" + , company = "OZEAN" + , email = "kimburris@ozean.com" + , eyeColor = "blue" + , favoriteFruit = "apple" + , friends = + [ { id = 0, name = "Shannon Good" } + , { id = 1, name = "Jody Coffey" } + , { id = 2, name = "Lola Travis" } + ] + , gender = "female" + , greeting = "Hello, Kim Burris! You have 7 unread messages." + , guid = "50cd3c0a-1153-4e3f-acb1-10fb05784782" + , index = 2 + , isActive = False + , latitude = 14.065609 + , longitude = 52.761211 + , name = "Kim Burris" + , phone = "+1 (812) 457-3590" + , picture = "http://placehold.it/32x32" + , registered = "2017-07-07T09:22:20 -02:00" + , tags = [ "consectetur", "sint", "et", "id", "amet", "fugiat", "do" ] + } +, { _id = "6688361b9b9b80d63259e594" + , about = + '' + Cillum excepteur consequat deserunt adipisicing magna elit exercitation non adipisicing voluptate in magna. Ipsum laborum nulla deserunt ex est do id occaecat Lorem excepteur ipsum nisi cupidatat. Nostrud id consectetur irure ipsum in veniam. Est esse excepteur ad ex ut eu labore labore esse irure culpa. In adipisicing eu ipsum nisi eu in ullamco reprehenderit. + '' + , address = "651 Belmont Avenue, Vienna, Virginia, 8620" + , age = 29 + , balance = "\$2,660.92" + , company = "QUONATA" + , email = "elisabethbryan@quonata.com" + , eyeColor = "green" + , favoriteFruit = "apple" + , friends = + [ { id = 0, name = "Cardenas Kelly" } + , { id = 1, name = "Wilder Rodriquez" } + , { id = 2, name = "Dotson Small" } + ] + , gender = "female" + , greeting = "Hello, Elisabeth Bryan! You have 1 unread messages." + , guid = "2479a002-6fe7-475b-bae0-98ed680c403e" + , index = 3 + , isActive = True + , latitude = -64.463259 + , longitude = 60.112556 + , name = "Elisabeth Bryan" + , phone = "+1 (911) 547-2115" + , picture = "http://placehold.it/32x32" + , registered = "2023-02-04T12:31:14 -01:00" + , tags = [ "eu", "proident", "fugiat", "ut", "commodo", "quis", "ex" ] + } +, { _id = "6688361b54a976d28acc87fb" + , about = + '' + Nostrud Lorem tempor laborum cupidatat voluptate proident. Dolor ad culpa commodo aute nostrud enim ea dolor mollit sunt quis esse do. Anim officia laborum labore enim adipisicing id nostrud velit laborum eiusmod nulla ad. + '' + , address = "607 Fenimore Street, Ernstville, Kansas, 3691" + , age = 20 + , balance = "\$1,815.97" + , company = "CEMENTION" + , email = "lolitadickson@cemention.com" + , eyeColor = "blue" + , favoriteFruit = "apple" + , friends = + [ { id = 0, name = "Gladys Herman" } + , { id = 1, name = "Slater Rasmussen" } + , { id = 2, name = "Tate Mccormick" } + ] + , gender = "female" + , greeting = "Hello, Lolita Dickson! You have 1 unread messages." + , guid = "8a0bcdd5-7863-4568-a0f7-10883866d81f" + , index = 4 + , isActive = False + , latitude = 33.101567 + , longitude = 4.260351 + , name = "Lolita Dickson" + , phone = "+1 (954) 423-3743" + , picture = "http://placehold.it/32x32" + , registered = "2021-01-24T10:45:58 -01:00" + , tags = + [ "adipisicing" + , "commodo" + , "enim" + , "proident" + , "fugiat" + , "ad" + , "incididunt" + ] + } +] diff --git a/scall-cli/src/test/resources/yaml-main-cases/26.json b/scall-cli/src/test/resources/yaml-main-cases/26.json new file mode 100644 index 00000000..7c12b1c8 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/26.json @@ -0,0 +1,227 @@ +[ + { + "_id": "6688361bcf9046f8f01af25a", + "about": "Dolor officia dolor veniam aliqua veniam velit qui in anim officia incididunt in laborum. Incididunt enim magna id nulla est minim enim proident Lorem minim. Consequat do aute exercitation est laborum deserunt tempor cillum dolor ullamco ullamco reprehenderit.\n", + "address": "807 Joralemon Street, Harviell, Wisconsin, 117", + "age": 39, + "balance": "$3,886.85", + "company": "MEDIOT", + "email": "sandovalbowen@mediot.com", + "eyeColor": "brown", + "favoriteFruit": "strawberry", + "friends": [ + { + "id": 0, + "name": "Fitzpatrick Coleman" + }, + { + "id": 1, + "name": "Gaines Newton" + }, + { + "id": 2, + "name": "Trisha Lynch" + } + ], + "gender": "male", + "greeting": "Hello, Sandoval Bowen! You have 8 unread messages.", + "guid": "f45219c1-298e-4d3d-8c13-24460f9f711a", + "index": 0, + "isActive": true, + "latitude": -61.954654, + "longitude": 96.530764, + "name": "Sandoval Bowen", + "phone": "+1 (905) 450-2186", + "picture": "http://placehold.it/32x32", + "registered": "2017-06-04T04:42:19 -02:00", + "tags": [ + "deserunt", + "duis", + "incididunt", + "Lorem", + "aliqua", + "minim", + "laboris" + ] + }, + { + "_id": "6688361bcc7a77bb3c0d6607", + "about": "Laborum laboris eu enim enim. Magna pariatur ea nostrud commodo eu sit cupidatat magna laborum nostrud qui. Ea qui dolore enim eiusmod laboris consequat qui ut proident. Eiusmod ad dolore proident minim magna ex irure incididunt labore non est elit. Culpa incididunt elit id veniam exercitation.\n", + "address": "783 Dooley Street, Englevale, Montana, 5479", + "age": 36, + "balance": "$2,707.82", + "company": "ENERFORCE", + "email": "hansenwynn@enerforce.com", + "eyeColor": "green", + "favoriteFruit": "banana", + "friends": [ + { + "id": 0, + "name": "Vega Everett" + }, + { + "id": 1, + "name": "Deana Hood" + }, + { + "id": 2, + "name": "Barton Eaton" + } + ], + "gender": "male", + "greeting": "Hello, Hansen Wynn! You have 6 unread messages.", + "guid": "78f46526-f4d0-49e9-9e26-964eefc61335", + "index": 1, + "isActive": false, + "latitude": 78.498411, + "longitude": -51.089063, + "name": "Hansen Wynn", + "phone": "+1 (910) 424-3850", + "picture": "http://placehold.it/32x32", + "registered": "2015-01-28T07:19:02 -01:00", + "tags": [ + "dolor", + "elit", + "fugiat", + "in", + "commodo", + "quis", + "commodo" + ] + }, + { + "_id": "6688361b8a40be2e059cc06d", + "about": "Non incididunt laboris cillum quis in anim occaecat voluptate ad aliqua consectetur velit dolore. Id ad est et magna irure eu. Consequat exercitation aute ad anim esse velit est tempor esse occaecat commodo. Eu ut nostrud nisi occaecat tempor deserunt dolor. Fugiat irure et duis nisi reprehenderit ipsum exercitation nostrud excepteur incididunt eu ullamco consectetur. Occaecat veniam elit esse officia dolor ea laboris elit reprehenderit anim irure officia dolore ut. Velit consequat nulla adipisicing fugiat ullamco nulla.\n", + "address": "966 Stockton Street, Lydia, Florida, 9300", + "age": 23, + "balance": "$3,569.95", + "company": "OZEAN", + "email": "kimburris@ozean.com", + "eyeColor": "blue", + "favoriteFruit": "apple", + "friends": [ + { + "id": 0, + "name": "Shannon Good" + }, + { + "id": 1, + "name": "Jody Coffey" + }, + { + "id": 2, + "name": "Lola Travis" + } + ], + "gender": "female", + "greeting": "Hello, Kim Burris! You have 7 unread messages.", + "guid": "50cd3c0a-1153-4e3f-acb1-10fb05784782", + "index": 2, + "isActive": false, + "latitude": 14.065609, + "longitude": 52.761211, + "name": "Kim Burris", + "phone": "+1 (812) 457-3590", + "picture": "http://placehold.it/32x32", + "registered": "2017-07-07T09:22:20 -02:00", + "tags": [ + "consectetur", + "sint", + "et", + "id", + "amet", + "fugiat", + "do" + ] + }, + { + "_id": "6688361b9b9b80d63259e594", + "about": "Cillum excepteur consequat deserunt adipisicing magna elit exercitation non adipisicing voluptate in magna. Ipsum laborum nulla deserunt ex est do id occaecat Lorem excepteur ipsum nisi cupidatat. Nostrud id consectetur irure ipsum in veniam. Est esse excepteur ad ex ut eu labore labore esse irure culpa. In adipisicing eu ipsum nisi eu in ullamco reprehenderit.\n", + "address": "651 Belmont Avenue, Vienna, Virginia, 8620", + "age": 29, + "balance": "$2,660.92", + "company": "QUONATA", + "email": "elisabethbryan@quonata.com", + "eyeColor": "green", + "favoriteFruit": "apple", + "friends": [ + { + "id": 0, + "name": "Cardenas Kelly" + }, + { + "id": 1, + "name": "Wilder Rodriquez" + }, + { + "id": 2, + "name": "Dotson Small" + } + ], + "gender": "female", + "greeting": "Hello, Elisabeth Bryan! You have 1 unread messages.", + "guid": "2479a002-6fe7-475b-bae0-98ed680c403e", + "index": 3, + "isActive": true, + "latitude": -64.463259, + "longitude": 60.112556, + "name": "Elisabeth Bryan", + "phone": "+1 (911) 547-2115", + "picture": "http://placehold.it/32x32", + "registered": "2023-02-04T12:31:14 -01:00", + "tags": [ + "eu", + "proident", + "fugiat", + "ut", + "commodo", + "quis", + "ex" + ] + }, + { + "_id": "6688361b54a976d28acc87fb", + "about": "Nostrud Lorem tempor laborum cupidatat voluptate proident. Dolor ad culpa commodo aute nostrud enim ea dolor mollit sunt quis esse do. Anim officia laborum labore enim adipisicing id nostrud velit laborum eiusmod nulla ad.\n", + "address": "607 Fenimore Street, Ernstville, Kansas, 3691", + "age": 20, + "balance": "$1,815.97", + "company": "CEMENTION", + "email": "lolitadickson@cemention.com", + "eyeColor": "blue", + "favoriteFruit": "apple", + "friends": [ + { + "id": 0, + "name": "Gladys Herman" + }, + { + "id": 1, + "name": "Slater Rasmussen" + }, + { + "id": 2, + "name": "Tate Mccormick" + } + ], + "gender": "female", + "greeting": "Hello, Lolita Dickson! You have 1 unread messages.", + "guid": "8a0bcdd5-7863-4568-a0f7-10883866d81f", + "index": 4, + "isActive": false, + "latitude": 33.101567, + "longitude": 4.260351, + "name": "Lolita Dickson", + "phone": "+1 (954) 423-3743", + "picture": "http://placehold.it/32x32", + "registered": "2021-01-24T10:45:58 -01:00", + "tags": [ + "adipisicing", + "commodo", + "enim", + "proident", + "fugiat", + "ad", + "incididunt" + ] + } +] diff --git a/scall-cli/src/test/resources/yaml-main-cases/26.yaml b/scall-cli/src/test/resources/yaml-main-cases/26.yaml new file mode 100644 index 00000000..077561a6 --- /dev/null +++ b/scall-cli/src/test/resources/yaml-main-cases/26.yaml @@ -0,0 +1,180 @@ +- _id: 6688361bcf9046f8f01af25a + about: | + Dolor officia dolor veniam aliqua veniam velit qui in anim officia incididunt in laborum. Incididunt enim magna id nulla est minim enim proident Lorem minim. Consequat do aute exercitation est laborum deserunt tempor cillum dolor ullamco ullamco reprehenderit. + address: 807 Joralemon Street, Harviell, Wisconsin, 117 + age: 39 + balance: "$3,886.85" + company: MEDIOT + email: sandovalbowen@mediot.com + eyeColor: brown + favoriteFruit: strawberry + friends: + - id: 0 + name: Fitzpatrick Coleman + - id: 1 + name: Gaines Newton + - id: 2 + name: Trisha Lynch + gender: male + greeting: "Hello, Sandoval Bowen! You have 8 unread messages." + guid: f45219c1-298e-4d3d-8c13-24460f9f711a + index: 0 + isActive: true + latitude: -61.954654 + longitude: 96.530764 + name: Sandoval Bowen + phone: +1 (905) 450-2186 + picture: "http://placehold.it/32x32" + registered: "2017-06-04T04:42:19 -02:00" + tags: + - deserunt + - duis + - incididunt + - Lorem + - aliqua + - minim + - laboris +- _id: 6688361bcc7a77bb3c0d6607 + about: | + Laborum laboris eu enim enim. Magna pariatur ea nostrud commodo eu sit cupidatat magna laborum nostrud qui. Ea qui dolore enim eiusmod laboris consequat qui ut proident. Eiusmod ad dolore proident minim magna ex irure incididunt labore non est elit. Culpa incididunt elit id veniam exercitation. + address: 783 Dooley Street, Englevale, Montana, 5479 + age: 36 + balance: "$2,707.82" + company: ENERFORCE + email: hansenwynn@enerforce.com + eyeColor: green + favoriteFruit: banana + friends: + - id: 0 + name: Vega Everett + - id: 1 + name: Deana Hood + - id: 2 + name: Barton Eaton + gender: male + greeting: "Hello, Hansen Wynn! You have 6 unread messages." + guid: 78f46526-f4d0-49e9-9e26-964eefc61335 + index: 1 + isActive: false + latitude: 78.498411 + longitude: -51.089063 + name: Hansen Wynn + phone: +1 (910) 424-3850 + picture: "http://placehold.it/32x32" + registered: "2015-01-28T07:19:02 -01:00" + tags: + - dolor + - elit + - fugiat + - in + - commodo + - quis + - commodo +- _id: 6688361b8a40be2e059cc06d + about: | + Non incididunt laboris cillum quis in anim occaecat voluptate ad aliqua consectetur velit dolore. Id ad est et magna irure eu. Consequat exercitation aute ad anim esse velit est tempor esse occaecat commodo. Eu ut nostrud nisi occaecat tempor deserunt dolor. Fugiat irure et duis nisi reprehenderit ipsum exercitation nostrud excepteur incididunt eu ullamco consectetur. Occaecat veniam elit esse officia dolor ea laboris elit reprehenderit anim irure officia dolore ut. Velit consequat nulla adipisicing fugiat ullamco nulla. + address: 966 Stockton Street, Lydia, Florida, 9300 + age: 23 + balance: "$3,569.95" + company: OZEAN + email: kimburris@ozean.com + eyeColor: blue + favoriteFruit: apple + friends: + - id: 0 + name: Shannon Good + - id: 1 + name: Jody Coffey + - id: 2 + name: Lola Travis + gender: female + greeting: "Hello, Kim Burris! You have 7 unread messages." + guid: 50cd3c0a-1153-4e3f-acb1-10fb05784782 + index: 2 + isActive: false + latitude: 14.065609 + longitude: 52.761211 + name: Kim Burris + phone: +1 (812) 457-3590 + picture: "http://placehold.it/32x32" + registered: "2017-07-07T09:22:20 -02:00" + tags: + - consectetur + - sint + - et + - id + - amet + - fugiat + - do +- _id: 6688361b9b9b80d63259e594 + about: | + Cillum excepteur consequat deserunt adipisicing magna elit exercitation non adipisicing voluptate in magna. Ipsum laborum nulla deserunt ex est do id occaecat Lorem excepteur ipsum nisi cupidatat. Nostrud id consectetur irure ipsum in veniam. Est esse excepteur ad ex ut eu labore labore esse irure culpa. In adipisicing eu ipsum nisi eu in ullamco reprehenderit. + address: 651 Belmont Avenue, Vienna, Virginia, 8620 + age: 29 + balance: "$2,660.92" + company: QUONATA + email: elisabethbryan@quonata.com + eyeColor: green + favoriteFruit: apple + friends: + - id: 0 + name: Cardenas Kelly + - id: 1 + name: Wilder Rodriquez + - id: 2 + name: Dotson Small + gender: female + greeting: "Hello, Elisabeth Bryan! You have 1 unread messages." + guid: 2479a002-6fe7-475b-bae0-98ed680c403e + index: 3 + isActive: true + latitude: -64.463259 + longitude: 60.112556 + name: Elisabeth Bryan + phone: +1 (911) 547-2115 + picture: "http://placehold.it/32x32" + registered: "2023-02-04T12:31:14 -01:00" + tags: + - eu + - proident + - fugiat + - ut + - commodo + - quis + - ex +- _id: 6688361b54a976d28acc87fb + about: | + Nostrud Lorem tempor laborum cupidatat voluptate proident. Dolor ad culpa commodo aute nostrud enim ea dolor mollit sunt quis esse do. Anim officia laborum labore enim adipisicing id nostrud velit laborum eiusmod nulla ad. + address: 607 Fenimore Street, Ernstville, Kansas, 3691 + age: 20 + balance: "$1,815.97" + company: CEMENTION + email: lolitadickson@cemention.com + eyeColor: blue + favoriteFruit: apple + friends: + - id: 0 + name: Gladys Herman + - id: 1 + name: Slater Rasmussen + - id: 2 + name: Tate Mccormick + gender: female + greeting: "Hello, Lolita Dickson! You have 1 unread messages." + guid: 8a0bcdd5-7863-4568-a0f7-10883866d81f + index: 4 + isActive: false + latitude: 33.101567 + longitude: 4.260351 + name: Lolita Dickson + phone: +1 (954) 423-3743 + picture: "http://placehold.it/32x32" + registered: "2021-01-24T10:45:58 -01:00" + tags: + - adipisicing + - commodo + - enim + - proident + - fugiat + - ad + - incididunt diff --git a/scall-cli/src/test/scala/io/chymyst/dhall/unit/MainSpec.scala b/scall-cli/src/test/scala/io/chymyst/dhall/unit/MainSpec.scala index b1cfaa14..e9d9d3cf 100644 --- a/scall-cli/src/test/scala/io/chymyst/dhall/unit/MainSpec.scala +++ b/scall-cli/src/test/scala/io/chymyst/dhall/unit/MainSpec.scala @@ -87,98 +87,57 @@ class MainSpec extends FunSuite with TestTimings with ResourceFiles with ManyFix } test("fail to export yaml if Dhall expression contains unsupported types") { - expect(runMain("{ a = 12:00:00, b = 2 }", "yaml") == "Error: Unsupported expression type for Yaml export: 12:00:00 of type Time\n") + expect(runMain("{ a = Natural, b = 2 }", "yaml") == "Error: Unsupported expression type for Yaml export: Natural of type Type\n") expect( runMain("{ a = 1, b = \\(x : Bool) -> x }", "yaml") == "Error: Unsupported expression type for Yaml export: λ(x : Bool) → x of type ∀(x : Bool) → Bool\n" ) expect(runMain("{ a = Type }", "yaml") == "Error: Unsupported expression type for Yaml export: Type of type Kind\n") } - test("yaml output for lists of numbers") { - expect( - runMain("[1, 2, 3]", "yaml") == - """- 1 - |- 2 - |- 3 - |""".stripMargin - ) - } - - test("yaml output for records of numbers") { - expect( - runMain("{ a = 1, b = 2, c = 3 }", "yaml") == - """a: 1 - |b: 2 - |c: 3 - |""".stripMargin - ) - } - - test("yaml output for lists of lists of numbers") { - expect( - runMain("[[1, 2, 3], [4, 5]]", "yaml") == - """- - 1 - | - 2 - | - 3 - |- - 4 - | - 5 - |""".stripMargin - ) - } - - test("yaml output for record of lists") { - expect(runMain("{a = [1, 2, 3], b= [4, 5]}", "yaml") == """a: - | - 1 - | - 2 - | - 3 - |b: - | - 4 - | - 5 - |""".stripMargin) - } - - test("yaml output for list of records, including None") { - val result = runMain("[Some {a = 1, b = 2}, None { a : Natural, b : Natural }, Some {a = 3, b = 4}]", "yaml") - expect(result == """- a: 1 - | b: 2 - |- a: 3 - | b: 4 - |""".stripMargin) - } + test("json main test cases") { + val results = enumerateResourceFiles("yaml-main-cases", Some(".dhall")).map { file => + val createDocuments = file.getName matches ".*-document.*" + val options = YamlOptions(createDocuments = createDocuments) + val testOut = new ByteArrayOutputStream + try { + Main.process(file.toPath, new FileInputStream(file), testOut, OutputMode.Json, options.copy(jsonFormat = true)) + } finally { + testOut.close() + } + val resultJson = new String(testOut.toByteArray) + val expectedJson = new String(Files.readAllBytes(Paths.get(file.getAbsolutePath.replace(".dhall", ".json")))) + if (resultJson != expectedJson) println(s"DEBUG failure in $file, resultJson=$resultJson") + Try(expect(resultJson == expectedJson)) + } - test("yaml output for record of records") { - expect(runMain("{x = {a = 1, b = 2}, y = {c = 3, d = 4}}", "yaml") == """x: - | a: 1 - | b: 2 - |'y': - | c: 3 - | d: 4 - |""".stripMargin) + requireSuccessAtLeast(totalTests = 26, results, allowFailures = 0) } - test("yaml for optional values") { - expect(runMain("{x = Some {a = 1, b = Some 2, c = None Natural}, z = None Bool, y = {c = Some 3, d = 4}}", "yaml") == """x: - | a: 1 - | b: 2 - |'y': - | c: 3 - | d: 4 - |""".stripMargin) - } + test("yaml main test cases") { + val results = enumerateResourceFiles("yaml-main-cases", Some(".dhall")).map { file => + val needToQuote = file.getName == "quoted.dhall" + val createDocuments = file.getName matches ".*-document.*" + val options = YamlOptions(quoteAllStrings = needToQuote, createDocuments = createDocuments) + val testOut = new ByteArrayOutputStream + try { + Main.process(file.toPath, new FileInputStream(file), testOut, OutputMode.Yaml, options) + } finally { + testOut.close() + } + val resultYaml = new String(testOut.toByteArray) + val expectedYaml = new String(Files.readAllBytes(Paths.get(file.getAbsolutePath.replace(".dhall", ".yaml")))) + if (resultYaml != expectedYaml) println(s"DEBUG failure in $file, resultYaml=$resultYaml") + Try(expect(resultYaml == expectedYaml)) + } - test("yaml for map-typed values") { - expect(runMain("[{mapKey=\"a\",mapValue=123},{mapKey=\"b\",mapValue=456}]", "yaml") == """a: 123 - |b: 456 - |""".stripMargin) + requireSuccessAtLeast(totalTests = 26, results, allowFailures = 0) } test("yaml corner cases from dhall-haskell/yaml") { - val parentPath = resourceAsFile("yaml-corner-cases").get.toPath.getParent - val results = enumerateResourceFiles("yaml-corner-cases", Some(".dhall")).map { file => + val results = enumerateResourceFiles("yaml-corner-cases", Some(".dhall")).map { file => val needToQuote = file.getName == "quoted.dhall" val createDocuments = file.getName matches ".*-document.*" val options = YamlOptions(quoteAllStrings = needToQuote, createDocuments = createDocuments) - // val relativePathForTest = parentPath.relativize(file.toPath) val testOut = new ByteArrayOutputStream try { Main.process(file.toPath, new FileInputStream(file), testOut, OutputMode.Yaml, options) diff --git a/scall-core/src/main/scala/io/chymyst/dhall/Yaml.scala b/scall-core/src/main/scala/io/chymyst/dhall/Yaml.scala index 1ef00799..4ef50ecb 100644 --- a/scall-core/src/main/scala/io/chymyst/dhall/Yaml.scala +++ b/scall-core/src/main/scala/io/chymyst/dhall/Yaml.scala @@ -5,57 +5,196 @@ import io.chymyst.dhall.Syntax.ExpressionScheme.{ExprBuiltin, RecordLiteral, Tex import io.chymyst.dhall.Syntax.{DhallFile, Expression, ExpressionScheme} import io.chymyst.dhall.SyntaxConstants.{Builtin, FieldName} +/** Conversion of Dhall values to Yaml is supported for numbers, strings, date/time values, lists, records, and union types, arbitrarily nested. Other types or + * kinds are not supported and will give an error when converting to Yaml. + * + * As a rule, only normal forms may be converted to Yaml. For example, converting `{ a.b = 1 }` involves desugaring to `{ a = { b = 1 } }`; the desugaring must + * be performed before converting to Yaml. + * + * Conversion of Dhall values to Yaml is performed according to the following rules: + * + * - Each supported Dhall value is converted into a (possibly empty) list of Yaml lines. + * + * - Natural literals (including Bytes literals) are translated into Yaml integers. + * - Double literals are translated into Yaml floats. + * - Text literals are translated into Yaml unquoted strings, quoted strings, or multiline strings. + * - If a text literal contains one of the special characters, it is quoted in double quotes. + * - If a text literal contains newlines, it is represented as a multiline string. + * - If a text literal is a reserved Yaml word, or matches the format of a number or a date, it is quoted in single quotes. + * - Otherwise the text literal is unquoted (unless the "quote all" option is given; in that case, it is quoted in double quotes). + * - Date, Time, TimeZone are translated into Yaml quoted strings, except when they are part of a timestamp record as follows: + * - A timestamp record of type { date : Date, time : Time } is translated into a quoted string such as "1960-12-25T04:23:34". + * - A timestamp record of type { date : Date, time : Time, timeZone: TimeZone } is translated into a quoted string such as "1960-12-25T04:23:34+00:00". + * - A value of Optional type that is a `None T` is omitted (translated into empty list of Yaml lines) unless it is at top-level, in which case it is + * translated into `null`. If an option is given to preserve null values, `None T` is always translated into `null` (also when not at top level). + * - A value of a union type is either a constructor without arguments, or a constructor with a single argument. + * - A constructor without argument is converted to a Yaml string corresponding to the constructor's name. + * - A constructor with argument is converted to Yaml lines corresponding to the argument (the constructor's name is then ignored). + * + * - Lists of values are translated into Yaml arrays as follows: + * - Empty lists are translated into the Yaml line `[]` except if the empty list has a map type. + * - Empty lists of map type `{ mapKey : Text, mapValue : ... }` are translated into the Yaml line `{}`. + * - For non-empty lists, each list element is translated into zero or more Yaml lines. + * - If a list element is translated into an empty Yaml, that list element is set to null. + * - If a list element is a single Yaml line, it is formatted after the dash: + * + * {{{ + * - 123 + * - 456 + * }}} + * + * - If a list element is a multiline Yaml, the first line is formatted after the dash, and all next lines are indented: + * + * {{{ + * - - 1 + * - 2 + * - a: 1 + * b: 2 + * }}} + * + * - Records are translated into Yaml records as follows: + * - Empty records are translated into the Yaml line `{}`. + * - For each field of a non-empty record, the corresponding value is translated into zero or more Yaml lines. + * - If a field's value is an empty Yaml, that field is omitted. + * - If a field's value is a single Yaml line, that line is formatted after the field's name: + * + * {{{ + * a: xyz + * }}} + * - If the field's name is a reserved word, or if the "quote all" option is given, the field's name is put in single quotes. + * + * Reserved words are "true", "false", "null", "~", "e", "yes", "no", "y", "n", "on", "off". + * + * - If a field's value is a multi-line string (which is a Yaml primitive type), the beginning separator is formatted after the field's name: + * + * {{{ + * a: | + * multi-line + * string + * }}} + * + * - If a field's value is multi-line Yaml, and if the field's value is a record or a list (i.e., not a primitive type), it is formatted started from the + * next line and all lines are indented. For example: + * + * {{{ + * a: + * - 1 + * - 2 + * b: + * c: 1 + * d: 2 + * }}} + */ object Yaml { def yamlIndent(indent: Int) = " " * indent - final case class YamlOptions(quoteAllStrings: Boolean = false, indent: Int = 2, createDocuments: Boolean = false) + final case class YamlOptions(quoteAllStrings: Boolean = false, indent: Int = 2, createDocuments: Boolean = false, jsonFormat: Boolean = false) sealed trait LineType case object YRecord extends LineType case object YArray extends LineType case object YPrimitive extends LineType + case object YNull extends LineType final case class YamlLines(ltype: LineType, lines: Seq[String]) + sealed trait RecordIsDate + case object RecordIsDateTime extends RecordIsDate + case object RecordIsDateTimeWithZone extends RecordIsDate + // This function should ignore options.createDocuments because it is used recursively for sub-document Yaml values. - private def toYamlLines(expr: Expression, options: YamlOptions): Either[String, YamlLines] = + private def toYamlLines(expr: Expression, options: YamlOptions): Either[String, YamlLines] = { + val format = if (options.jsonFormat) "JSON" else "Yaml" expr.inferType match { case TypecheckResult.Invalid(errors) => Left(errors.toString) case TypecheckResult.Valid(tpe) => // Check if it has type List { mapKey : Text, mapValue : _ }. - lazy val isRecordMap = tpe.scheme match { + lazy val isRecordMap = tpe.scheme match { case ExpressionScheme.Application(Expression(ExprBuiltin(Builtin.List)), Expression(ExpressionScheme.RecordType(defs))) => val fieldMap: Map[FieldName, Expression] = defs.toMap fieldMap.keySet == Set(FieldName("mapKey"), FieldName("mapValue")) && fieldMap(FieldName("mapKey")) == Expression(ExprBuiltin(Builtin.Text)) case _ => false } + // Check if it has type { date : Date, time : Time } or { date : Date, time : Time, timeZone : TimeZone }. + lazy val timestampRecord: Option[RecordIsDate] = tpe.scheme match { + case ExpressionScheme.RecordType(defs) => + val fieldMap: Map[FieldName, Expression] = defs.toMap + val isDateTime = + fieldMap.keySet == Set(FieldName("date"), FieldName("time")) && fieldMap(FieldName("date")) == Expression(ExprBuiltin(Builtin.Date)) && fieldMap( + FieldName("time") + ) == Expression(ExprBuiltin(Builtin.Time)) + val isDateTimeWithZone = fieldMap.keySet == Set(FieldName("date"), FieldName("time"), FieldName("timeZone")) && fieldMap( + FieldName("date") + ) == Expression(ExprBuiltin(Builtin.Date)) && fieldMap(FieldName("time")) == Expression(ExprBuiltin(Builtin.Time)) && fieldMap( + FieldName("timeZone") + ) == Expression(ExprBuiltin(Builtin.TimeZone)) + if (isDateTime) Some(RecordIsDateTime) else if (isDateTimeWithZone) Some(RecordIsDateTimeWithZone) else None + + case _ => None + } expr.scheme match { + // Empty record literal. case ExpressionScheme.RecordLiteral(Seq()) => Right(YamlLines(YPrimitive, Seq("{}"))) + // Non-empty record literal. case ExpressionScheme.RecordLiteral(defs) => - val content: Seq[Either[String, (String, YamlLines)]] = defs.map { case (FieldName(name), e: Expression) => - toYamlLines(e, options).map(lines => (name, lines)) - } - val errors = content.collect { case Left(e) => e } - if (errors.nonEmpty) Left(errors.mkString("; ")) - else { - val valids = content.map { case Right(x) => x } - val output: Seq[YamlLines] = valids.map { - case (_, YamlLines(t, Seq())) => YamlLines(t, Seq[String]()) - case (name, YamlLines(YPrimitive, Seq(firstLine))) => YamlLines(YRecord, Seq(escapeYamlName(name, options) + ": " + firstLine)) - // If the value of the record field is a multiline YAML, we will skip a line unless the first line is empty. - case (name, YamlLines(_, lines)) => - if (lines.head.isEmpty) - YamlLines(YRecord, (escapeYamlName(name, options) + ": " + lines.tail.head) +: lines.tail.tail.map(l => yamlIndent(options.indent) + l)) - else - YamlLines(YRecord, (escapeYamlName(name, options) + ":") +: lines.map(l => yamlIndent(options.indent) + l)) - } - Right(YamlLines(YRecord, output.flatMap(_.lines))) + lazy val fieldMap = defs.toMap + timestampRecord match { + case Some(RecordIsDateTime) => + Right(YamlLines(YPrimitive, Seq("\"" + fieldMap(FieldName("date")).print + "T" + fieldMap(FieldName("time")).print + "\""))) + case Some(RecordIsDateTimeWithZone) => + Right( + YamlLines( + YPrimitive, + Seq("\"" + fieldMap(FieldName("date")).print + "T" + fieldMap(FieldName("time")).print + fieldMap(FieldName("timeZone")).print + "\""), + ) + ) + + case None => // Not a timestamp record. + val content: Seq[Either[String, (String, YamlLines)]] = defs.map { case (FieldName(name), e: Expression) => + toYamlLines(e, options).map(lines => (name, lines)) + } + + val errors = content.collect { case Left(e) => e } + if (errors.nonEmpty) Left(errors.mkString("; ")) + else { + val valids = content.map { case Right(x) => x } + val output: Seq[YamlLines] = valids.map { + case (_, YamlLines(t, Seq())) => YamlLines(t, Seq[String]()) // null values are omitted. + + case (name, YamlLines(YPrimitive, lines)) => + YamlLines( + YRecord, + Seq(escapeSpecialName(name, options) + ":" + yamlIndent(math.max(1, options.indent - 1)) + lines.head) ++ lines.tail.map(l => + yamlIndent(options.indent) + l + ), + ) + + case (name, YamlLines(_, lines)) if options.jsonFormat => + YamlLines(YRecord, (escapeSpecialName(name, options) + ":" + yamlIndent(math.max(1, options.indent - 1)) + lines.head) +: lines.tail) + + case (name, YamlLines(_, lines)) => + YamlLines(YRecord, (escapeSpecialName(name, options) + ":") +: lines.map(l => yamlIndent(options.indent) + l)) + } + if (options.jsonFormat) { + if (output.isEmpty) Right(YamlLines(YRecord, Seq("{}"))) + else { + val outputWithoutOmittedLines = output.filter( + _.lines.nonEmpty + ) // We should remove those lines right away, or else there will be commas inserted before removed lines, which will make an invalid final comma appear in JSON. + val (jsonBeginRecord, jsonEndRecord) = (Seq("{"), Seq("}")) + val init = outputWithoutOmittedLines.init.flatMap(y => if (y.lines.isEmpty) y.lines else y.lines.init :+ (y.lines.last + ",")) + val last = outputWithoutOmittedLines.last.lines + Right(YamlLines(YRecord, jsonBeginRecord ++ (init ++ last).map(l => yamlIndent(options.indent) + l) ++ jsonEndRecord)) + } + } else Right(YamlLines(YRecord, output.flatMap(_.lines))) + } } - case ExpressionScheme.EmptyList(_) => + + case ExpressionScheme.EmptyList(_) => val emptyListOrRecord = if (isRecordMap) "{}" else "[]" Right(YamlLines(YPrimitive, Seq(emptyListOrRecord))) @@ -75,68 +214,97 @@ object Yaml { val errors = content.collect { case Left(e) => e } if (errors.nonEmpty) Left(errors.mkString("; ")) else { + val delimiter = if (options.jsonFormat) "" else "-" + yamlIndent(math.max(1, options.indent - 1)) val valids = content.map { case Right(x) => x } val output: Seq[YamlLines] = valids.map { - case YamlLines(t, Seq()) => YamlLines(t, Seq()) - case YamlLines(_, Seq(firstLine)) => YamlLines(YArray, Seq("- " + firstLine)) - // If the value of the list item is a multiline YAML, we will skip the first line if it is empty. - case YamlLines(_, lines) => - val content = if (lines.head.isEmpty) lines.tail else lines - YamlLines(YArray, ("- " + content.head) +: content.tail.map(l => yamlIndent(options.indent) + l)) + case YamlLines(YNull, Seq()) => YamlLines(YNull, Seq(delimiter + "null")) // null empty values are represented by `null`. + case YamlLines(t, Seq()) => YamlLines(t, Seq()) // other empty values are omitted. + case y @ YamlLines(_, lines) => + if (options.jsonFormat) y else y.copy(lines = (delimiter + lines.head) +: lines.tail.map(l => yamlIndent(options.indent) + l)) } - Right(YamlLines(YArray, output.flatMap(_.lines))) + + if (options.jsonFormat) { + val (jsonBeginList, jsonEndList) = if (options.jsonFormat) (Seq("["), Seq("]")) else (Seq(), Seq()) + if (output.isEmpty) Right(YamlLines(YArray, Seq("[]"))) + else { + val init = output.init.flatMap(y => if (y.lines.isEmpty) y.lines else y.lines.init :+ (y.lines.last + ",")) + val last = output.last.lines + Right(YamlLines(YArray, jsonBeginList ++ (init ++ last).map(l => yamlIndent(options.indent) + l) ++ jsonEndList)) + } + } else Right(YamlLines(YArray, output.flatMap(_.lines))) } } case ExpressionScheme.TextLiteral(List(), trailing) => - if (trailing.contains("\n")) { + if (!options.jsonFormat && trailing.contains("\n")) { val lines = trailing.split("\n").toSeq - Right(YamlLines(YPrimitive, Seq("", "|") ++ lines)) + Right(YamlLines(YPrimitive, Seq("|") ++ lines)) } else Right(YamlLines(YPrimitive, Seq(stringEscapeForYaml(trailing, options)))) case ExpressionScheme.NaturalLiteral(_) | ExpressionScheme.DoubleLiteral(_) => Right(YamlLines(YPrimitive, Seq(expr.print))) + case ExpressionScheme.TimeLiteral(_, _, _, _) | ExpressionScheme.TimeZoneLiteral(_) => + Right(YamlLines(YPrimitive, Seq("\"" + expr.print + "\""))) + + case ExpressionScheme.DateLiteral(_, _, _) => + val quote = if (options.jsonFormat) "\"" else "'" + Right(YamlLines(YPrimitive, Seq(quote + expr.print + quote))) + case ExpressionScheme.ExprConstant(SyntaxConstants.Constant.True) | ExpressionScheme.ExprConstant(SyntaxConstants.Constant.False) => Right(YamlLines(YPrimitive, Seq(expr.print.toLowerCase))) case ExpressionScheme.KeywordSome(expression: Expression) => toYamlLines(expression, options) - case ExpressionScheme.Application(Expression(ExprBuiltin(Builtin.None)), _) => Right(YamlLines(YPrimitive, Seq())) + case ExpressionScheme.Application(Expression(ExprBuiltin(Builtin.None)), _) => Right(YamlLines(YNull, Seq())) + + case ExpressionScheme.Field(Expression(ExpressionScheme.UnionType(_)), FieldName(name)) => + Right(YamlLines(YPrimitive, Seq(stringEscapeForYaml(name, options)))) + + case ExpressionScheme.Application(Expression(ExpressionScheme.Field(Expression(ExpressionScheme.UnionType(_)), FieldName(_))), expr) => + toYamlLines(expr, options) - case _ => Left(s"Error: Unsupported expression type for Yaml export: ${expr.print} of type ${tpe.print}") + case _ => Left(s"Error: Unsupported expression type for $format export: ${expr.print} of type ${tpe.print}") } } + } - private val yamlSpecialNames = Set("y", "n", "yes", "no", "on", "off", "true", "false", "null", "~") + private val yamlReservedWords = Set("y", "n", "e", "yes", "no", "on", "off", "true", "false", "null", "~") private def stringEscapeForYaml(str: String, options: YamlOptions): String = { - if (yamlSpecialNames contains str.toLowerCase) "'" + str + "'" - else if (str.matches("^[+-]?([0-9]+|\\.inf|nan|[0-9]*\\.[0-9]*)$")) "'" + str + "'" - else if (str.matches("^([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]|[0-9][0-9]:[0-9][0-9]:[0-9][0-9])$")) "'" + str + "'" - else if ( - options.quoteAllStrings || str.matches("^(.*[\":{}$\\[\\]\\\\*&#?|<>!%@]|[^A-Za-z0-9_]*-).*$") - ) // Quote the string with "..." if the string contains a bare "-" but not if "-" is preceded by an alphanum symbol. - CString( - str - ).toString // \0, \x01, \x02, \x03, \x04, \x05, \x06, \a, \b, \t, \n, \v, \f, \r, \x0e, \x0f, \x10, \x11, \x12, \x13, \x14, \x15, \x16, \x17, \x18, \x19, \x1a, \e, \x1c, \x1d, \x1e, \x1f, \N, \_, \L, \P - else str + if (options.jsonFormat) CString(str).toString + else { + val singleQuote = "'" + if (yamlReservedWords contains str.toLowerCase) singleQuote + str + singleQuote + else if (str.matches("^[+-]?([0-9]+|\\.inf|nan|[0-9]*\\.[0-9]*)$")) singleQuote + str + singleQuote + else if (str.matches("^([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]|[0-9][0-9]:[0-9][0-9]:[0-9][0-9])$")) singleQuote + str + singleQuote + else if ( + options.quoteAllStrings || str.matches("^(.*[\":{}$\\[\\]\\\\*&#?|<>!%]|[^A-Za-z0-9_]*-).*$") + ) // Quote the string with "..." if the string contains a bare "-" but not if "-" is preceded by an alphanum symbol. + CString( + str + ).toString // \0, \x01, \x02, \x03, \x04, \x05, \x06, \a, \b, \t, \n, \v, \f, \r, \x0e, \x0f, \x10, \x11, \x12, \x13, \x14, \x15, \x16, \x17, \x18, \x19, \x1a, \e, \x1c, \x1d, \x1e, \x1f, \N, \_, \L, \P + else str + } } - private def escapeYamlName(name: String, options: YamlOptions): String = { - if (options.quoteAllStrings || (yamlSpecialNames contains name.toLowerCase)) s"'$name'" else name + private def escapeSpecialName(name: String, options: YamlOptions): String = { + val singleQuote = if (options.jsonFormat) "\"" else "'" + if (options.quoteAllStrings || options.jsonFormat || (yamlReservedWords contains name.toLowerCase)) singleQuote + name + singleQuote else name } - private def commentsToYaml(comments: String): String = { - if (comments.isEmpty) "" else comments.split("\n").map(line => line.replaceFirst("^[ \\t]*--", "")).mkString("#", "\n#", "\n") + private def commentsToYaml(comments: String, options: YamlOptions): String = { + if (comments.isEmpty || options.jsonFormat) "" else comments.split("\n").map(line => line.replaceFirst("^[ \\t]*--", "")).mkString("#", "\n#", "\n") } + // It is assumed that `expression` is reduced to its beta-normal form. Unreduced syntax sugar such as `{ a.b = 1 }` will not be accepted. def toYaml(expression: Expression, options: YamlOptions): Either[String, String] = { toYaml(DhallFile(Seq(), "", expression), options) } - def toYaml(dhallFile: DhallFile, options: YamlOptions): Either[String, String] = { - val yamlLines = (options.createDocuments, dhallFile.value.scheme) match { + def toYaml(dhallFile: DhallFile, rawOptions: YamlOptions): Either[String, String] = { + val options = if (!rawOptions.jsonFormat) rawOptions.copy(indent = math.max(rawOptions.indent, 1)) else rawOptions + val yamlLines = (options.createDocuments && !options.jsonFormat, dhallFile.value.scheme) match { case (true, ExpressionScheme.NonEmptyList(exprs)) => val results = exprs.map { e => toYamlLines(e, options.copy(createDocuments = false)) } val errors = results.collect { case Left(x) => x } @@ -149,7 +317,7 @@ object Yaml { val documentPrefix: Seq[String] = if (options.createDocuments) Seq("---") else Seq() toYamlLines(dhallFile.value, options.copy(createDocuments = false)).map(y => y.copy(lines = documentPrefix ++ y.lines)) } - yamlLines.map(_.lines.mkString("", "\n", "\n")).map(yaml => commentsToYaml(dhallFile.headerComments) + yaml) + yamlLines.map(_.lines.mkString("", "\n", "\n")).map(yaml => commentsToYaml(dhallFile.headerComments, options) + yaml) } } diff --git a/scall-core/src/test/scala/io/chymyst/dhall/unit/JsonTest.scala b/scall-core/src/test/scala/io/chymyst/dhall/unit/JsonTest.scala new file mode 100644 index 00000000..85bdeb67 --- /dev/null +++ b/scall-core/src/test/scala/io/chymyst/dhall/unit/JsonTest.scala @@ -0,0 +1,34 @@ +package io.chymyst.dhall.unit + +import com.eed3si9n.expecty.Expecty.expect +import io.chymyst.dhall.Parser.StringAsDhallExpression +import io.chymyst.dhall.Yaml +import io.chymyst.dhall.Yaml.YamlOptions +import munit.FunSuite + +class JsonTest extends FunSuite { + val options = YamlOptions(jsonFormat = true) + test("yaml output for record of lists with indent") { + expect( + Yaml.toYaml("{a = [1, 2, 3], b= [[4], [5]]}".dhall, options.copy(indent = 4)).merge + == + """{ + | "a": [ + | 1, + | 2, + | 3 + | ], + | "b": [ + | [ + | 4 + | ], + | [ + | 5 + | ] + | ] + |} + |""".stripMargin + ) + } + +} diff --git a/scall-core/src/test/scala/io/chymyst/dhall/unit/YamlTest.scala b/scall-core/src/test/scala/io/chymyst/dhall/unit/YamlTest.scala index 6cba1aee..f4d10091 100644 --- a/scall-core/src/test/scala/io/chymyst/dhall/unit/YamlTest.scala +++ b/scall-core/src/test/scala/io/chymyst/dhall/unit/YamlTest.scala @@ -16,8 +16,8 @@ class YamlTest extends FunSuite { expect( result == """# comment - |a: 'True' - |""".stripMargin + |a: 'True' + |""".stripMargin ) } @@ -27,10 +27,10 @@ class YamlTest extends FunSuite { expect( result == """# comment - |# - |# comment - |a: 'True' - |""".stripMargin + |# + |# comment + |a: 'True' + |""".stripMargin ) } @@ -40,21 +40,25 @@ class YamlTest extends FunSuite { expect( result == """# comment - |# comment - |#{- abc -} - |a: 'True' - |""".stripMargin + |# comment + |#{- abc -} + |a: 'True' + |""".stripMargin ) } - test("yaml output for record of lists with indent") { - expect(Yaml.toYaml("{a = [1, 2, 3], b= [4, 5]}".dhall, options.copy(indent = 4)).merge == """a: - | - 1 - | - 2 - | - 3 - |b: - | - 4 - | - 5 - |""".stripMargin) + + test("yaml output for record of lists with indent 4") { + expect( + Yaml.toYaml("{a = [1, 2, 3], b= [4, 5]}".dhall, options.copy(indent = 4)).merge == + """a: + | - 1 + | - 2 + | - 3 + |b: + | - 4 + | - 5 + |""".stripMargin + ) } test("yaml output for strings with special characters") { @@ -62,122 +66,44 @@ class YamlTest extends FunSuite { expect( result1 == """a: "-" - |""".stripMargin + |""".stripMargin ) val result2 = Yaml.toYaml("{a = \"a-b\"}".dhall, options).merge expect( result2 == """a: a-b - |""".stripMargin + |""".stripMargin ) val result3 = Yaml.toYaml("""{a = "\"abc\""}""".dhall, options).merge expect( result3 == """a: "\"abc\"" - |""".stripMargin - ) - } - - test("yaml output for multiline strings with special characters") { - val result1 = Yaml.toYaml("{a = \"-\\n\\\"-\\\"\"}".dhall, options).merge - expect(result1 == """a: | - | - - | "-" - |""".stripMargin) - val result2 = Yaml.toYaml("[ \"-\\n\\\"-\\\"\", \"a\", \"b\"]".dhall, options).merge - expect(result2 == """- | - | - - | "-" - |- a - |- b - |""".stripMargin) - val result3 = Yaml.toYaml("{a = [\"-\\n\\\"-\\\"\", \"a\", \"b\"]}".dhall, options).merge - expect(result3 == """a: - | - | - | - - | "-" - | - a - | - b - |""".stripMargin) - - } - - test("yaml output for strings with special characters") { - val result = Yaml.toYaml("{a = \"a-b: c\"}".dhall, options).merge - expect( - result == - """a: "a-b: c" - |""".stripMargin - ) - } - - test("yaml output for record of lists of strings") { - val result = Yaml.toYaml("{a = [\" - c\",\"d\",\"e\"]}".dhall, options).merge - expect( - result == - """a: - | - " - c" - | - d - | - e |""".stripMargin ) } - test("yaml output for record of length-1 lists of strings") { - val result = Yaml.toYaml("{a = [\"e\"]}".dhall, options).merge + test("json output with longer indentation") { expect( - result == - """a: - | - e - |""".stripMargin - ) - } - - test("yaml output for record of records of strings") { - val result = Yaml.toYaml("{a.b =\"e\", a.c = \"f\" }".dhall.betaNormalized, options).merge - expect( - result == - """a: - | b: e - | c: f - |""".stripMargin - ) - } - - test("yaml output for record of length-1 records of strings") { - val result = Yaml.toYaml("{a.b =\"e\" }".dhall, options).merge - expect( - result == - """a: - | b: e - |""".stripMargin - ) - } - - test("yaml output for record of length-0 records") { - val result = Yaml.toYaml("{a.b = {=} }".dhall, options).merge - expect( - result == - """a: - | b: {} - |""".stripMargin - ) - } - - test("yaml output for record of length-0 lists") { - val result = Yaml.toYaml("{a.b = [] : List Bool }".dhall, options).merge - expect( - result == - """a: - | b: [] - |""".stripMargin + Yaml.toYaml("{a = [1, 2, 3], b=True,c= [[4], [5]]}".dhall, options.copy(indent = 4, jsonFormat = true)).merge + == + """{ + | "a": [ + | 1, + | 2, + | 3 + | ], + | "b": true, + | "c": [ + | [ + | 4 + | ], + | [ + | 5 + | ] + | ] + |} + |""".stripMargin ) } - test("yaml should fail if expression does not typecheck") { - val result = Yaml.toYaml("1 + True".dhall, options) - expect( - result == Left("List(Inferred type Bool differs from the expected type Natural, expression under type inference: True, type inference context = {})") - ) - } }