diff options
Diffstat (limited to 'std/encoding/csv_stringify_test.ts')
-rw-r--r-- | std/encoding/csv_stringify_test.ts | 373 |
1 files changed, 373 insertions, 0 deletions
diff --git a/std/encoding/csv_stringify_test.ts b/std/encoding/csv_stringify_test.ts new file mode 100644 index 000000000..7cad190fc --- /dev/null +++ b/std/encoding/csv_stringify_test.ts @@ -0,0 +1,373 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. + +import { assertEquals, assertThrowsAsync } from "../testing/asserts.ts"; + +import { + Column, + DataItem, + NEWLINE, + stringify, + StringifyError, + StringifyOptions, +} from "./csv_stringify.ts"; + +type StringifyTestCaseBase = { + columns: Column[]; + data: DataItem[]; + name: string; + options?: StringifyOptions; +}; + +type StringifyTestCaseError = StringifyTestCaseBase & { + errorMessage?: string; + // deno-lint-ignore no-explicit-any + throwsError: new (...args: any[]) => Error; +}; + +type StringifyTestCase = StringifyTestCaseBase & { expected: string }; + +const stringifyTestCases: (StringifyTestCase | StringifyTestCaseError)[] = [ + { + columns: ["a"], + data: [["foo"], ["bar"]], + errorMessage: 'Property accessor is not of type "number"', + name: "[CSV_stringify] Access array index using string", + throwsError: StringifyError, + }, + { + columns: [0], + data: [["foo"], ["bar"]], + errorMessage: [ + "Separator cannot include the following strings:", + ' - U+0022: Quotation mark (")', + " - U+000D U+000A: Carriage Return + Line Feed (\\r\\n)", + ].join("\n"), + name: "[CSV_stringify] Double quote in separator", + options: { separator: '"' }, + throwsError: StringifyError, + }, + { + columns: [0], + data: [["foo"], ["bar"]], + errorMessage: [ + "Separator cannot include the following strings:", + ' - U+0022: Quotation mark (")', + " - U+000D U+000A: Carriage Return + Line Feed (\\r\\n)", + ].join("\n"), + name: "[CSV_stringify] CRLF in separator", + options: { separator: "\r\n" }, + throwsError: StringifyError, + }, + { + columns: [ + { + fn: (obj) => obj.toUpperCase(), + prop: "msg", + }, + ], + data: [{ msg: { value: "foo" } }, { msg: { value: "bar" } }], + name: "[CSV_stringify] Transform function", + throwsError: TypeError, + }, + { + columns: [], + data: [], + expected: NEWLINE, + name: "[CSV_stringify] No data, no columns", + }, + { + columns: [], + data: [], + expected: ``, + name: "[CSV_stringify] No data, no columns, no headers", + options: { headers: false }, + }, + { + columns: ["a"], + data: [], + expected: `a${NEWLINE}`, + name: "[CSV_stringify] No data, columns", + }, + { + columns: ["a"], + data: [], + expected: ``, + name: "[CSV_stringify] No data, columns, no headers", + options: { headers: false }, + }, + { + columns: [], + data: [{ a: 1 }, { a: 2 }], + expected: `${NEWLINE}${NEWLINE}${NEWLINE}`, + name: "[CSV_stringify] Data, no columns", + }, + { + columns: [0, 1], + data: [["foo", "bar"], ["baz", "qux"]], + expected: `0\r1${NEWLINE}foo\rbar${NEWLINE}baz\rqux${NEWLINE}`, + name: "[CSV_stringify] Separator: CR", + options: { separator: "\r" }, + }, + { + columns: [0, 1], + data: [["foo", "bar"], ["baz", "qux"]], + expected: `0\n1${NEWLINE}foo\nbar${NEWLINE}baz\nqux${NEWLINE}`, + name: "[CSV_stringify] Separator: LF", + options: { separator: "\n" }, + }, + { + columns: [1], + data: [{ 1: 1 }, { 1: 2 }], + expected: `1${NEWLINE}1${NEWLINE}2${NEWLINE}`, + name: "[CSV_stringify] Column: number accessor, Data: object", + }, + { + columns: [{ header: "Value", prop: "value" }], + data: [{ value: "foo" }, { value: "bar" }], + expected: `foo${NEWLINE}bar${NEWLINE}`, + name: "[CSV_stringify] Explicit header value, no headers", + options: { headers: false }, + }, + { + columns: [1], + data: [["key", "foo"], ["key", "bar"]], + expected: `1${NEWLINE}foo${NEWLINE}bar${NEWLINE}`, + name: "[CSV_stringify] Column: number accessor, Data: array", + }, + { + columns: [[1]], + data: [{ 1: 1 }, { 1: 2 }], + expected: `1${NEWLINE}1${NEWLINE}2${NEWLINE}`, + name: "[CSV_stringify] Column: array number accessor, Data: object", + }, + { + columns: [[1]], + data: [["key", "foo"], ["key", "bar"]], + expected: `1${NEWLINE}foo${NEWLINE}bar${NEWLINE}`, + name: "[CSV_stringify] Column: array number accessor, Data: array", + }, + { + columns: [[1, 1]], + data: [["key", ["key", "foo"]], ["key", ["key", "bar"]]], + expected: `1${NEWLINE}foo${NEWLINE}bar${NEWLINE}`, + name: "[CSV_stringify] Column: array number accessor, Data: array", + }, + { + columns: ["value"], + data: [{ value: "foo" }, { value: "bar" }], + expected: `value${NEWLINE}foo${NEWLINE}bar${NEWLINE}`, + name: "[CSV_stringify] Column: string accessor, Data: object", + }, + { + columns: [["value"]], + data: [{ value: "foo" }, { value: "bar" }], + expected: `value${NEWLINE}foo${NEWLINE}bar${NEWLINE}`, + name: "[CSV_stringify] Column: array string accessor, Data: object", + }, + { + columns: [["msg", "value"]], + data: [{ msg: { value: "foo" } }, { msg: { value: "bar" } }], + expected: `value${NEWLINE}foo${NEWLINE}bar${NEWLINE}`, + name: "[CSV_stringify] Column: array string accessor, Data: object", + }, + { + columns: [ + { + header: "Value", + prop: ["msg", "value"], + }, + ], + data: [{ msg: { value: "foo" } }, { msg: { value: "bar" } }], + expected: `Value${NEWLINE}foo${NEWLINE}bar${NEWLINE}`, + name: "[CSV_stringify] Explicit header", + }, + { + columns: [ + { + fn: (str: string) => str.toUpperCase(), + prop: ["msg", "value"], + }, + ], + data: [{ msg: { value: "foo" } }, { msg: { value: "bar" } }], + expected: `value${NEWLINE}FOO${NEWLINE}BAR${NEWLINE}`, + name: "[CSV_stringify] Transform function 1", + }, + { + columns: [ + { + fn: (str: string) => Promise.resolve(str.toUpperCase()), + prop: ["msg", "value"], + }, + ], + data: [{ msg: { value: "foo" } }, { msg: { value: "bar" } }], + expected: `value${NEWLINE}FOO${NEWLINE}BAR${NEWLINE}`, + name: "[CSV_stringify] Transform function 1 async", + }, + { + columns: [ + { + fn: (obj: { value: string }) => obj.value, + prop: "msg", + }, + ], + data: [{ msg: { value: "foo" } }, { msg: { value: "bar" } }], + expected: `msg${NEWLINE}foo${NEWLINE}bar${NEWLINE}`, + name: "[CSV_stringify] Transform function 2", + }, + { + columns: [ + { + fn: (obj: { value: string }) => obj.value, + header: "Value", + prop: "msg", + }, + ], + data: [{ msg: { value: "foo" } }, { msg: { value: "bar" } }], + expected: `Value${NEWLINE}foo${NEWLINE}bar${NEWLINE}`, + name: "[CSV_stringify] Transform function 2, explicit header", + }, + { + columns: [0], + data: [[{ value: "foo" }], [{ value: "bar" }]], + expected: + `0${NEWLINE}"{""value"":""foo""}"${NEWLINE}"{""value"":""bar""}"${NEWLINE}`, + name: "[CSV_stringify] Targeted value: object", + }, + { + columns: [0], + data: [ + [[{ value: "foo" }, { value: "bar" }]], + [[{ value: "baz" }, { value: "qux" }]], + ], + expected: + `0${NEWLINE}"[{""value"":""foo""},{""value"":""bar""}]"${NEWLINE}"[{""value"":""baz""},{""value"":""qux""}]"${NEWLINE}`, + name: "[CSV_stringify] Targeted value: arary of objects", + }, + { + columns: [0], + data: [[["foo", "bar"]], [["baz", "qux"]]], + expected: + `0${NEWLINE}"[""foo"",""bar""]"${NEWLINE}"[""baz"",""qux""]"${NEWLINE}`, + name: "[CSV_stringify] Targeted value: array", + }, + { + columns: [0], + data: [[["foo", "bar"]], [["baz", "qux"]]], + expected: + `0${NEWLINE}"[""foo"",""bar""]"${NEWLINE}"[""baz"",""qux""]"${NEWLINE}`, + name: "[CSV_stringify] Targeted value: array, separator: tab", + options: { separator: "\t" }, + }, + { + columns: [0], + data: [[], []], + expected: `0${NEWLINE}${NEWLINE}${NEWLINE}`, + name: "[CSV_stringify] Targeted value: undefined", + }, + { + columns: [0], + data: [[null], [null]], + expected: `0${NEWLINE}${NEWLINE}${NEWLINE}`, + name: "[CSV_stringify] Targeted value: null", + }, + { + columns: [0], + data: [[0xa], [0xb]], + expected: `0${NEWLINE}10${NEWLINE}11${NEWLINE}`, + name: "[CSV_stringify] Targeted value: hex number", + }, + { + columns: [0], + data: [[BigInt("1")], [BigInt("2")]], + expected: `0${NEWLINE}1${NEWLINE}2${NEWLINE}`, + name: "[CSV_stringify] Targeted value: BigInt", + }, + { + columns: [0], + data: [[true], [false]], + expected: `0${NEWLINE}true${NEWLINE}false${NEWLINE}`, + name: "[CSV_stringify] Targeted value: boolean", + }, + { + columns: [0], + data: [["foo"], ["bar"]], + expected: `0${NEWLINE}foo${NEWLINE}bar${NEWLINE}`, + name: "[CSV_stringify] Targeted value: string", + }, + { + columns: [0], + data: [[Symbol("foo")], [Symbol("bar")]], + expected: `0${NEWLINE}Symbol(foo)${NEWLINE}Symbol(bar)${NEWLINE}`, + name: "[CSV_stringify] Targeted value: symbol", + }, + { + columns: [0], + data: [[(n: number) => n]], + expected: `0${NEWLINE}(n) => n${NEWLINE}`, + name: "[CSV_stringify] Targeted value: function", + }, + { + columns: [0], + data: [['foo"']], + expected: `0${NEWLINE}"foo"""${NEWLINE}`, + name: "[CSV_stringify] Value with double quote", + }, + { + columns: [0], + data: [["foo\r\n"]], + expected: `0${NEWLINE}"foo\r\n"${NEWLINE}`, + name: "[CSV_stringify] Value with CRLF", + }, + { + columns: [0], + data: [["foo\r"]], + expected: `0${NEWLINE}foo\r${NEWLINE}`, + name: "[CSV_stringify] Value with CR", + }, + { + columns: [0], + data: [["foo\n"]], + expected: `0${NEWLINE}foo\n${NEWLINE}`, + name: "[CSV_stringify] Value with LF", + }, + { + columns: [0], + data: [["foo,"]], + expected: `0${NEWLINE}"foo,"${NEWLINE}`, + name: "[CSV_stringify] Value with comma", + }, + { + columns: [0], + data: [["foo,"]], + expected: `0${NEWLINE}foo,${NEWLINE}`, + name: "[CSV_stringify] Value with comma, tab separator", + options: { separator: "\t" }, + }, +]; + +for (const tc of stringifyTestCases) { + if ((tc as StringifyTestCaseError).throwsError) { + const t = tc as StringifyTestCaseError; + Deno.test({ + async fn() { + await assertThrowsAsync( + async () => { + await stringify(t.data, t.columns, t.options); + }, + t.throwsError, + t.errorMessage, + ); + }, + name: t.name, + }); + } else { + const t = tc as StringifyTestCase; + Deno.test({ + async fn() { + const actual = await stringify(t.data, t.columns, t.options); + assertEquals(actual, t.expected); + }, + name: t.name, + }); + } +} |