Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/io/csv.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,9 @@ export function parse(csv, options, reviver = v => v) {
}
}

// flush the last value
if (ctx.entry.length !== 0) {
// flush the last value. In a one-column row, the pending value is still in
// ctx.value with ctx.entry empty, so checking the entry alone drops it.
if (state !== 0 || ctx.entry.length !== 0) {
valueEnd(ctx);
entryEnd(ctx);
}
Expand Down
5 changes: 3 additions & 2 deletions src/io/files.js
Original file line number Diff line number Diff line change
Expand Up @@ -511,9 +511,10 @@ function files(p5, fn) {
});

if (header) {
ret.columns = data.shift();
ret.columns = data.shift() || [];
} else {
ret.columns = Array(data[0].length).fill(null);
// An empty file parses to no rows at all.
ret.columns = Array(data.length ? data[0].length : 0).fill(null);
}

data.forEach(line => {
Expand Down
Empty file added test/unit/assets/csv_empty.csv
Empty file.
3 changes: 3 additions & 0 deletions test/unit/assets/csv_one_column.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
alice
bob
carol
1 change: 1 addition & 0 deletions test/unit/assets/csv_one_value.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
42
34 changes: 34 additions & 0 deletions test/unit/io/csv.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { parse } from '../../../src/io/csv';

suite('csv parse', function () {
test('keeps the last row of a one-column file without a trailing newline', function () {
expect(parse('a\nb')).toEqual([['a'], ['b']]);
});

test('parses a single value as one row', function () {
expect(parse('only')).toEqual([['only']]);
expect(parse('42')).toEqual([['42']]);
});

test('parses a single quoted value as one row', function () {
expect(parse('"only"')).toEqual([['only']]);
});

test('keeps a row after an empty line', function () {
expect(parse('a\n\nb')).toEqual([['a'], [''], ['b']]);
});

test('does not add a row for a trailing newline', function () {
expect(parse('a\n')).toEqual([['a']]);
expect(parse('x,y\n1,2\n')).toEqual([['x', 'y'], ['1', '2']]);
});

test('keeps multi-column rows and trailing empty fields', function () {
expect(parse('x,y\n1,2')).toEqual([['x', 'y'], ['1', '2']]);
expect(parse('x,')).toEqual([['x', '']]);
});

test('returns no rows for an empty string', function () {
expect(parse('')).toEqual([]);
});
});
17 changes: 17 additions & 0 deletions test/unit/io/loadTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,23 @@ suite('loadTable', function () {
assert.strictEqual(table.getRow(1).getNum(1), 31);
});

test('keeps the last row of a one-column file without a trailing newline', async () => {
const table = await mockP5Prototype.loadTable('/test/unit/assets/csv_one_column.csv');
assert.equal(table.getRowCount(), 3);
assert.strictEqual(table.getRow(2).getString(0), 'carol');
});

test('loads a file holding a single value', async () => {
const table = await mockP5Prototype.loadTable('/test/unit/assets/csv_one_value.csv');
assert.equal(table.getRowCount(), 1);
assert.strictEqual(table.getRow(0).getNum(0), 42);
});

test('loads an empty file as an empty table', async () => {
const table = await mockP5Prototype.loadTable('/test/unit/assets/csv_empty.csv');
assert.equal(table.getRowCount(), 0);
});

test('using the header option works', async () => {
const table = await mockP5Prototype.loadTable(validFile, ',', true);
assert.equal(table.getRowCount(), 3);
Expand Down