|
1 | | -import { assert, assertEquals, assertObjectMatch } from '@std/assert' |
| 1 | +import { assert, assertEquals, assertNotEquals, assertObjectMatch } from '@std/assert' |
2 | 2 | import { pathToFile } from './filetree.ts' |
3 | 3 | import { loadTSV } from './tsv.ts' |
4 | 4 | import { streamFromString } from '../tests/utils.ts' |
@@ -104,6 +104,34 @@ Deno.test('TSV loading', async (t) => { |
104 | 104 | assertEquals(map.c, ['3', '6', '9']) |
105 | 105 | }) |
106 | 106 |
|
| 107 | + await t.step('caching avoids multiple reads', async () => { |
| 108 | + loadTSV.cache.clear() |
| 109 | + const file = pathToFile('/long.tsv') |
| 110 | + // Use 1500 to avoid overlap with default initial capacity |
| 111 | + const text = 'a\tb\tc\n' + '1\t2\t3\n'.repeat(1500) |
| 112 | + file.stream = streamFromString(text) |
| 113 | + |
| 114 | + let map = await loadTSV(file, 2) |
| 115 | + assertEquals(map.a, ['1', '1']) |
| 116 | + assertEquals(map.b, ['2', '2']) |
| 117 | + assertEquals(map.c, ['3', '3']) |
| 118 | + |
| 119 | + // Replace stream to ensure cache does not depend on deep object equality |
| 120 | + file.stream = streamFromString(text) |
| 121 | + let repeatMap = await loadTSV(file, 2) |
| 122 | + // Equality is identity for objects |
| 123 | + assertEquals(map, repeatMap) |
| 124 | + |
| 125 | + loadTSV.cache.clear() |
| 126 | + // DO NOT replace stream so the next read verifies the previous stream wasn't read |
| 127 | + repeatMap = await loadTSV(file, 2) |
| 128 | + assertEquals(repeatMap.a, ['1', '1']) |
| 129 | + assertEquals(repeatMap.b, ['2', '2']) |
| 130 | + assertEquals(repeatMap.c, ['3', '3']) |
| 131 | + // Same contents, different objects |
| 132 | + assertNotEquals(map, repeatMap) |
| 133 | + }) |
| 134 | + |
107 | 135 | // Tests will have populated the memoization cache |
108 | | - await loadTSV.cache.clear() |
| 136 | + loadTSV.cache.clear() |
109 | 137 | }) |
0 commit comments