UNPKG

json-stream-es

Version:

A streaming JSON parser/stringifier using web streams.

124 lines (111 loc) 3.9 kB
import { expect, test } from "vitest"; import { stringifyJsonStream, parseJsonStream, parseNestedJsonStream, parseNestedJsonStreamWithPaths, parseJsonStreamWithPaths } from "../convenience"; import { arrayStream, objectStream } from "../json-serializer"; import { streamToArray, streamToIterable, streamToString, stringToStream } from "../utils"; import type { JsonPath } from "../json-path-detector"; const testObject = { apples: { results: ["apple1", "apple2"] }, cherries: { results: { "1": "cherry1", "2": "cherry2" } } }; test.each([ { space: undefined, description: "no indentation" }, { space: "\t", description: "tab indentation" }, { space: 4, description: "4 spaces indentation" } ])("stringifyJsonStream ($description)", async ({ space }) => { const stream = stringifyJsonStream({ apples: { results: arrayStream(testObject.apples.results) }, cherries: { results: objectStream(Object.entries(testObject.cherries.results)) } }, space); expect(await streamToString(stream)).toBe(JSON.stringify(testObject, undefined, space)); }); test("parseJsonStream", async () => { const stream = stringToStream(JSON.stringify(testObject)) .pipeThrough(parseJsonStream([["apples", "cherries"], "results"])); expect(await streamToArray(stream)).toEqual(["apple1", "apple2", "cherry1", "cherry2"]); }); test("parseJsonStream fails for multiple documents", async () => { const stream = stringToStream(`"value1"\n"value2"`) .pipeThrough(parseJsonStream([])); await expect(async () => await streamToArray(stream)).rejects.toThrowError("Unexpected character"); }); test("parseJsonStream multi", async () => { const documents = [ "value1", 2, { test3: "value3" }, ["value4"] ]; const stream = stringToStream(documents.map((v) => `\x1e${JSON.stringify(v)}`).join("\n")) .pipeThrough(parseJsonStream(undefined, { multi: true })); expect(await streamToArray(stream)).toEqual(documents); }); test("parseJsonStream multi no values", async () => { const stream = stringToStream("") .pipeThrough(parseJsonStream(undefined, { multi: true })); expect(await streamToArray(stream)).toEqual([]); }); test("parseJsonStreamWithPaths", async () => { const stream = stringToStream(JSON.stringify(testObject)) .pipeThrough(parseJsonStreamWithPaths([["apples", "cherries"], "results"])); expect(await streamToArray(stream)).toEqual([ { value: "apple1", path: ["apples", "results", 0] }, { value: "apple2", path: ["apples", "results", 1] }, { value: "cherry1", path: ["cherries", "results", "1"] }, { value: "cherry2", path: ["cherries", "results", "2"] } ]); }); test("parseNestedJsonStream", async () => { const stream = stringToStream(JSON.stringify(testObject)) .pipeThrough(parseNestedJsonStream([["apples", "cherries"], "results"])); let results: Array<{ path: JsonPath; chunks: any[] }> = []; for await (const subStream of streamToIterable(stream)) { results.push({ path: subStream.path, chunks: await streamToArray(subStream) }); } expect(results).toEqual([ { path: ["apples", "results"], chunks: ["apple1", "apple2"] }, { path: ["cherries", "results"], chunks: ["cherry1", "cherry2"] } ]); }); test("parseNestedJsonStreamWithPaths", async () => { const stream = stringToStream(JSON.stringify(testObject)) .pipeThrough(parseNestedJsonStreamWithPaths([["apples", "cherries"], "results"])); let results: Array<{ path: JsonPath; chunks: any[] }> = []; for await (const subStream of streamToIterable(stream)) { results.push({ path: subStream.path, chunks: await streamToArray(subStream) }); } expect(results).toEqual([ { path: ["apples", "results"], chunks: [ { value: "apple1", path: [0] }, { value: "apple2", path: [1] } ] }, { path: ["cherries", "results"], chunks: [ { value: "cherry1", path: ["1"] }, { value: "cherry2", path: ["2"] } ] } ]); });