aboutsummaryrefslogtreecommitdiffstats
path: root/libtests
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2022-01-18 00:40:38 +0100
committerJay Berkenbilt <ejb@ql.org>2022-01-30 19:11:03 +0100
commite8e8f6f43c760523520dfe7a5c76d88c959599f6 (patch)
treea000bcb5cbbde3e2833a57a28e761449b62165b2 /libtests
parentb9af421ef788b94fcbf18ecf702cec3ba9a018b7 (diff)
downloadqpdf-e8e8f6f43c760523520dfe7a5c76d88c959599f6.tar.zst
Add JSON::parse
Diffstat (limited to 'libtests')
-rw-r--r--libtests/build.mk1
-rw-r--r--libtests/json.cc136
-rw-r--r--libtests/json_parse.cc27
-rw-r--r--libtests/libtests.testcov26
-rw-r--r--libtests/qtest/json/json.out25
-rw-r--r--libtests/qtest/json_parse.test137
-rw-r--r--libtests/qtest/json_parse/bad-01.json1
-rw-r--r--libtests/qtest/json_parse/bad-01.out1
-rw-r--r--libtests/qtest/json_parse/bad-02.json1
-rw-r--r--libtests/qtest/json_parse/bad-02.out1
-rw-r--r--libtests/qtest/json_parse/bad-03.json1
-rw-r--r--libtests/qtest/json_parse/bad-03.out1
-rw-r--r--libtests/qtest/json_parse/bad-04.json2
-rw-r--r--libtests/qtest/json_parse/bad-04.out1
-rw-r--r--libtests/qtest/json_parse/bad-05.json1
-rw-r--r--libtests/qtest/json_parse/bad-05.out1
-rw-r--r--libtests/qtest/json_parse/bad-06.json1
-rw-r--r--libtests/qtest/json_parse/bad-06.out1
-rw-r--r--libtests/qtest/json_parse/bad-07.json1
-rw-r--r--libtests/qtest/json_parse/bad-07.out1
-rw-r--r--libtests/qtest/json_parse/bad-08.json1
-rw-r--r--libtests/qtest/json_parse/bad-08.out1
-rw-r--r--libtests/qtest/json_parse/bad-09.json1
-rw-r--r--libtests/qtest/json_parse/bad-09.out1
-rw-r--r--libtests/qtest/json_parse/bad-10.json1
-rw-r--r--libtests/qtest/json_parse/bad-10.out1
-rw-r--r--libtests/qtest/json_parse/bad-11.json1
-rw-r--r--libtests/qtest/json_parse/bad-11.out1
-rw-r--r--libtests/qtest/json_parse/bad-12.json1
-rw-r--r--libtests/qtest/json_parse/bad-12.out1
-rw-r--r--libtests/qtest/json_parse/bad-13.json1
-rw-r--r--libtests/qtest/json_parse/bad-13.out1
-rw-r--r--libtests/qtest/json_parse/bad-14.json1
-rw-r--r--libtests/qtest/json_parse/bad-14.out1
-rw-r--r--libtests/qtest/json_parse/bad-15.json1
-rw-r--r--libtests/qtest/json_parse/bad-15.out1
-rw-r--r--libtests/qtest/json_parse/bad-16.json1
-rw-r--r--libtests/qtest/json_parse/bad-16.out1
-rw-r--r--libtests/qtest/json_parse/bad-17.json1
-rw-r--r--libtests/qtest/json_parse/bad-17.out1
-rw-r--r--libtests/qtest/json_parse/bad-18.jsonbin0 -> 9 bytes
-rw-r--r--libtests/qtest/json_parse/bad-18.out1
-rw-r--r--libtests/qtest/json_parse/bad-19.json1
-rw-r--r--libtests/qtest/json_parse/bad-19.out1
-rw-r--r--libtests/qtest/json_parse/bad-20.json1
-rw-r--r--libtests/qtest/json_parse/bad-20.out1
-rw-r--r--libtests/qtest/json_parse/bad-21.json1
-rw-r--r--libtests/qtest/json_parse/bad-21.out1
-rw-r--r--libtests/qtest/json_parse/bad-22.json1
-rw-r--r--libtests/qtest/json_parse/bad-22.out1
-rw-r--r--libtests/qtest/json_parse/bad-23.json1
-rw-r--r--libtests/qtest/json_parse/bad-23.out1
-rw-r--r--libtests/qtest/json_parse/bad-24.json1
-rw-r--r--libtests/qtest/json_parse/bad-24.out1
-rw-r--r--libtests/qtest/json_parse/bad-25.json1
-rw-r--r--libtests/qtest/json_parse/bad-25.out1
-rw-r--r--libtests/qtest/json_parse/bad-26.json1
-rw-r--r--libtests/qtest/json_parse/bad-26.out1
-rw-r--r--libtests/qtest/json_parse/bad-27.json1
-rw-r--r--libtests/qtest/json_parse/bad-27.out1
-rw-r--r--libtests/qtest/json_parse/bad-28.json1
-rw-r--r--libtests/qtest/json_parse/bad-28.out1
-rw-r--r--libtests/qtest/json_parse/bad-29.json1
-rw-r--r--libtests/qtest/json_parse/bad-29.out1
-rw-r--r--libtests/qtest/json_parse/bad-30.json1
-rw-r--r--libtests/qtest/json_parse/bad-30.out1
-rw-r--r--libtests/qtest/json_parse/bad-31.json1
-rw-r--r--libtests/qtest/json_parse/bad-31.out1
-rw-r--r--libtests/qtest/json_parse/bad-32.json1
-rw-r--r--libtests/qtest/json_parse/bad-32.out1
-rw-r--r--libtests/qtest/json_parse/bad-33.json1
-rw-r--r--libtests/qtest/json_parse/bad-33.out1
-rw-r--r--libtests/qtest/json_parse/bad-34.json1
-rw-r--r--libtests/qtest/json_parse/bad-34.out1
-rw-r--r--libtests/qtest/json_parse/bad-35.json1
-rw-r--r--libtests/qtest/json_parse/bad-35.out1
-rw-r--r--libtests/qtest/json_parse/good-01.json3
-rw-r--r--libtests/qtest/json_parse/good-02.json1
-rw-r--r--libtests/qtest/json_parse/good-03.json1
-rw-r--r--libtests/qtest/json_parse/good-04.json1
-rw-r--r--libtests/qtest/json_parse/good-05.json1
-rw-r--r--libtests/qtest/json_parse/good-06.json1
-rw-r--r--libtests/qtest/json_parse/good-07.json1
-rw-r--r--libtests/qtest/json_parse/good-08.json1
-rw-r--r--libtests/qtest/json_parse/good-09.json1
-rw-r--r--libtests/qtest/json_parse/save-01.json17
-rw-r--r--libtests/qtest/json_parse/save-02.json1
-rw-r--r--libtests/qtest/json_parse/save-03.json1
-rw-r--r--libtests/qtest/json_parse/save-04.json10
-rw-r--r--libtests/qtest/json_parse/save-05.json1
-rw-r--r--libtests/qtest/json_parse/save-06.json1
-rw-r--r--libtests/qtest/json_parse/save-07.json1
-rw-r--r--libtests/qtest/json_parse/save-08.json10
-rw-r--r--libtests/qtest/json_parse/save-09.json7
94 files changed, 410 insertions, 72 deletions
diff --git a/libtests/build.mk b/libtests/build.mk
index 1ae95196..a23b9c28 100644
--- a/libtests/build.mk
+++ b/libtests/build.mk
@@ -13,6 +13,7 @@ BINS_libtests = \
hex \
input_source \
json \
+ json_parse \
lzw \
main_from_wmain \
matrix \
diff --git a/libtests/json.cc b/libtests/json.cc
index d788ab4e..7bea5589 100644
--- a/libtests/json.cc
+++ b/libtests/json.cc
@@ -91,67 +91,83 @@ static void check_schema(JSON& obj, JSON& schema, bool exp,
static void test_schema()
{
- // Since we don't have a JSON parser, use the PDF parser as a
- // shortcut for creating a complex JSON structure.
- JSON schema = QPDFObjectHandle::parse(
- "<<"
- " /one <<"
- " /a <<"
- " /q (queue)"
- " /r <<"
- " /x (ecks)"
- " /y (why)"
- " >>"
- " /s [ (esses) ]"
- " >>"
- " >>"
- " /two ["
- " <<"
- " /goose (gander)"
- " /glarp (enspliel)"
- " >>"
- " ]"
- ">>").getJSON();
- JSON three = JSON::makeDictionary();
- three.addDictionaryMember(
- "<objid>",
- QPDFObjectHandle::parse("<< /z (ebra) >>").getJSON());
- schema.addDictionaryMember("/three", three);
- JSON a = QPDFObjectHandle::parse("[(not a) (dictionary)]").getJSON();
+ JSON schema = JSON::parse(R"(
+{
+ "one": {
+ "a": {
+ "q": "queue",
+ "r": {
+ "x": "ecks",
+ "y": "(bool) why"
+ },
+ "s": [
+ "esses"
+ ]
+ }
+ },
+ "two": [
+ {
+ "goose": "gander",
+ "glarp": "enspliel"
+ }
+ ],
+ "three": {
+ "<objid>": {
+ "z": "ebra",
+ "o": "(optional, string) optional"
+ }
+ }
+}
+)");
+
+ JSON a = JSON::parse(R"(["not a", "dictionary"])");
check_schema(a, schema, false, "top-level type mismatch");
- JSON b = QPDFObjectHandle::parse(
- "<<"
- " /one <<"
- " /a <<"
- " /t (oops)"
- " /r ["
- " /x (ecks)"
- " /y (why)"
- " ]"
- " /s << /z (esses) >>"
- " >>"
- " >>"
- " /two ["
- " <<"
- " /goose (0 gander)"
- " /glarp (0 enspliel)"
- " >>"
- " <<"
- " /goose (1 gander)"
- " /flarp (1 enspliel)"
- " >>"
- " 2"
- " [ (three) ]"
- " <<"
- " /goose (4 gander)"
- " /glarp (4 enspliel)"
- " >>"
- " ]"
- " /three <<"
- " /anything << /x (oops) >>"
- " /else << /z (okay) >>"
- " >>"
- ">>").getJSON();
+ JSON b = JSON::parse(R"(
+{
+ "one": {
+ "a": {
+ "t": "oops",
+ "r": [
+ "x",
+ "ecks",
+ "y",
+ "why"
+ ],
+ "s": {
+ "z": "esses"
+ }
+ }
+ },
+ "two": [
+ {
+ "goose": "0 gander",
+ "glarp": "0 enspliel"
+ },
+ {
+ "goose": "1 gander",
+ "flarp": "1 enspliel"
+ },
+ 2,
+ [
+ "three"
+ ],
+ {
+ "goose": "4 gander",
+ "glarp": 4
+ }
+ ],
+ "three": {
+ "anything": {
+ "x": "oops",
+ "o": "okay"
+ },
+ "else": {
+ "z": "okay"
+ }
+ }
+}
+)");
+
check_schema(b, schema, false, "missing items");
check_schema(a, a, false, "top-level schema array error");
check_schema(b, b, false, "lower-level schema array error");
diff --git a/libtests/json_parse.cc b/libtests/json_parse.cc
new file mode 100644
index 00000000..f0491723
--- /dev/null
+++ b/libtests/json_parse.cc
@@ -0,0 +1,27 @@
+#include <qpdf/JSON.hh>
+#include <qpdf/QUtil.hh>
+#include <iostream>
+
+int main(int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ std::cerr << "Usage: json_parse file" << std::endl;
+ return 2;
+ }
+ char const* filename = argv[1];
+ try
+ {
+ PointerHolder<char> buf;
+ size_t size;
+ QUtil::read_file_into_memory(filename, buf, size);
+ std::string s(buf.getPointer(), size);
+ std::cout << JSON::parse(s).unparse() << std::endl;
+ }
+ catch (std::exception& e)
+ {
+ std::cerr << "exception: " << filename<< ": " << e.what() << std::endl;
+ return 2;
+ }
+ return 0;
+}
diff --git a/libtests/libtests.testcov b/libtests/libtests.testcov
index 70aae578..5f36819a 100644
--- a/libtests/libtests.testcov
+++ b/libtests/libtests.testcov
@@ -61,3 +61,29 @@ QPDFArgParser duplicate option help 0
QPDFArgParser bad option for help 0
QPDFArgParser bad topic for help 0
QPDFArgParser invalid choice handler to unknown 0
+JSON parse junk after object 0
+JSON parse decimal with no digits 0
+JSON parse invalid keyword 0
+JSON parse expected colon 0
+JSON parse expected , or } 0
+JSON parse expected, or ] 0
+JSON parse string as dict key 0
+JSON parse unexpected } 0
+JSON parse unexpected ] 0
+JSON parse unexpected : 0
+JSON parse unexpected , 0
+JSON parse preature EOF 0
+JSON parse null character 0
+JSON parse bad character 0
+JSON parse point after e 0
+JSON parse duplicate point 0
+JSON parse duplicate e 0
+JSON parse unexpected sign 0
+JSON parse numeric bad character 0
+JSON parse keyword bad character 0
+JSON parse backslash bad character 0
+JSON parse unterminated string 0
+JSON parse leading zero 0
+JSON parse number no digits 0
+JSON parse premature end of u 0
+JSON parse bad hex after u 0
diff --git a/libtests/qtest/json/json.out b/libtests/qtest/json/json.out
index ad668e51..1a320dcf 100644
--- a/libtests/qtest/json/json.out
+++ b/libtests/qtest/json/json.out
@@ -2,23 +2,24 @@
top-level object is supposed to be a dictionary
---
--- missing items
-json key "./one./a": key "/q" is present in schema but missing in object
-json key "./one./a./r" is supposed to be a dictionary
-json key "./one./a./s" is supposed to be an array
-json key "./one./a": key "/t" is not present in schema but appears in object
-json key "./three./anything": key "/z" is present in schema but missing in object
-json key "./three./anything": key "/x" is not present in schema but appears in object
-json key "./two.1": key "/glarp" is present in schema but missing in object
-json key "./two.1": key "/flarp" is not present in schema but appears in object
-json key "./two.2" is supposed to be a dictionary
-json key "./two.3" is supposed to be a dictionary
+json key ".one.a": key "q" is present in schema but missing in object
+json key ".one.a.r" is supposed to be a dictionary
+json key ".one.a.s" is supposed to be an array
+json key ".one.a": key "t" is not present in schema but appears in object
+json key ".three.anything": key "z" is present in schema but missing in object
+json key ".three.anything": key "x" is not present in schema but appears in object
+json key ".three.else": key "o" is present in schema but missing in object
+json key ".two.1": key "glarp" is present in schema but missing in object
+json key ".two.1": key "flarp" is not present in schema but appears in object
+json key ".two.2" is supposed to be a dictionary
+json key ".two.3" is supposed to be a dictionary
---
--- top-level schema array error
top-level object schema array contains other than one item
---
--- lower-level schema array error
-json key "./one./a./r" schema array contains other than one item
-json key "./two" schema array contains other than one item
+json key ".one.a.r" schema array contains other than one item
+json key ".two" schema array contains other than one item
---
--- pass
---
diff --git a/libtests/qtest/json_parse.test b/libtests/qtest/json_parse.test
new file mode 100644
index 00000000..7b1824e9
--- /dev/null
+++ b/libtests/qtest/json_parse.test
@@ -0,0 +1,137 @@
+#!/usr/bin/env perl
+require 5.008;
+use warnings;
+use strict;
+use File::Copy;
+use File::Compare;
+
+chdir("json_parse") or die "chdir testdir failed: $!\n";
+
+require TestDriver;
+
+my $td = new TestDriver('json_parse');
+
+my $json_mod = 0;
+eval {
+ require JSON;
+ $json_mod = 1;
+};
+if ($@)
+{
+ $td->emphasize("JSON.pm not found -- using stored actual outputs");
+}
+
+cleanup();
+
+my $good = 9;
+
+for (my $i = 1; $i <= $good; ++$i)
+{
+ my $n = sprintf("%02d", $i);
+
+ unlink "out.json";
+ my $r = system("json_parse good-$n.json > out.json 2>&1");
+ if ($td->runtest("json_parse accepted $n",
+ {$td->STRING => "$r\n"},
+ {$td->STRING => "0\n"},
+ $td->NORMALIZE_NEWLINES))
+ {
+ if ($json_mod)
+ {
+ if ($td->runtest("check output $n",
+ {$td->STRING => normalize_json("out.json")},
+ {$td->STRING => normalize_json("good-$n.json")},
+ $td->NORMALIZE_NEWLINES))
+ {
+ if (compare("out.json", "save-$n.json"))
+ {
+ copy("out.json", "save-$n.json");
+ $td->emphasize("updated save-$n.json from out.json");
+ }
+ }
+ }
+ else
+ {
+ $td->runtest("check output $n against saved",
+ {$td->FILE => "out.json"},
+ {$td->FILE => "save-$n.json"},
+ $td->NORMALIZE_NEWLINES);
+ }
+ }
+ else
+ {
+ $td->runtest("skip checking output $n",
+ {$td->FILE => "out.json"},
+ {$td->STRING => ""});
+ }
+}
+
+my @bad = (
+ "junk after string", # 1
+ "junk after array", # 2
+ "junk after dictionary", # 3
+ "bad number", # 4
+ "invalid keyword", # 5
+ "missing colon", # 6
+ "missing comma in dict", # 7
+ "missing comma in array", # 8
+ "dict key not string", # 9
+ "unexpected } in array", # 10
+ "unexpected } at top", # 11
+ "unexpected } in dict", # 12
+ "unexpected ] in dict", # 13
+ "unexpected ] at top", # 14
+ "unexpected :", # 15
+ "unexpected ,", # 16
+ "premature end array", # 17
+ "null character", # 18
+ "unexpected character", # 19
+ "point in exponent", # 20
+ "duplicate point", # 21
+ "duplicate e", # 22
+ "stray +", # 23
+ "bad character in number", # 24
+ "bad character in keyword", # 25
+ "bad backslash character", # 26
+ "unterminated string", # 27
+ "unterminated after \\", # 28
+ "leading +", # 29
+ "decimal with no digits", # 30
+ "minus with no digits", # 31
+ "leading zero", # 32
+ "leading zero negative", # 33
+ "premature end after u", # 34
+ "bad hex digit", # 35
+ );
+
+my $i = 0;
+foreach my $d (@bad)
+{
+ ++$i;
+ my $n = sprintf("%02d", $i);
+ $td->runtest("$n: $d",
+ {$td->COMMAND => "json_parse bad-$n.json"},
+ {$td->FILE => "bad-$n.out", $td->EXIT_STATUS => 2},
+ $td->NORMALIZE_NEWLINES);
+}
+
+cleanup();
+
+$td->report((2 * $good) + scalar(@bad));
+
+sub cleanup
+{
+ unlink "out.json";
+}
+
+sub normalize_json
+{
+ my $file = shift;
+ open(F, "<$file") or die "can't open $file: $file: $!\n";
+ $/ = undef;
+ my $encoded = scalar(<F>);
+ close(F);
+ my $j = JSON->new->allow_nonref;
+ $j->canonical();
+ $j->utf8->pretty->encode($j->utf8->decode($encoded));
+}
diff --git a/libtests/qtest/json_parse/bad-01.json b/libtests/qtest/json_parse/bad-01.json
new file mode 100644
index 00000000..be8f5206
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-01.json
@@ -0,0 +1 @@
+"a" junk
diff --git a/libtests/qtest/json_parse/bad-01.out b/libtests/qtest/json_parse/bad-01.out
new file mode 100644
index 00000000..a4254cff
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-01.out
@@ -0,0 +1 @@
+exception: bad-01.json: JSON: offset 9: material follows end of object: junk
diff --git a/libtests/qtest/json_parse/bad-02.json b/libtests/qtest/json_parse/bad-02.json
new file mode 100644
index 00000000..63dffebd
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-02.json
@@ -0,0 +1 @@
+["a"] junk
diff --git a/libtests/qtest/json_parse/bad-02.out b/libtests/qtest/json_parse/bad-02.out
new file mode 100644
index 00000000..485c9658
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-02.out
@@ -0,0 +1 @@
+exception: bad-02.json: JSON: offset 11: material follows end of object: junk
diff --git a/libtests/qtest/json_parse/bad-03.json b/libtests/qtest/json_parse/bad-03.json
new file mode 100644
index 00000000..20769389
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-03.json
@@ -0,0 +1 @@
+{"a": "b"} junk
diff --git a/libtests/qtest/json_parse/bad-03.out b/libtests/qtest/json_parse/bad-03.out
new file mode 100644
index 00000000..38f35119
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-03.out
@@ -0,0 +1 @@
+exception: bad-03.json: JSON: offset 16: material follows end of object: junk
diff --git a/libtests/qtest/json_parse/bad-04.json b/libtests/qtest/json_parse/bad-04.json
new file mode 100644
index 00000000..cb5c9145
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-04.json
@@ -0,0 +1,2 @@
+[1, .]
+
diff --git a/libtests/qtest/json_parse/bad-04.out b/libtests/qtest/json_parse/bad-04.out
new file mode 100644
index 00000000..7fe71693
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-04.out
@@ -0,0 +1 @@
+exception: bad-04.json: JSON: offset 5: decimal point with no digits
diff --git a/libtests/qtest/json_parse/bad-05.json b/libtests/qtest/json_parse/bad-05.json
new file mode 100644
index 00000000..632b1ab2
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-05.json
@@ -0,0 +1 @@
+[true, potato]
diff --git a/libtests/qtest/json_parse/bad-05.out b/libtests/qtest/json_parse/bad-05.out
new file mode 100644
index 00000000..d94b4e62
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-05.out
@@ -0,0 +1 @@
+exception: bad-05.json: JSON: offset 13: invalid keyword potato
diff --git a/libtests/qtest/json_parse/bad-06.json b/libtests/qtest/json_parse/bad-06.json
new file mode 100644
index 00000000..de355688
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-06.json
@@ -0,0 +1 @@
+{"x" "y"}
diff --git a/libtests/qtest/json_parse/bad-06.out b/libtests/qtest/json_parse/bad-06.out
new file mode 100644
index 00000000..8ed262ce
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-06.out
@@ -0,0 +1 @@
+exception: bad-06.json: JSON: offset 8: expected ':'
diff --git a/libtests/qtest/json_parse/bad-07.json b/libtests/qtest/json_parse/bad-07.json
new file mode 100644
index 00000000..b24dc391
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-07.json
@@ -0,0 +1 @@
+{"x": 3 "y"}
diff --git a/libtests/qtest/json_parse/bad-07.out b/libtests/qtest/json_parse/bad-07.out
new file mode 100644
index 00000000..06774722
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-07.out
@@ -0,0 +1 @@
+exception: bad-07.json: JSON: offset 11: expected ',' or '}'
diff --git a/libtests/qtest/json_parse/bad-08.json b/libtests/qtest/json_parse/bad-08.json
new file mode 100644
index 00000000..b15acc57
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-08.json
@@ -0,0 +1 @@
+["x" "y"]
diff --git a/libtests/qtest/json_parse/bad-08.out b/libtests/qtest/json_parse/bad-08.out
new file mode 100644
index 00000000..c597e60e
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-08.out
@@ -0,0 +1 @@
+exception: bad-08.json: JSON: offset 8: expected ',' or ']'
diff --git a/libtests/qtest/json_parse/bad-09.json b/libtests/qtest/json_parse/bad-09.json
new file mode 100644
index 00000000..d82de610
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-09.json
@@ -0,0 +1 @@
+{5 : 5}
diff --git a/libtests/qtest/json_parse/bad-09.out b/libtests/qtest/json_parse/bad-09.out
new file mode 100644
index 00000000..21d2f1c1
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-09.out
@@ -0,0 +1 @@
+exception: bad-09.json: JSON: offset 3: expect string as dictionary key
diff --git a/libtests/qtest/json_parse/bad-10.json b/libtests/qtest/json_parse/bad-10.json
new file mode 100644
index 00000000..f5cc41b6
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-10.json
@@ -0,0 +1 @@
+["a"}
diff --git a/libtests/qtest/json_parse/bad-10.out b/libtests/qtest/json_parse/bad-10.out
new file mode 100644
index 00000000..d725d492
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-10.out
@@ -0,0 +1 @@
+exception: bad-10.json: JSON: offset 5: unexpected dictionary end delimiter
diff --git a/libtests/qtest/json_parse/bad-11.json b/libtests/qtest/json_parse/bad-11.json
new file mode 100644
index 00000000..5c34318c
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-11.json
@@ -0,0 +1 @@
+}
diff --git a/libtests/qtest/json_parse/bad-11.out b/libtests/qtest/json_parse/bad-11.out
new file mode 100644
index 00000000..ae8fd636
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-11.out
@@ -0,0 +1 @@
+exception: bad-11.json: JSON: offset 1: unexpected dictionary end delimiter
diff --git a/libtests/qtest/json_parse/bad-12.json b/libtests/qtest/json_parse/bad-12.json
new file mode 100644
index 00000000..c9c9b68f
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-12.json
@@ -0,0 +1 @@
+{""}
diff --git a/libtests/qtest/json_parse/bad-12.out b/libtests/qtest/json_parse/bad-12.out
new file mode 100644
index 00000000..0ff371a1
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-12.out
@@ -0,0 +1 @@
+exception: bad-12.json: JSON: offset 4: unexpected dictionary end delimiter
diff --git a/libtests/qtest/json_parse/bad-13.json b/libtests/qtest/json_parse/bad-13.json
new file mode 100644
index 00000000..70312269
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-13.json
@@ -0,0 +1 @@
+{"": "x"]
diff --git a/libtests/qtest/json_parse/bad-13.out b/libtests/qtest/json_parse/bad-13.out
new file mode 100644
index 00000000..8a53bd3f
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-13.out
@@ -0,0 +1 @@
+exception: bad-13.json: JSON: offset 9: unexpected array end delimiter
diff --git a/libtests/qtest/json_parse/bad-14.json b/libtests/qtest/json_parse/bad-14.json
new file mode 100644
index 00000000..079b5796
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-14.json
@@ -0,0 +1 @@
+]
diff --git a/libtests/qtest/json_parse/bad-14.out b/libtests/qtest/json_parse/bad-14.out
new file mode 100644
index 00000000..8f619ef8
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-14.out
@@ -0,0 +1 @@
+exception: bad-14.json: JSON: offset 1: unexpected array end delimiter
diff --git a/libtests/qtest/json_parse/bad-15.json b/libtests/qtest/json_parse/bad-15.json
new file mode 100644
index 00000000..aaac6657
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-15.json
@@ -0,0 +1 @@
+["a": ]
diff --git a/libtests/qtest/json_parse/bad-15.out b/libtests/qtest/json_parse/bad-15.out
new file mode 100644
index 00000000..68153212
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-15.out
@@ -0,0 +1 @@
+exception: bad-15.json: JSON: offset 5: unexpected colon
diff --git a/libtests/qtest/json_parse/bad-16.json b/libtests/qtest/json_parse/bad-16.json
new file mode 100644
index 00000000..12684fdb
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-16.json
@@ -0,0 +1 @@
+[,]
diff --git a/libtests/qtest/json_parse/bad-16.out b/libtests/qtest/json_parse/bad-16.out
new file mode 100644
index 00000000..1553e0b6
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-16.out
@@ -0,0 +1 @@
+exception: bad-16.json: JSON: offset 2: unexpected comma
diff --git a/libtests/qtest/json_parse/bad-17.json b/libtests/qtest/json_parse/bad-17.json
new file mode 100644
index 00000000..0617cad4
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-17.json
@@ -0,0 +1 @@
+[1, 2,
diff --git a/libtests/qtest/json_parse/bad-17.out b/libtests/qtest/json_parse/bad-17.out
new file mode 100644
index 00000000..d2bf40e2
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-17.out
@@ -0,0 +1 @@
+exception: bad-17.json: JSON: premature end of input
diff --git a/libtests/qtest/json_parse/bad-18.json b/libtests/qtest/json_parse/bad-18.json
new file mode 100644
index 00000000..a0c81001
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-18.json
Binary files differ
diff --git a/libtests/qtest/json_parse/bad-18.out b/libtests/qtest/json_parse/bad-18.out
new file mode 100644
index 00000000..0428b64f
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-18.out
@@ -0,0 +1 @@
+exception: bad-18.json: JSON: null character at offset 5
diff --git a/libtests/qtest/json_parse/bad-19.json b/libtests/qtest/json_parse/bad-19.json
new file mode 100644
index 00000000..b498fd49
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-19.json
@@ -0,0 +1 @@
+/
diff --git a/libtests/qtest/json_parse/bad-19.out b/libtests/qtest/json_parse/bad-19.out
new file mode 100644
index 00000000..534ff943
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-19.out
@@ -0,0 +1 @@
+exception: bad-19.json: JSON: offset 0: unexpected character /
diff --git a/libtests/qtest/json_parse/bad-20.json b/libtests/qtest/json_parse/bad-20.json
new file mode 100644
index 00000000..fb5264eb
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-20.json
@@ -0,0 +1 @@
+3.14e5.6
diff --git a/libtests/qtest/json_parse/bad-20.out b/libtests/qtest/json_parse/bad-20.out
new file mode 100644
index 00000000..e761bf0c
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-20.out
@@ -0,0 +1 @@
+exception: bad-20.json: JSON: offset 6: numeric literal: decimal point after e
diff --git a/libtests/qtest/json_parse/bad-21.json b/libtests/qtest/json_parse/bad-21.json
new file mode 100644
index 00000000..bd87886b
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-21.json
@@ -0,0 +1 @@
+3.14.159
diff --git a/libtests/qtest/json_parse/bad-21.out b/libtests/qtest/json_parse/bad-21.out
new file mode 100644
index 00000000..697fb0e3
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-21.out
@@ -0,0 +1 @@
+exception: bad-21.json: JSON: offset 4: numeric literal: decimal point already seen
diff --git a/libtests/qtest/json_parse/bad-22.json b/libtests/qtest/json_parse/bad-22.json
new file mode 100644
index 00000000..38860be1
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-22.json
@@ -0,0 +1 @@
+3e4e5
diff --git a/libtests/qtest/json_parse/bad-22.out b/libtests/qtest/json_parse/bad-22.out
new file mode 100644
index 00000000..bb48715b
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-22.out
@@ -0,0 +1 @@
+exception: bad-22.json: JSON: offset 3: numeric literal: e already seen
diff --git a/libtests/qtest/json_parse/bad-23.json b/libtests/qtest/json_parse/bad-23.json
new file mode 100644
index 00000000..60def52f
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-23.json
@@ -0,0 +1 @@
+3+4
diff --git a/libtests/qtest/json_parse/bad-23.out b/libtests/qtest/json_parse/bad-23.out
new file mode 100644
index 00000000..18872df5
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-23.out
@@ -0,0 +1 @@
+exception: bad-23.json: JSON: offset 1: numeric literal: unexpected sign
diff --git a/libtests/qtest/json_parse/bad-24.json b/libtests/qtest/json_parse/bad-24.json
new file mode 100644
index 00000000..c863fc63
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-24.json
@@ -0,0 +1 @@
+12x
diff --git a/libtests/qtest/json_parse/bad-24.out b/libtests/qtest/json_parse/bad-24.out
new file mode 100644
index 00000000..7d539267
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-24.out
@@ -0,0 +1 @@
+exception: bad-24.json: JSON: offset 2: numeric literal: unexpected character x
diff --git a/libtests/qtest/json_parse/bad-25.json b/libtests/qtest/json_parse/bad-25.json
new file mode 100644
index 00000000..6fede091
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-25.json
@@ -0,0 +1 @@
+abc1
diff --git a/libtests/qtest/json_parse/bad-25.out b/libtests/qtest/json_parse/bad-25.out
new file mode 100644
index 00000000..f2572b25
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-25.out
@@ -0,0 +1 @@
+exception: bad-25.json: JSON: offset 3: keyword: unexpected character 1
diff --git a/libtests/qtest/json_parse/bad-26.json b/libtests/qtest/json_parse/bad-26.json
new file mode 100644
index 00000000..5c62a2f2
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-26.json
@@ -0,0 +1 @@
+"abc\yd"
diff --git a/libtests/qtest/json_parse/bad-26.out b/libtests/qtest/json_parse/bad-26.out
new file mode 100644
index 00000000..33f536c1
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-26.out
@@ -0,0 +1 @@
+exception: bad-26.json: JSON: offset 5: invalid character after backslash: y
diff --git a/libtests/qtest/json_parse/bad-27.json b/libtests/qtest/json_parse/bad-27.json
new file mode 100644
index 00000000..083d193e
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-27.json
@@ -0,0 +1 @@
+"abcd
diff --git a/libtests/qtest/json_parse/bad-27.out b/libtests/qtest/json_parse/bad-27.out
new file mode 100644
index 00000000..2c2df076
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-27.out
@@ -0,0 +1 @@
+exception: bad-27.json: JSON: offset 6: unterminated string
diff --git a/libtests/qtest/json_parse/bad-28.json b/libtests/qtest/json_parse/bad-28.json
new file mode 100644
index 00000000..9b571f08
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-28.json
@@ -0,0 +1 @@
+"abc-no-newline\ \ No newline at end of file
diff --git a/libtests/qtest/json_parse/bad-28.out b/libtests/qtest/json_parse/bad-28.out
new file mode 100644
index 00000000..d7db2aea
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-28.out
@@ -0,0 +1 @@
+exception: bad-28.json: JSON: offset 16: unterminated string
diff --git a/libtests/qtest/json_parse/bad-29.json b/libtests/qtest/json_parse/bad-29.json
new file mode 100644
index 00000000..c367cd81
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-29.json
@@ -0,0 +1 @@
++123.
diff --git a/libtests/qtest/json_parse/bad-29.out b/libtests/qtest/json_parse/bad-29.out
new file mode 100644
index 00000000..b7ee83fb
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-29.out
@@ -0,0 +1 @@
+exception: bad-29.json: JSON: offset 0: unexpected character +
diff --git a/libtests/qtest/json_parse/bad-30.json b/libtests/qtest/json_parse/bad-30.json
new file mode 100644
index 00000000..b8db69c7
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-30.json
@@ -0,0 +1 @@
+123.
diff --git a/libtests/qtest/json_parse/bad-30.out b/libtests/qtest/json_parse/bad-30.out
new file mode 100644
index 00000000..bff961af
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-30.out
@@ -0,0 +1 @@
+exception: bad-30.json: JSON: offset 5: decimal point with no digits
diff --git a/libtests/qtest/json_parse/bad-31.json b/libtests/qtest/json_parse/bad-31.json
new file mode 100644
index 00000000..39cdd0de
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-31.json
@@ -0,0 +1 @@
+-
diff --git a/libtests/qtest/json_parse/bad-31.out b/libtests/qtest/json_parse/bad-31.out
new file mode 100644
index 00000000..344f42e8
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-31.out
@@ -0,0 +1 @@
+exception: bad-31.json: JSON: offset 2: number with no digits
diff --git a/libtests/qtest/json_parse/bad-32.json b/libtests/qtest/json_parse/bad-32.json
new file mode 100644
index 00000000..40381e26
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-32.json
@@ -0,0 +1 @@
+0123
diff --git a/libtests/qtest/json_parse/bad-32.out b/libtests/qtest/json_parse/bad-32.out
new file mode 100644
index 00000000..4372e0cf
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-32.out
@@ -0,0 +1 @@
+exception: bad-32.json: JSON: offset 5: number with leading zero
diff --git a/libtests/qtest/json_parse/bad-33.json b/libtests/qtest/json_parse/bad-33.json
new file mode 100644
index 00000000..2e7a4b45
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-33.json
@@ -0,0 +1 @@
+-0123
diff --git a/libtests/qtest/json_parse/bad-33.out b/libtests/qtest/json_parse/bad-33.out
new file mode 100644
index 00000000..ae41e48b
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-33.out
@@ -0,0 +1 @@
+exception: bad-33.json: JSON: offset 6: number with leading zero
diff --git a/libtests/qtest/json_parse/bad-34.json b/libtests/qtest/json_parse/bad-34.json
new file mode 100644
index 00000000..fdefd9af
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-34.json
@@ -0,0 +1 @@
+"a\u123 \ No newline at end of file
diff --git a/libtests/qtest/json_parse/bad-34.out b/libtests/qtest/json_parse/bad-34.out
new file mode 100644
index 00000000..f9db587a
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-34.out
@@ -0,0 +1 @@
+exception: bad-34.json: JSON: offset 3: \u must be followed by four characters
diff --git a/libtests/qtest/json_parse/bad-35.json b/libtests/qtest/json_parse/bad-35.json
new file mode 100644
index 00000000..b7bea102
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-35.json
@@ -0,0 +1 @@
+"a\u123qx"
diff --git a/libtests/qtest/json_parse/bad-35.out b/libtests/qtest/json_parse/bad-35.out
new file mode 100644
index 00000000..dabd6571
--- /dev/null
+++ b/libtests/qtest/json_parse/bad-35.out
@@ -0,0 +1 @@
+exception: bad-35.json: JSON: offset 3: \u must be followed by four hex digits
diff --git a/libtests/qtest/json_parse/good-01.json b/libtests/qtest/json_parse/good-01.json
new file mode 100644
index 00000000..3d6ce297
--- /dev/null
+++ b/libtests/qtest/json_parse/good-01.json
@@ -0,0 +1,3 @@
+{"a": "bcd", "e": [1,
+ 2, 3,4,"five", {"six": 7, "8": 9}, null, true,
+ false]}
diff --git a/libtests/qtest/json_parse/good-02.json b/libtests/qtest/json_parse/good-02.json
new file mode 100644
index 00000000..0967ef42
--- /dev/null
+++ b/libtests/qtest/json_parse/good-02.json
@@ -0,0 +1 @@
+{}
diff --git a/libtests/qtest/json_parse/good-03.json b/libtests/qtest/json_parse/good-03.json
new file mode 100644
index 00000000..fe51488c
--- /dev/null
+++ b/libtests/qtest/json_parse/good-03.json
@@ -0,0 +1 @@
+[]
diff --git a/libtests/qtest/json_parse/good-04.json b/libtests/qtest/json_parse/good-04.json
new file mode 100644
index 00000000..d6144800
--- /dev/null
+++ b/libtests/qtest/json_parse/good-04.json
@@ -0,0 +1 @@
+[[[{}], {"": {}}]]
diff --git a/libtests/qtest/json_parse/good-05.json b/libtests/qtest/json_parse/good-05.json
new file mode 100644
index 00000000..92232f69
--- /dev/null
+++ b/libtests/qtest/json_parse/good-05.json
@@ -0,0 +1 @@
+"x"
diff --git a/libtests/qtest/json_parse/good-06.json b/libtests/qtest/json_parse/good-06.json
new file mode 100644
index 00000000..190a1803
--- /dev/null
+++ b/libtests/qtest/json_parse/good-06.json
@@ -0,0 +1 @@
+123
diff --git a/libtests/qtest/json_parse/good-07.json b/libtests/qtest/json_parse/good-07.json
new file mode 100644
index 00000000..3a437cdb
--- /dev/null
+++ b/libtests/qtest/json_parse/good-07.json
@@ -0,0 +1 @@
+-123
diff --git a/libtests/qtest/json_parse/good-08.json b/libtests/qtest/json_parse/good-08.json
new file mode 100644
index 00000000..5708ac7f
--- /dev/null
+++ b/libtests/qtest/json_parse/good-08.json
@@ -0,0 +1 @@
+[1, -2, 3.4, -5.6, -9e1, 10e2, 12.3e5, 12.6e-7]
diff --git a/libtests/qtest/json_parse/good-09.json b/libtests/qtest/json_parse/good-09.json
new file mode 100644
index 00000000..91db9d20
--- /dev/null
+++ b/libtests/qtest/json_parse/good-09.json
@@ -0,0 +1 @@
+["aπb", "a\b\f\n\r\tc", "a\u03c0b\u03C0c", "\u03c0", "a\u0018b\u02acc"]
diff --git a/libtests/qtest/json_parse/save-01.json b/libtests/qtest/json_parse/save-01.json
new file mode 100644
index 00000000..2a9e3c20
--- /dev/null
+++ b/libtests/qtest/json_parse/save-01.json
@@ -0,0 +1,17 @@
+{
+ "a": "bcd",
+ "e": [
+ 1,
+ 2,
+ 3,
+ 4,
+ "five",
+ {
+ "8": 9,
+ "six": 7
+ },
+ null,
+ true,
+ false
+ ]
+}
diff --git a/libtests/qtest/json_parse/save-02.json b/libtests/qtest/json_parse/save-02.json
new file mode 100644
index 00000000..0967ef42
--- /dev/null
+++ b/libtests/qtest/json_parse/save-02.json
@@ -0,0 +1 @@
+{}
diff --git a/libtests/qtest/json_parse/save-03.json b/libtests/qtest/json_parse/save-03.json
new file mode 100644
index 00000000..fe51488c
--- /dev/null
+++ b/libtests/qtest/json_parse/save-03.json
@@ -0,0 +1 @@
+[]
diff --git a/libtests/qtest/json_parse/save-04.json b/libtests/qtest/json_parse/save-04.json
new file mode 100644
index 00000000..9286cc19
--- /dev/null
+++ b/libtests/qtest/json_parse/save-04.json
@@ -0,0 +1,10 @@
+[
+ [
+ [
+ {}
+ ],
+ {
+ "": {}
+ }
+ ]
+]
diff --git a/libtests/qtest/json_parse/save-05.json b/libtests/qtest/json_parse/save-05.json
new file mode 100644
index 00000000..92232f69
--- /dev/null
+++ b/libtests/qtest/json_parse/save-05.json
@@ -0,0 +1 @@
+"x"
diff --git a/libtests/qtest/json_parse/save-06.json b/libtests/qtest/json_parse/save-06.json
new file mode 100644
index 00000000..190a1803
--- /dev/null
+++ b/libtests/qtest/json_parse/save-06.json
@@ -0,0 +1 @@
+123
diff --git a/libtests/qtest/json_parse/save-07.json b/libtests/qtest/json_parse/save-07.json
new file mode 100644
index 00000000..3a437cdb
--- /dev/null
+++ b/libtests/qtest/json_parse/save-07.json
@@ -0,0 +1 @@
+-123
diff --git a/libtests/qtest/json_parse/save-08.json b/libtests/qtest/json_parse/save-08.json
new file mode 100644
index 00000000..30ceeba1
--- /dev/null
+++ b/libtests/qtest/json_parse/save-08.json
@@ -0,0 +1,10 @@
+[
+ 1,
+ -2,
+ 3.4,
+ -5.6,
+ -9e1,
+ 10e2,
+ 12.3e5,
+ 12.6e-7
+]
diff --git a/libtests/qtest/json_parse/save-09.json b/libtests/qtest/json_parse/save-09.json
new file mode 100644
index 00000000..a064cbac
--- /dev/null
+++ b/libtests/qtest/json_parse/save-09.json
@@ -0,0 +1,7 @@
+[
+ "aπb",
+ "a\b\f\n\r\tc",
+ "aπbπc",
+ "π",
+ "a\u0018bʬc"
+]