|
| 1 | +import { assert, assertEquals, assertObjectMatch } from '@std/assert' |
| 2 | +import { pathToFile } from './filetree.ts' |
| 3 | +import { loadTSV } from './tsv.ts' |
| 4 | +import { streamFromString } from '../tests/utils.ts' |
| 5 | +import { ColumnsMap } from '../types/columns.ts' |
| 6 | + |
| 7 | +Deno.test('TSV loading', async (t) => { |
| 8 | + await t.step('Empty file produces empty map', async () => { |
| 9 | + const file = pathToFile('/empty.tsv') |
| 10 | + file.stream = streamFromString('') |
| 11 | + |
| 12 | + const map = await loadTSV(file) |
| 13 | + // map.size looks for a column called map, so work around it |
| 14 | + assertEquals(Object.keys(map).length, 0) |
| 15 | + }) |
| 16 | + |
| 17 | + await t.step('Single row file produces header-only map', async () => { |
| 18 | + const file = pathToFile('/single_row.tsv') |
| 19 | + file.stream = streamFromString('a\tb\tc\n') |
| 20 | + |
| 21 | + const map = await loadTSV(file) |
| 22 | + assertEquals(map.a, []) |
| 23 | + assertEquals(map.b, []) |
| 24 | + assertEquals(map.c, []) |
| 25 | + }) |
| 26 | + |
| 27 | + await t.step('Single column file produces single column map', async () => { |
| 28 | + const file = pathToFile('/single_column.tsv') |
| 29 | + file.stream = streamFromString('a\n1\n2\n3\n') |
| 30 | + |
| 31 | + const map = await loadTSV(file) |
| 32 | + assertEquals(map.a, ['1', '2', '3']) |
| 33 | + }) |
| 34 | + |
| 35 | + await t.step('Missing final newline is ignored', async () => { |
| 36 | + const file = pathToFile('/missing_newline.tsv') |
| 37 | + file.stream = streamFromString('a\n1\n2\n3') |
| 38 | + |
| 39 | + const map = await loadTSV(file) |
| 40 | + assertEquals(map.a, ['1', '2', '3']) |
| 41 | + }) |
| 42 | + |
| 43 | + await t.step('Empty row throws issue', async () => { |
| 44 | + const file = pathToFile('/empty_row.tsv') |
| 45 | + file.stream = streamFromString('a\tb\tc\n1\t2\t3\n\n4\t5\t6\n') |
| 46 | + |
| 47 | + try { |
| 48 | + await loadTSV(file) |
| 49 | + } catch (e: any) { |
| 50 | + assertObjectMatch(e, { key: 'TSV_EMPTY_LINE', line: 3 }) |
| 51 | + } |
| 52 | + }) |
| 53 | + |
| 54 | + await t.step('Mismatched row length throws issue', async () => { |
| 55 | + const file = pathToFile('/mismatched_row.tsv') |
| 56 | + file.stream = streamFromString('a\tb\tc\n1\t2\t3\n4\t5\n') |
| 57 | + |
| 58 | + try { |
| 59 | + await loadTSV(file) |
| 60 | + } catch (e: any) { |
| 61 | + assertObjectMatch(e, { key: 'TSV_EQUAL_ROWS', line: 3 }) |
| 62 | + } |
| 63 | + }) |
| 64 | + |
| 65 | + await t.step('maxRows limits the number of rows read', async () => { |
| 66 | + const file = pathToFile('/long.tsv') |
| 67 | + // Use 1500 to avoid overlap with default initial capacity |
| 68 | + const text = 'a\tb\tc\n' + '1\t2\t3\n'.repeat(1500) |
| 69 | + file.stream = streamFromString(text) |
| 70 | + |
| 71 | + let map = await loadTSV(file, 0) |
| 72 | + assertEquals(map.a, []) |
| 73 | + assertEquals(map.b, []) |
| 74 | + assertEquals(map.c, []) |
| 75 | + |
| 76 | + // Clear memoization cache. We currently do not key on maxRows. |
| 77 | + loadTSV.cache.clear() |
| 78 | + file.stream = streamFromString(text) |
| 79 | + map = await loadTSV(file, 1) |
| 80 | + assertEquals(map.a, ['1']) |
| 81 | + assertEquals(map.b, ['2']) |
| 82 | + assertEquals(map.c, ['3']) |
| 83 | + |
| 84 | + loadTSV.cache.clear() |
| 85 | + file.stream = streamFromString(text) |
| 86 | + map = await loadTSV(file, 2) |
| 87 | + assertEquals(map.a, ['1', '1']) |
| 88 | + assertEquals(map.b, ['2', '2']) |
| 89 | + assertEquals(map.c, ['3', '3']) |
| 90 | + |
| 91 | + loadTSV.cache.clear() |
| 92 | + file.stream = streamFromString(text) |
| 93 | + map = await loadTSV(file, -1) |
| 94 | + assertEquals(map.a, Array(1500).fill('1')) |
| 95 | + assertEquals(map.b, Array(1500).fill('2')) |
| 96 | + assertEquals(map.c, Array(1500).fill('3')) |
| 97 | + |
| 98 | + loadTSV.cache.clear() |
| 99 | + // Check that maxRows does not truncate shorter files |
| 100 | + file.stream = streamFromString('a\tb\tc\n1\t2\t3\n4\t5\t6\n7\t8\t9\n') |
| 101 | + map = await loadTSV(file, 4) |
| 102 | + assertEquals(map.a, ['1', '4', '7']) |
| 103 | + assertEquals(map.b, ['2', '5', '8']) |
| 104 | + assertEquals(map.c, ['3', '6', '9']) |
| 105 | + }) |
| 106 | + |
| 107 | + // Tests will have populated the memoization cache |
| 108 | + await loadTSV.cache.clear() |
| 109 | +}) |
0 commit comments