summaryrefslogtreecommitdiffhomepage
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/custom/03_stdlib/34_json157
1 files changed, 156 insertions, 1 deletions
diff --git a/tests/custom/03_stdlib/34_json b/tests/custom/03_stdlib/34_json
index ba8ad9f..c30d6d0 100644
--- a/tests/custom/03_stdlib/34_json
+++ b/tests/custom/03_stdlib/34_json
@@ -49,7 +49,7 @@ Passing a non-string value throws an exception.
-- End --
-- Expect stderr --
-Type error: Passed value is not a string
+Type error: Passed value is neither a string nor an object
In line 2, byte 11:
` json(true);`
@@ -108,3 +108,158 @@ In line 2, byte 28:
-- End --
+
+
+Additionally, `json()` accepts objects implementing a read method as input.
+During JSON parsing, the read method is repeatedly invoked with a buffer size
+hint as sole argument. The return value of the read method is converted to a
+string if needed and passed on to the JSON parser. A `null` or an empty string
+return value is treated as EOF, ending the parse process.
+
+-- Testcase --
+{%
+ let fs = require("fs");
+
+ // parse JSON from open file handle
+ printf("%.J\n",
+ json(fs.open("files/test.json"))
+ );
+%}
+-- End --
+
+-- Expect stdout --
+{
+ "hello": "world"
+}
+-- End --
+
+-- File test.json --
+{"hello":"world"}
+-- End --
+
+
+The `json()` function is able to parse JSON from any object providing a `read()`
+method that incrementally yields JSON source data.
+
+-- Testcase --
+{%
+ let parts = [
+ '{"some"',
+ ':',
+ '"object"',
+ ', ',
+ '"etc."',
+ ':',
+ !0, // this is stringified to "true"
+ '}'
+ ];
+
+ let producer = {
+ read: function(size) {
+ return shift(parts);
+ }
+ };
+
+ // parse JSON from producer object
+ printf("%.J\n",
+ json(producer)
+ );
+%}
+-- End --
+
+-- Expect stdout --
+{
+ "some": "object",
+ "etc.": true
+}
+-- End --
+
+
+Passing objects or resources not providing a `read()` method yields an exception.
+
+-- Testcase --
+{%
+ json({});
+%}
+-- End --
+
+-- Expect stderr --
+Type error: Input object does not implement read() method
+In line 2, byte 9:
+
+ ` json({});`
+ Near here -^
+
+
+-- End --
+
+
+Exceptions triggered by the `read()` method are properly forwarded.
+
+-- Testcase --
+{%
+ json({
+ read: function() {
+ die("Exception in read()");
+ }
+ });
+%}
+-- End --
+
+-- Expect stderr --
+Exception in read()
+In [anonymous function](), line 4, byte 29:
+ called from function json ([C])
+ called from anonymous function ([stdin]:6:3)
+
+ ` die("Exception in read()");`
+ Near here ---------------------------^
+
+
+-- End --
+
+
+EOF stops parsing and does not lead to further `read()` invocations.
+
+-- Testcase --
+{%
+ let parts = [
+ '["some",',
+ '"JSON array",',
+ 'true,false,1,2,3',
+ ']',
+ '', // empty string treated as EOF
+ '{"some":', // this is not reached in the first pass
+ '"object"}',
+ null, // null treated as EOF
+ '"test ', // this is not reached in the second pass
+ 'value"'
+ ];
+
+ let producer = { read: () => shift(parts) };
+
+ printf("%.J\n", [
+ json(producer),
+ json(producer),
+ json(producer)
+ ]);
+%}
+-- End --
+
+-- Expect stdout --
+[
+ [
+ "some",
+ "JSON array",
+ true,
+ false,
+ 1,
+ 2,
+ 3
+ ],
+ {
+ "some": "object"
+ },
+ "test value"
+]
+-- End --