diff options
Diffstat (limited to 'js/buffer_test.ts')
-rw-r--r-- | js/buffer_test.ts | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/js/buffer_test.ts b/js/buffer_test.ts new file mode 100644 index 000000000..c614b2e03 --- /dev/null +++ b/js/buffer_test.ts @@ -0,0 +1,185 @@ +// This code has been ported almost directly from Go's src/bytes/buffer_test.go +// Copyright 2009 The Go Authors. All rights reserved. BSD license. +// https://github.com/golang/go/blob/master/LICENSE +import { test, assert, assertEqual } from "./test_util.ts"; +import { Buffer } from "deno"; + +// N controls how many iterations of certain checks are performed. +const N = 100; +let testBytes: Uint8Array | null; +let testString: string | null; + +function init() { + if (testBytes == null) { + testBytes = new Uint8Array(N); + for (let i = 0; i < N; i++) { + testBytes[i] = "a".charCodeAt(0) + (i % 26); + } + const decoder = new TextDecoder(); + testString = decoder.decode(testBytes); + } +} + +function check(buf: Buffer, s: string) { + const bytes = buf.bytes(); + assertEqual(buf.length, bytes.byteLength); + const decoder = new TextDecoder(); + const bytesStr = decoder.decode(bytes); + assertEqual(bytesStr, s); + assertEqual(buf.length, buf.toString().length); + assertEqual(buf.length, s.length); +} + +// Fill buf through n writes of byte slice fub. +// The initial contents of buf corresponds to the string s; +// the result is the final contents of buf returned as a string. +async function fillBytes( + buf: Buffer, + s: string, + n: number, + fub: Uint8Array +): Promise<string> { + check(buf, s); + for (; n > 0; n--) { + let m = await buf.write(fub); + assertEqual(m, fub.byteLength); + const decoder = new TextDecoder(); + s += decoder.decode(fub); + check(buf, s); + } + return s; +} + +// Empty buf through repeated reads into fub. +// The initial contents of buf corresponds to the string s. +async function empty(buf: Buffer, s: string, fub: Uint8Array): Promise<void> { + check(buf, s); + while (true) { + const r = await buf.read(fub); + if (r.nread == 0) { + break; + } + s = s.slice(r.nread); + check(buf, s); + } + check(buf, ""); +} + +test(function bufferNewBuffer() { + init(); + const buf = new Buffer(testBytes.buffer as ArrayBuffer); + check(buf, testString); +}); + +test(async function bufferBasicOperations() { + init(); + let buf = new Buffer(); + for (let i = 0; i < 5; i++) { + check(buf, ""); + + buf.reset(); + check(buf, ""); + + buf.truncate(0); + check(buf, ""); + + let n = await buf.write(testBytes.subarray(0, 1)); + assertEqual(n, 1); + check(buf, "a"); + + n = await buf.write(testBytes.subarray(1, 2)); + assertEqual(n, 1); + check(buf, "ab"); + + n = await buf.write(testBytes.subarray(2, 26)); + assertEqual(n, 24); + check(buf, testString.slice(0, 26)); + + buf.truncate(26); + check(buf, testString.slice(0, 26)); + + buf.truncate(20); + check(buf, testString.slice(0, 20)); + + await empty(buf, testString.slice(0, 20), new Uint8Array(5)); + await empty(buf, "", new Uint8Array(100)); + + // TODO buf.writeByte() + // TODO buf.readByte() + } +}); + +test(async function bufferLargeByteWrites() { + init(); + const buf = new Buffer(); + const limit = 9; + for (let i = 3; i < limit; i += 3) { + const s = await fillBytes(buf, "", 5, testBytes); + await empty(buf, s, new Uint8Array(Math.floor(testString.length / i))); + } + check(buf, ""); +}); + +test(async function bufferLargeByteReads() { + init(); + const buf = new Buffer(); + for (let i = 3; i < 30; i += 3) { + const n = Math.floor(testBytes.byteLength / i); + const s = await fillBytes(buf, "", 5, testBytes.subarray(0, n)); + await empty(buf, s, new Uint8Array(testString.length)); + } + check(buf, ""); +}); + +test(function bufferCapWithPreallocatedSlice() { + const buf = new Buffer(new ArrayBuffer(10)); + assertEqual(buf.capacity, 10); +}); + +test(async function bufferReadFrom() { + init(); + const buf = new Buffer(); + for (let i = 3; i < 30; i += 3) { + const s = await fillBytes( + buf, + "", + 5, + testBytes.subarray(0, Math.floor(testBytes.byteLength / i)) + ); + const b = new Buffer(); + await b.readFrom(buf); + const fub = new Uint8Array(testString.length); + await empty(b, s, fub); + } +}); + +function repeat(c: string, bytes: number): Uint8Array { + assertEqual(c.length, 1); + const ui8 = new Uint8Array(bytes); + ui8.fill(c.charCodeAt(0)); + return ui8; +} + +test(async function bufferTestGrow() { + const tmp = new Uint8Array(72); + for (let startLen of [0, 100, 1000, 10000, 100000]) { + const xBytes = repeat("x", startLen); + for (let growLen of [0, 100, 1000, 10000, 100000]) { + const buf = new Buffer(xBytes.buffer as ArrayBuffer); + // If we read, this affects buf.off, which is good to test. + const { nread, eof } = await buf.read(tmp); + buf.grow(growLen); + const yBytes = repeat("y", growLen); + await buf.write(yBytes); + // Check that buffer has correct data. + assertEqual( + buf.bytes().subarray(0, startLen - nread), + xBytes.subarray(nread) + ); + assertEqual( + buf.bytes().subarray(startLen - nread, startLen - nread + growLen), + yBytes + ); + } + } +}); |