diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/custom/03_stdlib/34_json | 157 |
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 -- |