summaryrefslogtreecommitdiff
path: root/std/encoding/csv_test.ts
diff options
context:
space:
mode:
authorCasper Beyer <caspervonb@pm.me>2021-02-02 19:05:46 +0800
committerGitHub <noreply@github.com>2021-02-02 12:05:46 +0100
commit6abf126c2a7a451cded8c6b5e6ddf1b69c84055d (patch)
treefd94c013a19fcb38954844085821ec1601c20e18 /std/encoding/csv_test.ts
parenta2b5d44f1aa9d64f448a2a3cc2001272e2f60b98 (diff)
chore: remove std directory (#9361)
This removes the std folder from the tree. Various parts of the tests are pretty tightly dependent on std (47 direct imports and 75 indirect imports, not counting the cli tests that use them as fixtures) so I've added std as a submodule for now.
Diffstat (limited to 'std/encoding/csv_test.ts')
-rw-r--r--std/encoding/csv_test.ts653
1 files changed, 0 insertions, 653 deletions
diff --git a/std/encoding/csv_test.ts b/std/encoding/csv_test.ts
deleted file mode 100644
index c3257808f..000000000
--- a/std/encoding/csv_test.ts
+++ /dev/null
@@ -1,653 +0,0 @@
-// Test ported from Golang
-// https://github.com/golang/go/blob/2cc15b1/src/encoding/csv/reader_test.go
-// Copyright 2011 The Go Authors. All rights reserved. BSD license.
-// https://github.com/golang/go/blob/master/LICENSE
-// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
-
-import { assertEquals, assertThrowsAsync } from "../testing/asserts.ts";
-import {
- ERR_BARE_QUOTE,
- ERR_FIELD_COUNT,
- ERR_INVALID_DELIM,
- ERR_QUOTE,
- parse,
- ParseError,
- readMatrix,
-} from "./csv.ts";
-import { StringReader } from "../io/readers.ts";
-import { BufReader } from "../io/bufio.ts";
-
-// Test cases for `readMatrix()`
-const testCases = [
- {
- Name: "Simple",
- Input: "a,b,c\n",
- Output: [["a", "b", "c"]],
- },
- {
- Name: "CRLF",
- Input: "a,b\r\nc,d\r\n",
- Output: [
- ["a", "b"],
- ["c", "d"],
- ],
- },
- {
- Name: "BareCR",
- Input: "a,b\rc,d\r\n",
- Output: [["a", "b\rc", "d"]],
- },
- {
- Name: "RFC4180test",
- Input: `#field1,field2,field3
-"aaa","bbb","ccc"
-"a,a","bbb","ccc"
-zzz,yyy,xxx`,
- UseFieldsPerRecord: true,
- FieldsPerRecord: 0,
- Output: [
- ["#field1", "field2", "field3"],
- ["aaa", "bbb", "ccc"],
- ["a,a", `bbb`, "ccc"],
- ["zzz", "yyy", "xxx"],
- ],
- },
- {
- Name: "NoEOLTest",
- Input: "a,b,c",
- Output: [["a", "b", "c"]],
- },
- {
- Name: "Semicolon",
- Input: "a;b;c\n",
- Output: [["a", "b", "c"]],
- Separator: ";",
- },
- {
- Name: "MultiLine",
- Input: `"two
-line","one line","three
-line
-field"`,
- Output: [["two\nline", "one line", "three\nline\nfield"]],
- },
- {
- Name: "BlankLine",
- Input: "a,b,c\n\nd,e,f\n\n",
- Output: [
- ["a", "b", "c"],
- ["d", "e", "f"],
- ],
- },
- {
- Name: "BlankLineFieldCount",
- Input: "a,b,c\n\nd,e,f\n\n",
- Output: [
- ["a", "b", "c"],
- ["d", "e", "f"],
- ],
- UseFieldsPerRecord: true,
- FieldsPerRecord: 0,
- },
- {
- Name: "TrimSpace",
- Input: " a, b, c\n",
- Output: [["a", "b", "c"]],
- TrimLeadingSpace: true,
- },
- {
- Name: "LeadingSpace",
- Input: " a, b, c\n",
- Output: [[" a", " b", " c"]],
- },
- {
- Name: "Comment",
- Input: "#1,2,3\na,b,c\n#comment",
- Output: [["a", "b", "c"]],
- Comment: "#",
- },
- {
- Name: "NoComment",
- Input: "#1,2,3\na,b,c",
- Output: [
- ["#1", "2", "3"],
- ["a", "b", "c"],
- ],
- },
- {
- Name: "LazyQuotes",
- Input: `a "word","1"2",a","b`,
- Output: [[`a "word"`, `1"2`, `a"`, `b`]],
- LazyQuotes: true,
- },
- {
- Name: "BareQuotes",
- Input: `a "word","1"2",a"`,
- Output: [[`a "word"`, `1"2`, `a"`]],
- LazyQuotes: true,
- },
- {
- Name: "BareDoubleQuotes",
- Input: `a""b,c`,
- Output: [[`a""b`, `c`]],
- LazyQuotes: true,
- },
- {
- Name: "BadDoubleQuotes",
- Input: `a""b,c`,
- Error: new ParseError(1, 1, 1, ERR_BARE_QUOTE),
- },
- {
- Name: "TrimQuote",
- Input: ` "a"," b",c`,
- Output: [["a", " b", "c"]],
- TrimLeadingSpace: true,
- },
- {
- Name: "BadBareQuote",
- Input: `a "word","b"`,
- Error: new ParseError(1, 1, 2, ERR_BARE_QUOTE),
- },
- {
- Name: "BadTrailingQuote",
- Input: `"a word",b"`,
- Error: new ParseError(1, 1, 10, ERR_BARE_QUOTE),
- },
- {
- Name: "ExtraneousQuote",
- Input: `"a "word","b"`,
- Error: new ParseError(1, 1, 3, ERR_QUOTE),
- },
- {
- Name: "BadFieldCount",
- Input: "a,b,c\nd,e",
- Error: new ParseError(2, 2, null, ERR_FIELD_COUNT),
- UseFieldsPerRecord: true,
- FieldsPerRecord: 0,
- },
- {
- Name: "BadFieldCount1",
- Input: `a,b,c`,
- UseFieldsPerRecord: true,
- FieldsPerRecord: 2,
- Error: new ParseError(1, 1, null, ERR_FIELD_COUNT),
- },
- {
- Name: "FieldCount",
- Input: "a,b,c\nd,e",
- Output: [
- ["a", "b", "c"],
- ["d", "e"],
- ],
- },
- {
- Name: "TrailingCommaEOF",
- Input: "a,b,c,",
- Output: [["a", "b", "c", ""]],
- },
- {
- Name: "TrailingCommaEOL",
- Input: "a,b,c,\n",
- Output: [["a", "b", "c", ""]],
- },
- {
- Name: "TrailingCommaSpaceEOF",
- Input: "a,b,c, ",
- Output: [["a", "b", "c", ""]],
- TrimLeadingSpace: true,
- },
- {
- Name: "TrailingCommaSpaceEOL",
- Input: "a,b,c, \n",
- Output: [["a", "b", "c", ""]],
- TrimLeadingSpace: true,
- },
- {
- Name: "TrailingCommaLine3",
- Input: "a,b,c\nd,e,f\ng,hi,",
- Output: [
- ["a", "b", "c"],
- ["d", "e", "f"],
- ["g", "hi", ""],
- ],
- TrimLeadingSpace: true,
- },
- {
- Name: "NotTrailingComma3",
- Input: "a,b,c, \n",
- Output: [["a", "b", "c", " "]],
- },
- {
- Name: "CommaFieldTest",
- Input: `x,y,z,w
-x,y,z,
-x,y,,
-x,,,
-,,,
-"x","y","z","w"
-"x","y","z",""
-"x","y","",""
-"x","","",""
-"","","",""
-`,
- Output: [
- ["x", "y", "z", "w"],
- ["x", "y", "z", ""],
- ["x", "y", "", ""],
- ["x", "", "", ""],
- ["", "", "", ""],
- ["x", "y", "z", "w"],
- ["x", "y", "z", ""],
- ["x", "y", "", ""],
- ["x", "", "", ""],
- ["", "", "", ""],
- ],
- },
- {
- Name: "TrailingCommaIneffective1",
- Input: "a,b,\nc,d,e",
- Output: [
- ["a", "b", ""],
- ["c", "d", "e"],
- ],
- TrimLeadingSpace: true,
- },
- {
- Name: "ReadAllReuseRecord",
- Input: "a,b\nc,d",
- Output: [
- ["a", "b"],
- ["c", "d"],
- ],
- ReuseRecord: true,
- },
- {
- Name: "StartLine1", // Issue 19019
- Input: 'a,"b\nc"d,e',
- Error: new ParseError(1, 2, 1, ERR_QUOTE),
- },
- {
- Name: "StartLine2",
- Input: 'a,b\n\"d\n\n,e',
- Error: new ParseError(2, 5, 0, ERR_QUOTE),
- },
- {
- Name: "CRLFInQuotedField", // Issue 21201
- Input: 'A,"Hello\r\nHi",B\r\n',
- Output: [["A", "Hello\nHi", "B"]],
- },
- {
- Name: "BinaryBlobField", // Issue 19410
- Input: "x09\x41\xb4\x1c,aktau",
- Output: [["x09A\xb4\x1c", "aktau"]],
- },
- {
- Name: "TrailingCR",
- Input: "field1,field2\r",
- Output: [["field1", "field2"]],
- },
- {
- Name: "QuotedTrailingCR",
- Input: '"field"\r',
- Output: [["field"]],
- },
- {
- Name: "QuotedTrailingCRCR",
- Input: '"field"\r\r',
- Error: new ParseError(1, 1, 6, ERR_QUOTE),
- },
- {
- Name: "FieldCR",
- Input: "field\rfield\r",
- Output: [["field\rfield"]],
- },
- {
- Name: "FieldCRCR",
- Input: "field\r\rfield\r\r",
- Output: [["field\r\rfield\r"]],
- },
- {
- Name: "FieldCRCRLF",
- Input: "field\r\r\nfield\r\r\n",
- Output: [["field\r"], ["field\r"]],
- },
- {
- Name: "FieldCRCRLFCR",
- Input: "field\r\r\n\rfield\r\r\n\r",
- Output: [["field\r"], ["\rfield\r"]],
- },
- {
- Name: "FieldCRCRLFCRCR",
- Input: "field\r\r\n\r\rfield\r\r\n\r\r",
- Output: [["field\r"], ["\r\rfield\r"], ["\r"]],
- },
- {
- Name: "MultiFieldCRCRLFCRCR",
- Input: "field1,field2\r\r\n\r\rfield1,field2\r\r\n\r\r,",
- Output: [
- ["field1", "field2\r"],
- ["\r\rfield1", "field2\r"],
- ["\r\r", ""],
- ],
- },
- {
- Name: "NonASCIICommaAndComment",
- Input: "a£b,c£ \td,e\n€ comment\n",
- Output: [["a", "b,c", "d,e"]],
- TrimLeadingSpace: true,
- Separator: "£",
- Comment: "€",
- },
- {
- Name: "NonASCIICommaAndCommentWithQuotes",
- Input: 'a€" b,"€ c\nλ comment\n',
- Output: [["a", " b,", " c"]],
- Separator: "€",
- Comment: "λ",
- },
- {
- // λ and θ start with the same byte.
- // This tests that the parser doesn't confuse such characters.
- Name: "NonASCIICommaConfusion",
- Input: '"abθcd"λefθgh',
- Output: [["abθcd", "efθgh"]],
- Separator: "λ",
- Comment: "€",
- },
- {
- Name: "NonASCIICommentConfusion",
- Input: "λ\nλ\nθ\nλ\n",
- Output: [["λ"], ["λ"], ["λ"]],
- Comment: "θ",
- },
- {
- Name: "QuotedFieldMultipleLF",
- Input: '"\n\n\n\n"',
- Output: [["\n\n\n\n"]],
- },
- {
- Name: "MultipleCRLF",
- Input: "\r\n\r\n\r\n\r\n",
- Output: [],
- },
- /**
- * The implementation may read each line in several chunks if
- * it doesn't fit entirely.
- * in the read buffer, so we should test the code to handle that condition.
- */
- {
- Name: "HugeLines",
- Input: "#ignore\n".repeat(10000) + "@".repeat(5000) + "," +
- "*".repeat(5000),
- Output: [["@".repeat(5000), "*".repeat(5000)]],
- Comment: "#",
- },
- {
- Name: "QuoteWithTrailingCRLF",
- Input: '"foo"bar"\r\n',
- Error: new ParseError(1, 1, 4, ERR_QUOTE),
- },
- {
- Name: "LazyQuoteWithTrailingCRLF",
- Input: '"foo"bar"\r\n',
- Output: [[`foo"bar`]],
- LazyQuotes: true,
- },
- {
- Name: "DoubleQuoteWithTrailingCRLF",
- Input: '"foo""bar"\r\n',
- Output: [[`foo"bar`]],
- },
- {
- Name: "EvenQuotes",
- Input: `""""""""`,
- Output: [[`"""`]],
- },
- {
- Name: "OddQuotes",
- Input: `"""""""`,
- Error: new ParseError(1, 1, 7, ERR_QUOTE),
- },
- {
- Name: "LazyOddQuotes",
- Input: `"""""""`,
- Output: [[`"""`]],
- LazyQuotes: true,
- },
- {
- Name: "BadComma1",
- Separator: "\n",
- Error: new Error(ERR_INVALID_DELIM),
- },
- {
- Name: "BadComma2",
- Separator: "\r",
- Error: new Error(ERR_INVALID_DELIM),
- },
- {
- Name: "BadComma3",
- Separator: '"',
- Error: new Error(ERR_INVALID_DELIM),
- },
- {
- Name: "BadComment1",
- Comment: "\n",
- Error: new Error(ERR_INVALID_DELIM),
- },
- {
- Name: "BadComment2",
- Comment: "\r",
- Error: new Error(ERR_INVALID_DELIM),
- },
- {
- Name: "BadCommaComment",
- Separator: "X",
- Comment: "X",
- Error: new Error(ERR_INVALID_DELIM),
- },
-];
-for (const t of testCases) {
- Deno.test({
- name: `[CSV] ${t.Name}`,
- async fn(): Promise<void> {
- let separator = ",";
- let comment: string | undefined;
- let fieldsPerRec: number | undefined;
- let trim = false;
- let lazyquote = false;
- if (t.Separator) {
- separator = t.Separator;
- }
- if (t.Comment) {
- comment = t.Comment;
- }
- if (t.TrimLeadingSpace) {
- trim = true;
- }
- if (t.UseFieldsPerRecord) {
- fieldsPerRec = t.FieldsPerRecord;
- }
- if (t.LazyQuotes) {
- lazyquote = t.LazyQuotes;
- }
- let actual;
- if (t.Error) {
- const err = await assertThrowsAsync(async () => {
- await readMatrix(
- new BufReader(new StringReader(t.Input ?? "")),
- {
- separator,
- comment: comment,
- trimLeadingSpace: trim,
- fieldsPerRecord: fieldsPerRec,
- lazyQuotes: lazyquote,
- },
- );
- });
-
- assertEquals(err, t.Error);
- } else {
- actual = await readMatrix(
- new BufReader(new StringReader(t.Input ?? "")),
- {
- separator,
- comment: comment,
- trimLeadingSpace: trim,
- fieldsPerRecord: fieldsPerRec,
- lazyQuotes: lazyquote,
- },
- );
- const expected = t.Output;
- assertEquals(actual, expected);
- }
- },
- });
-}
-
-const parseTestCases = [
- {
- name: "simple",
- in: "a,b,c",
- skipFirstRow: false,
- result: [["a", "b", "c"]],
- },
- {
- name: "simple Bufreader",
- in: new BufReader(new StringReader("a,b,c")),
- skipFirstRow: false,
- result: [["a", "b", "c"]],
- },
- {
- name: "multiline",
- in: "a,b,c\ne,f,g\n",
- skipFirstRow: false,
- result: [
- ["a", "b", "c"],
- ["e", "f", "g"],
- ],
- },
- {
- name: "header mapping boolean",
- in: "a,b,c\ne,f,g\n",
- skipFirstRow: true,
- result: [{ a: "e", b: "f", c: "g" }],
- },
- {
- name: "header mapping array",
- in: "a,b,c\ne,f,g\n",
- columns: ["this", "is", "sparta"],
- result: [
- { this: "a", is: "b", sparta: "c" },
- { this: "e", is: "f", sparta: "g" },
- ],
- },
- {
- name: "header mapping object",
- in: "a,b,c\ne,f,g\n",
- columns: [{ name: "this" }, { name: "is" }, { name: "sparta" }],
- result: [
- { this: "a", is: "b", sparta: "c" },
- { this: "e", is: "f", sparta: "g" },
- ],
- },
- {
- name: "header mapping parse entry",
- in: "a,b,c\ne,f,g\n",
- columns: [
- {
- name: "this",
- parse: (e: string): string => {
- return `b${e}$$`;
- },
- },
- {
- name: "is",
- parse: (e: string): number => {
- return e.length;
- },
- },
- {
- name: "sparta",
- parse: (e: string): unknown => {
- return { bim: `boom-${e}` };
- },
- },
- ],
- result: [
- { this: "ba$$", is: 1, sparta: { bim: `boom-c` } },
- { this: "be$$", is: 1, sparta: { bim: `boom-g` } },
- ],
- },
- {
- name: "multiline parse",
- in: "a,b,c\ne,f,g\n",
- parse: (e: string[]): unknown => {
- return { super: e[0], street: e[1], fighter: e[2] };
- },
- skipFirstRow: false,
- result: [
- { super: "a", street: "b", fighter: "c" },
- { super: "e", street: "f", fighter: "g" },
- ],
- },
- {
- name: "header mapping object parseline",
- in: "a,b,c\ne,f,g\n",
- columns: [{ name: "this" }, { name: "is" }, { name: "sparta" }],
- parse: (e: Record<string, unknown>): unknown => {
- return { super: e.this, street: e.is, fighter: e.sparta };
- },
- result: [
- { super: "a", street: "b", fighter: "c" },
- { super: "e", street: "f", fighter: "g" },
- ],
- },
- {
- name: "provides both opts.skipFirstRow and opts.columns",
- in: "a,b,1\nc,d,2\ne,f,3",
- skipFirstRow: true,
- columns: [
- { name: "foo" },
- { name: "bar" },
- { name: "baz", parse: (e: string) => Number(e) },
- ],
- result: [
- { foo: "c", bar: "d", baz: 2 },
- { foo: "e", bar: "f", baz: 3 },
- ],
- },
-];
-
-for (const testCase of parseTestCases) {
- Deno.test({
- name: `[CSV] Parse ${testCase.name}`,
- async fn(): Promise<void> {
- const r = await parse(testCase.in, {
- skipFirstRow: testCase.skipFirstRow,
- columns: testCase.columns,
- parse: testCase.parse as (input: unknown) => unknown,
- });
- assertEquals(r, testCase.result);
- },
- });
-}
-
-Deno.test({
- name: "[CSV] ParseError.message",
- fn(): void {
- assertEquals(
- new ParseError(2, 2, null, ERR_FIELD_COUNT).message,
- `record on line 2: ${ERR_FIELD_COUNT}`,
- );
-
- assertEquals(
- new ParseError(1, 2, 1, ERR_QUOTE).message,
- `record on line 1; parse error on line 2, column 1: ${ERR_QUOTE}`,
- );
-
- assertEquals(
- new ParseError(1, 1, 7, ERR_QUOTE).message,
- `parse error on line 1, column 7: ${ERR_QUOTE}`,
- );
- },
-});