From 22583cf0ba3cd5c6d1c2831d602500404e38a5a0 Mon Sep 17 00:00:00 2001 From: TheoryOfNekomata Date: Fri, 21 Aug 2020 01:17:49 +0800 Subject: [PATCH] Add examples Include examples from Landon Curt Noll's website. --- src/Converter.ts | 13 ++++++------ src/ConverterStream.ts | 43 ++++++++++------------------------------ tests/Converter.test.ts | 18 ++++++++++------- tests/input/example1.txt | 1 + tests/input/example2.txt | 1 + tests/input/example3.txt | 1 + tests/input/example4.txt | 1 + tests/input/example5.txt | 1 + tests/input/example6.txt | 1 + tests/input/million.txt | 2 +- 10 files changed, 35 insertions(+), 47 deletions(-) create mode 100644 tests/input/example1.txt create mode 100644 tests/input/example2.txt create mode 100644 tests/input/example3.txt create mode 100644 tests/input/example4.txt create mode 100644 tests/input/example5.txt create mode 100644 tests/input/example6.txt diff --git a/src/Converter.ts b/src/Converter.ts index 5fc1ea2..d3b5e0e 100644 --- a/src/Converter.ts +++ b/src/Converter.ts @@ -2,14 +2,14 @@ import ConverterStream from './ConverterStream' import { ReadStreamOptions, ConvertOptions, NumberSystem, Digit } from './common' export default class Converter { - constructor(private readonly system: NumberSystem) {} + constructor(private readonly system: NumberSystem, private options: ConvertOptions) {} - public convert = (value: string | number | bigint, options: ConvertOptions): string => { + public convert = (value: string | number | bigint): string => { let converted: string[] = [] switch (typeof value!) { case 'string': case 'number': - return this.convert(BigInt(value), options) + return this.convert(BigInt(value)) case 'bigint': let current = value as bigint let thousandPower = 0n @@ -22,7 +22,7 @@ export default class Converter { let kiloCount: string if (!(ones === 0 && tens === 0 && hundreds === 0)) { if (thousandPower > 0n) { - const { scale = 'short' } = options + const { scale = 'short' } = this.options kiloName = this.system.getKiloName[scale!]!(thousandPower) } kiloCount = this.system.getKiloCount(hundreds, tens, ones) @@ -39,8 +39,7 @@ export default class Converter { throw TypeError('Invalid argument passed to value.') } - readStream(options: ReadStreamOptions): ConverterStream { - const { scale = 'short', encoding = 'utf-8' } = options - return new ConverterStream(this.system, { scale, encoding }) + public readStream = (streamOptions: ReadStreamOptions): ConverterStream => { + return new ConverterStream(this.convert, streamOptions) } } diff --git a/src/ConverterStream.ts b/src/ConverterStream.ts index 8e307a3..a010a10 100644 --- a/src/ConverterStream.ts +++ b/src/ConverterStream.ts @@ -1,47 +1,26 @@ import { Transform } from 'stream' -import { Digit, NumberSystem, ReadStreamOptions } from './common' +import { StreamOptions } from './common' export default class ConverterStream extends Transform { - private thousandPower: bigint = 0n + private bigintBuffer: bigint = 0n - private buffer = Buffer.from([]) - - constructor(private readonly system: NumberSystem, private readonly options: ReadStreamOptions) { + constructor( + private readonly converter: (value: string | number | bigint) => string, + readonly options: StreamOptions, + ) { super() - this.thousandPower = 0n } _transform(chunk: Buffer, _encoding: BufferEncoding, callback: Function) { - const { scale, encoding } = this.options - - const [ones = 0, tens = 0, hundreds = 0] = chunk - .toString(encoding!) - .split('') - .filter((s: string) => /[0-9]/.test(s)) - .map((d: string) => Number(d) as Digit) // todo use encoding - - let kiloName: string | undefined - let kiloCount: string - - if (!(ones === 0 && tens === 0 && hundreds === 0)) { - if (this.thousandPower > 0n) { - kiloName = this.system.getKiloName[scale!]!(this.thousandPower) - } - kiloCount = this.system.getKiloCount(hundreds, tens, ones) - this.buffer = Buffer.concat([ - Buffer.from(this.system.joinKilo(kiloCount, kiloName), encoding), - Buffer.from(' ', encoding), - this.buffer, - ]) - } - - this.thousandPower = this.thousandPower + 1n + let chunkStr = chunk.toString(this.options.encoding) + // we might run out of allocation for bigints? + this.bigintBuffer *= 10n ** BigInt(chunkStr.length) + this.bigintBuffer += BigInt(chunkStr) callback() } _flush(callback: Function) { - const { encoding } = this.options - this.push(this.buffer, encoding) + this.push(this.converter(this.bigintBuffer), this.options.encoding) callback() } } diff --git a/tests/Converter.test.ts b/tests/Converter.test.ts index f73c35e..29689e3 100644 --- a/tests/Converter.test.ts +++ b/tests/Converter.test.ts @@ -10,7 +10,7 @@ describe.each` let converter: Converter beforeAll(() => { - converter = new Converter(system) + converter = new Converter(system, { scale, }) }) describe('on values', () => { @@ -19,7 +19,7 @@ describe.each` ${1000000} | ${'one million'} ${123456789} | ${'one hundred twenty three million four hundred fifty six thousand seven hundred eighty nine'} `('should parse $value as $name', ({ value, name, }) => { - expect(converter.convert(value, { scale })).toBe(name) + expect(converter.convert(value)).toBe(name) }) }) @@ -27,22 +27,26 @@ describe.each` const ENCODING = 'utf-8' test.each([ - 'million.txt' + 'million', + 'example1', + 'example2', + 'example3', + 'example4', + 'example5', + 'example6', ])('should correctly parse a stream', async (filename) => { const inputStream = fs.createReadStream( - `./tests/input/${filename}`, + `./tests/input/${filename}.txt`, { encoding: ENCODING, - highWaterMark: 3, // this is required to parse kilos correctly } ) const readStream = converter.readStream({ - scale, encoding: ENCODING }) inputStream .pipe(readStream) - .pipe(fs.createWriteStream(`./tests/output/${filename}`)) + .pipe(fs.createWriteStream(`./tests/output/${filename}.${scale}.txt`)) return new Promise((resolve) => { readStream.on('end', () => { diff --git a/tests/input/example1.txt b/tests/input/example1.txt new file mode 100644 index 0000000..478042f --- /dev/null +++ b/tests/input/example1.txt @@ -0,0 +1 @@ +987654321 diff --git a/tests/input/example2.txt b/tests/input/example2.txt new file mode 100644 index 0000000..484cd5a --- /dev/null +++ b/tests/input/example2.txt @@ -0,0 +1 @@ +123456789246801357 diff --git a/tests/input/example3.txt b/tests/input/example3.txt new file mode 100644 index 0000000..806db9e --- /dev/null +++ b/tests/input/example3.txt @@ -0,0 +1 @@ +123456789246801357000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 diff --git a/tests/input/example4.txt b/tests/input/example4.txt new file mode 100644 index 0000000..4ac475a --- /dev/null +++ b/tests/input/example4.txt @@ -0,0 +1 @@ +123456789246801357000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 diff --git a/tests/input/example5.txt b/tests/input/example5.txt new file mode 100644 index 0000000..67b7552 --- /dev/null +++ b/tests/input/example5.txt @@ -0,0 +1 @@ +123456789246801357000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 diff --git a/tests/input/example6.txt b/tests/input/example6.txt new file mode 100644 index 0000000..5681967 --- /dev/null +++ b/tests/input/example6.txt @@ -0,0 +1 @@ +123456789246801357000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 diff --git a/tests/input/million.txt b/tests/input/million.txt index 762357d..749fce6 100644 --- a/tests/input/million.txt +++ b/tests/input/million.txt @@ -1 +1 @@ -987000321 +1000000