std/json/concatenated_json_parse_stream_test.ts
2024-06-25 16:35:00 +09:00

357 lines
8.6 KiB
TypeScript

// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import { assertEquals } from "@std/assert";
import { ConcatenatedJsonParseStream } from "./concatenated_json_parse_stream.ts";
import { assertInvalidParse, assertValidParse } from "./_test_utils.ts";
Deno.test({
name: "ConcatenatedJsonParseStream",
async fn() {
await assertValidParse(
ConcatenatedJsonParseStream,
['{"foo": "bar"}'],
[{ foo: "bar" }],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['{"foo": "bar"} '],
[{ foo: "bar" }],
);
await assertValidParse(
ConcatenatedJsonParseStream,
[' {"foo": "bar"}'],
[{ foo: "bar" }],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['[{"foo": "bar"}]'],
[[{ foo: "bar" }]],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['{"foo": "bar"}{"foo": "bar"}'],
[{ foo: "bar" }, { foo: "bar" }],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['{"foo": "bar"} {"foo": "bar"}'],
[{ foo: "bar" }, { foo: "bar" }],
);
},
});
Deno.test({
name: "ConcatenatedJsonParseStream handles primitive",
async fn() {
await assertValidParse(
ConcatenatedJsonParseStream,
["0"],
[0],
);
await assertValidParse(
ConcatenatedJsonParseStream,
["100"],
[100],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['100 200"foo"'],
[100, 200, "foo"],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['100 200{"foo": "bar"}'],
[100, 200, { foo: "bar" }],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['100 200["foo"]'],
[100, 200, ["foo"]],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['"foo"'],
["foo"],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['"foo""bar"{"foo": "bar"}'],
["foo", "bar", { foo: "bar" }],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['"foo""bar"["foo"]'],
["foo", "bar", ["foo"]],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['"foo""bar"0'],
["foo", "bar", 0],
);
await assertValidParse(
ConcatenatedJsonParseStream,
["null"],
[null],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['null null{"foo": "bar"}'],
[null, null, { foo: "bar" }],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['null null["foo"]'],
[null, null, ["foo"]],
);
await assertValidParse(
ConcatenatedJsonParseStream,
["null null 0"],
[null, null, 0],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['null null"foo"'],
[null, null, "foo"],
);
await assertValidParse(
ConcatenatedJsonParseStream,
["nullnull"],
[null, null],
);
await assertValidParse(
ConcatenatedJsonParseStream,
["nullnull0"],
[null, null, 0],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['nullnull"foo"'],
[null, null, "foo"],
);
await assertValidParse(
ConcatenatedJsonParseStream,
["true"],
[true],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['true true{"foo": "bar"}'],
[true, true, { foo: "bar" }],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['true true["foo"]'],
[true, true, ["foo"]],
);
await assertValidParse(
ConcatenatedJsonParseStream,
["true true 0"],
[true, true, 0],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['true true"foo"'],
[true, true, "foo"],
);
await assertValidParse(
ConcatenatedJsonParseStream,
["truetrue"],
[true, true],
);
await assertValidParse(
ConcatenatedJsonParseStream,
["truetrue0"],
[true, true, 0],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['truetrue"foo"'],
[true, true, "foo"],
);
await assertValidParse(
ConcatenatedJsonParseStream,
["false"],
[false],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['false false{"foo": "bar"}'],
[false, false, { foo: "bar" }],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['false false["foo"]'],
[false, false, ["foo"]],
);
await assertValidParse(
ConcatenatedJsonParseStream,
["false false 0"],
[false, false, 0],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['false false"foo"'],
[false, false, "foo"],
);
await assertValidParse(
ConcatenatedJsonParseStream,
["falsefalse"],
[false, false],
);
await assertValidParse(
ConcatenatedJsonParseStream,
["falsefalse0"],
[false, false, 0],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['falsefalse"foo"'],
[false, false, "foo"],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['nullfalsetrue0true"foo"falsenullnull'],
[null, false, true, 0, true, "foo", false, null, null],
);
},
});
Deno.test({
name: "ConcatenatedJsonParseStream handles chunk",
async fn() {
await assertValidParse(
ConcatenatedJsonParseStream,
["", '{"foo": "bar"}'],
[{ foo: "bar" }],
);
await assertValidParse(
ConcatenatedJsonParseStream,
["{", '"foo": "bar"}'],
[{ foo: "bar" }],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['{"foo": "b', 'ar"}'],
[{ foo: "bar" }],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['{"foo": "bar"', "}"],
[{ foo: "bar" }],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['{"foo": "bar"}', ""],
[{ foo: "bar" }],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['{"foo": "bar"}', '{"foo": "bar"}'],
[{ foo: "bar" }, { foo: "bar" }],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['{"foo": "bar"', '}{"foo": "bar"}'],
[{ foo: "bar" }, { foo: "bar" }],
);
await assertValidParse(
ConcatenatedJsonParseStream,
['{"foo": "bar"}{', '"foo": "bar"}'],
[{ foo: "bar" }, { foo: "bar" }],
);
await assertValidParse(
ConcatenatedJsonParseStream,
["tr", 'ue{"foo": "bar"}'],
[true, { foo: "bar" }],
);
// Invalid primitive which share some leading characters with the valid primitive
await assertInvalidParse(
ConcatenatedJsonParseStream,
["truu"],
SyntaxError,
`Unexpected token 'u', \"truu\" is not valid JSON (parsing: 'truu')`,
);
},
});
Deno.test({
name: "ConcatenatedJsonParseStream handles surrogate pair",
async fn() {
await assertValidParse(
ConcatenatedJsonParseStream,
['{"foo": "👪"}{"foo": "👪"}'],
[{ foo: "👪" }, { foo: "👪" }],
);
},
});
Deno.test({
name: "ConcatenatedJsonParseStream handles symbol between double quotes",
async fn() {
await assertValidParse(
ConcatenatedJsonParseStream,
['"[], {}"'],
["[], {}"],
);
},
});
Deno.test({
name: "ConcatenatedJsonParseStream handles primitives in containers",
async fn() {
await assertValidParse(
ConcatenatedJsonParseStream,
["[ true ]"],
[[true]],
);
},
});
Deno.test({
name: "ConcatenatedJsonParseStream handles halfway chunk",
async fn() {
await assertInvalidParse(
ConcatenatedJsonParseStream,
['{"foo": "bar"} {"foo": '],
SyntaxError,
`Unexpected end of JSON input (parsing: ' {"foo": ')`,
);
},
});
Deno.test({
name: "ConcatenatedJsonParseStream truncates error message",
async fn() {
await assertInvalidParse(
ConcatenatedJsonParseStream,
[`{${"foo".repeat(100)}}`],
SyntaxError,
`Expected property name or '}' in JSON at position 1 (line 1 column 2) (parsing: '{foofoofoofoofoofoofoofoofoofo...')`,
);
},
});
Deno.test({
// Read the test data file
name: "parse() handles concatenated-json testdata",
async fn() {
const url = "./testdata/test.concatenated-json";
const { body } = await fetch(new URL(url, import.meta.url).toString());
const readable = body!
.pipeThrough(new TextDecoderStream())
.pipeThrough(new ConcatenatedJsonParseStream());
const result = await Array.fromAsync(readable);
assertEquals(result, [
{ "hello": "world" },
["👋", "👋", "👋"],
{ "deno": "🦕" },
]);
},
});