diff --git a/assembly/buffer/index.ts b/assembly/buffer/index.ts index 66866bf..627a273 100644 --- a/assembly/buffer/index.ts +++ b/assembly/buffer/index.ts @@ -1,25 +1,415 @@ -import { BLOCK_MAXSIZE } from "rt/common"; +import { BLOCK_MAXSIZE, BLOCK, BLOCK_OVERHEAD } from "rt/common"; import { E_INVALIDLENGTH, E_INDEXOUTOFRANGE } from "util/error"; import { Uint8Array } from "typedarray"; export class Buffer extends Uint8Array { + [key: number]: u8; + constructor(size: i32) { super(size); } - public static alloc(size: i32): Buffer { + static alloc(size: i32): Buffer { return new Buffer(size); } - @unsafe public static allocUnsafe(size: i32): Buffer { - // Node throws an error if size is less than 0 - if (u32(size) > BLOCK_MAXSIZE) throw new RangeError(E_INVALIDLENGTH); + @unsafe static allocUnsafe(size: i32): Buffer { + // range must be valid + if (size > BLOCK_MAXSIZE) throw new RangeError(E_INVALIDLENGTH); let buffer = __alloc(size, idof()); - // This retains the pointer to the result Buffer. - let result = changetype(__alloc(offsetof(), idof())); - result.data = changetype(buffer); - result.dataStart = changetype(buffer); - result.dataLength = size; - return result; + let result = __alloc(offsetof(), idof()); + + // set the properties + store(result, __retain(buffer), offsetof("buffer")); + store(result, buffer, offsetof("dataStart")); + store(result, size, offsetof("byteLength")); + + // return and retain + return changetype(result); + } + + static isBuffer(value: T): bool { + return value instanceof Buffer; + } + + // Adapted from https://github.com/AssemblyScript/assemblyscript/blob/master/std/assembly/typedarray.ts + subarray(begin: i32 = 0, end: i32 = 0x7fffffff): Buffer { + var len = this.byteLength; + begin = begin < 0 ? max(len + begin, 0) : min(begin, len); + end = end < 0 ? max(len + end, 0) : min(end, len); + end = max(end, begin); + + var out = __alloc(offsetof(), idof()); // retains + store(out, __retain(changetype(this.buffer)), offsetof("buffer")); + store(out, this.dataStart + begin, offsetof("dataStart")); + store(out, end - begin, offsetof("byteLength")); + + // retains + return changetype(out); + } + + readInt8(offset: i32 = 0): i8 { + if (i32(offset < 0) | i32(offset >= this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return load(this.dataStart + offset); + } + + readUInt8(offset: i32 = 0): u8 { + if (i32(offset < 0) | i32(offset >= this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return load(this.dataStart + offset); + } + + writeInt8(value: i8, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset >= this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, value); + return offset + 1; + } + + writeUInt8(value: u8, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset >= this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, value); + return offset + 1; + } + + readInt16LE(offset: i32 = 0): i16 { + if (i32(offset < 0) | i32(offset + 2 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return load(this.dataStart + offset); + } + + readInt16BE(offset: i32 = 0): i16 { + if (i32(offset < 0) | i32(offset + 2 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return bswap(load(this.dataStart + offset)); + } + + readUInt16LE(offset: i32 = 0): u16 { + if (i32(offset < 0) | i32(offset + 2 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return load(this.dataStart + offset); + } + + readUInt16BE(offset: i32 = 0): u16 { + if (i32(offset < 0) | i32(offset + 2 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return bswap(load(this.dataStart + offset)); + } + + writeInt16LE(value: i16, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 2 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, value); + return offset + 2; + } + + writeInt16BE(value: i16, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 2 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, bswap(value)); + return offset + 2; + } + + writeUInt16LE(value: u16, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 2 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, value); + return offset + 2; + } + + writeUInt16BE(value: u16, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 2 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, bswap(value)); + return offset + 2; + } + + readInt32LE(offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 4 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return load(this.dataStart + offset); + } + + readInt32BE(offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 4 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return bswap(load(this.dataStart + offset)); + } + + readUInt32LE(offset: i32 = 0): u32 { + if (i32(offset < 0) | i32(offset + 4 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return load(this.dataStart + offset); + } + + readUInt32BE(offset: i32 = 0): u32 { + if (i32(offset < 0) | i32(offset + 4 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return bswap(load(this.dataStart + offset)); + } + + writeInt32LE(value: i32, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 4 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, value); + return offset + 4; + } + + writeInt32BE(value: i32, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 4 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, bswap(value)); + return offset + 4; + } + + writeUInt32LE(value: u32, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 4 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, value); + return offset + 4; + } + + writeUInt32BE(value: u32, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 4 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, bswap(value)); + return offset + 4; + } + + readFloatLE(offset: i32 = 0): f32 { + if (i32(offset < 0) | i32(offset + 4 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return load(this.dataStart + offset); + } + + readFloatBE(offset: i32 = 0): f32 { + if (i32(offset < 0) | i32(offset + 4 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return reinterpret(bswap(load(this.dataStart + offset))); + } + + writeFloatLE(value: f32, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 4 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, value); + return offset + 4; + } + + writeFloatBE(value: f32, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 4 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, bswap(reinterpret(value))); + return offset + 4; + } + + readBigInt64LE(offset: i32 = 0): i64 { + if (i32(offset < 0) | i32(offset + 8 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return load(this.dataStart + offset); + } + + readBigInt64BE(offset: i32 = 0): i64 { + if (i32(offset < 0) | i32(offset + 8 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return bswap(load(this.dataStart + offset)); + } + + readBigUInt64LE(offset: i32 = 0): u64 { + if (i32(offset < 0) | i32(offset + 8 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return load(this.dataStart + offset); + } + + readBigUInt64BE(offset: i32 = 0): u64 { + if (i32(offset < 0) | i32(offset + 8 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return bswap(load(this.dataStart + offset)); + } + + writeBigInt64LE(value: i64, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 8 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, value); + return offset + 8; + } + + writeBigInt64BE(value: i64, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 8 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, bswap(value)); + return offset + 8; + } + + writeBigUInt64LE(value: u64, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 8 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, value); + return offset + 8; + } + + writeBigUInt64BE(value: u64, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 8 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, bswap(value)); + return offset + 8; + } + + readDoubleLE(offset: i32 = 0): f64 { + if (i32(offset < 0) | i32(offset + 8 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return load(this.dataStart + offset); + } + + readDoubleBE(offset: i32 = 0): f64 { + if (i32(offset < 0) | i32(offset + 8 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + return reinterpret(bswap(load(this.dataStart + offset))); + } + + writeDoubleLE(value: f64, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 8 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, value); + return offset + 8; + } + + writeDoubleBE(value: f64, offset: i32 = 0): i32 { + if (i32(offset < 0) | i32(offset + 8 > this.byteLength)) throw new RangeError(E_INDEXOUTOFRANGE); + store(this.dataStart + offset, bswap(reinterpret(value))); + return offset + 8; + } + + swap16(): Buffer { + let byteLength = this.byteLength; + // Make sure byteLength is even + if (byteLength & 1) throw new RangeError(E_INVALIDLENGTH); + let dataStart = this.dataStart; + byteLength += dataStart; + while (dataStart < byteLength) { + store(dataStart, bswap(load(dataStart))); + dataStart += 2; + } + return this; + } + + swap32(): Buffer { + let byteLength = this.byteLength; + // Make sure byteLength is divisible by 4 + if (byteLength & 3) throw new RangeError(E_INVALIDLENGTH); + let dataStart = this.dataStart; + byteLength += dataStart; + while (dataStart < byteLength) { + store(dataStart, bswap(load(dataStart))); + dataStart += 4; + } + return this; + } + + swap64(): Buffer { + let byteLength = this.byteLength; + // Make sure byteLength is divisible by 8 + if (byteLength & 7) throw new RangeError(E_INVALIDLENGTH); + let dataStart = this.dataStart; + byteLength += dataStart; + while (dataStart < byteLength) { + store(dataStart, bswap(load(dataStart))); + dataStart += 8; + } + return this; + } +} + +export namespace Buffer { + export namespace ASCII { + export function encode(str: string): ArrayBuffer { + let length = str.length; + let output = __alloc(length, idof()); + for (let i = 0; i < length; i++) { + let char = load(changetype(str) + (i << 1)); + store(output + i, char & 0x7F); + } + return changetype(output); + } + + export function decode(buffer: ArrayBuffer): String { + return decodeUnsafe(changetype(buffer), buffer.byteLength); + } + + // @ts-ignore: decorator + @unsafe export function decodeUnsafe(pointer: usize, length: i32): String { + let result = __alloc(length << 1, idof()); + + for (let i = 0; i < length; i++) { + let byte = load(pointer + i); + store(result + (i << 1), byte & 0x7F); + } + + return changetype(result); + } + } + + export namespace HEX { + /** Calculates the byte length of the specified string when encoded as HEX. */ + export function byteLength(str: string): i32 { + let ptr = changetype(str); + let byteCount = changetype(changetype(str) - BLOCK_OVERHEAD).rtSize; + let length = byteCount >>> 2; + // The string length must be even because the bytes come in pairs of characters two wide + if (byteCount & 3) return 0; // encoding fails and returns an empty ArrayBuffer + + byteCount += ptr; + while (ptr < byteCount) { + var char = load(ptr); + if ( ((char - 0x30) <= 9) + || ((char - 0x61) <= 5) + || ((char - 0x41) <= 5)) { + ptr += 2; + continue; + } else { + return 0; + } + } + return length; + } + + /** Creates an ArrayBuffer from a given string that is encoded in the HEX format. */ + export function encode(str: string): ArrayBuffer { + let bufferLength = byteLength(str); + // short path: string is not a valid hex string, return a new empty ArrayBuffer + if (bufferLength == 0) return changetype(__alloc(0, idof())); + + // long path: loop over each enociding pair and perform the conversion + let ptr = changetype(str); + let byteEnd = ptr + changetype(changetype(str) - BLOCK_OVERHEAD).rtSize; + let result = __alloc(bufferLength, idof()); + let b: u32 = 0; + let outChar = 0; + for (let i: usize = 0; ptr < byteEnd; i++) { + if (i & 1) { + outChar <<= 4; + b >>>= 16; + if ((b - 0x30) <= 9) { + outChar |= b - 0x30; + } else if ((b - 0x61) <= 5) { + outChar |= b - 0x57; + } else if (b - 0x41 <= 5) { + outChar |= b - 0x37; + } + store(result + (i >> 1), (outChar & 0xFF)); + ptr += 4; + } else { + b = load(ptr); + outChar <<= 4; + let c = b & 0xFF; + if ((c - 0x30) <= 9) { + outChar |= c - 0x30; + } else if ((c - 0x61) <= 5) { + outChar |= c - 0x57; + } else if (c - 0x41 <= 5) { + outChar |= c - 0x37; + } + } + } + return changetype(result); + } + + /** Creates a string from a given ArrayBuffer that is decoded into hex format. */ + export function decode(buff: ArrayBuffer): string { + return decodeUnsafe(changetype(buff), buff.byteLength); + } + + /** Decodes a chunk of memory to a utf16le encoded string in hex format. */ + // @ts-ignore: decorator + @unsafe export function decodeUnsafe(ptr: usize, length: i32): string { + let stringByteLength = length << 2; // length * (2 bytes per char) * (2 chars per input byte) + let result = __alloc(stringByteLength, idof()); + let i = 0; + let inputByteLength = length + ptr; + + // loop over each byte and store a `u32` for each one + while (ptr < inputByteLength) { + store(result + i, charsFromByte(load(ptr++))); + i += 4; + } + + return changetype(result); + } + + /** Calculates the two char combination from the byte. */ + // @ts-ignore: decorator + @inline function charsFromByte(byte: u32): u32 { + let hi = (byte >>> 4) & 0xF; + let lo = byte & 0xF; + hi += select(0x57, 0x30, hi > 9); + lo += select(0x57, 0x30, lo > 9); + return (lo << 16) | hi; + } } } diff --git a/assembly/node.d.ts b/assembly/node.d.ts index 80075a8..a276e60 100644 --- a/assembly/node.d.ts +++ b/assembly/node.d.ts @@ -3,4 +3,105 @@ declare class Buffer extends Uint8Array { static alloc(size: i32): Buffer; /** This method allocates a new Buffer of indicated size. This is unsafe because the data is not zeroed. */ static allocUnsafe(size: i32): Buffer; + /** This method asserts a value is a Buffer object via `value instanceof Buffer`. */ + static isBuffer(value: T): bool; + /** Reads a signed integer at the designated offset. */ + readInt8(offset?: i32): i8; + /** Reads an unsigned integer at the designated offset. */ + readUInt8(offset?: i32): u8; + /** Writes an inputted value to the buffer, at the desired offset. */ + writeInt8(value:i8, offset?:i32): i32; + /** Writes an inputted u8 value to the buffer, at the desired offset. */ + writeUInt8(value:u8, offset?:i32): i32; + /** Reads a signed 16-bit integer, stored in Little Endian format at the designated offset. */ + readInt16LE(offset?: i32): i16; + /** Reads a signed 16-bit integer, stored in Big Endian format at the designated offset. */ + readInt16BE(offset?: i32): i16; + /** Reads an unsigned 16-bit integer, stored in Little Endian format at the designated offset. */ + readUInt16LE(offset?: i32): u16; + /** Reads an unsigned 16-bit integer, stored in Big Endian format at the designated offset. */ + readUInt16BE(offset?: i32): u16; + /** Writes an inputted 16-bit integer at the designated offset, stored in Little Endian format */ + writeInt16LE(value: i16, offset?: i32): i32; + /** Writes an inputted 16-bit integer at the designated offset, stored in Big Endian format */ + writeInt16BE(value: i16, offset?: i32): i32; + /** Writes an inputted unsigned 16-bit integer at the designated offset, stored in Little Endian format */ + writeUInt16LE(value: u16, offset?: i32): i32; + /** Writes an inputted unsigned 16-bit integer at the designated offset, stored in Big Endian format */ + writeUInt16BE(value: u16, offset?: i32): i32; + /** Reads a signed 32-bit integer, stored in Little Endian format at the designated offset. */ + readInt32LE(offset?: i32): i32; + /** Reads a signed 32-bit integer, stored in Big Endian format at the designated offset. */ + readInt32BE(offset?: i32): i32; + /** Reads an unsigned 32-bit integer, stored in Little Endian format at the designated offset. */ + readUInt32LE(offset?: i32): u32; + /** Reads an unsigned 32-bit integer, stored in Big Endian format at the designated offset. */ + readUInt32BE(offset?: i32): u32; + /** Writes an inputted 32-bit integer at the designated offset, stored in Little Endian format */ + writeInt32LE(value: i32, offset?: i32): i32; + /** Writes an inputted 32-bit integer at the designated offset, stored in Big Endian format */ + writeInt32BE(value: i32, offset?: i32): i32; + /** Writes an inputted unsigned 32-bit integer at the designated offset, stored in Little Endian format */ + writeUInt32LE(value: u32, offset?: i32): i32; + /** Writes an inputted unsigned 32-bit integer at the designated offset, stored in Big Endian format */ + writeUInt32BE(value: u32, offset?: i32): i32; + /** Reads a signed 32-bit float, stored in Little Endian format at the designated offset. */ + readFloatLE(offset?: i32): f32; + /** Reads a signed 32-bit float, stored in Big Endian format at the designated offset. */ + readFloatBE(offset?: i32): f32; + /** Writes an inputted 32-bit float at the designated offset, stored in Little Endian format */ + writeFloatLE(value: f32, offset?: i32): i32; + /** Writes an inputted 32-bit float at the designated offset, stored in Big Endian format */ + writeFloatBE(value: f32, offset?: i32): i32; + /** Reads a signed 64-bit integer, stored in Little Endian format at the designated offset. */ + readBigInt64LE(offset?: i32): i64; + /** Reads a signed 64-bit integer, stored in Big Endian format at the designated offset. */ + readBigInt64BE(offset?: i32): i64; + /** Reads an unsigned 64-bit integer, stored in Little Endian format at the designated offset. */ + readBigUInt64LE(offset?: i32): u64; + /** Reads an unsigned 64-bit integer, stored in Big Endian format at the designated offset. */ + readBigUInt64BE(offset?: i32): u64; + /** Writes an inputted 64-bit integer at the designated offset, stored in Little Endian format */ + writeBigInt64LE(value: i64, offset?: i32): i32; + /** Writes an inputted 64-bit integer at the designated offset, stored in Big Endian format */ + writeBigInt64BE(value: i64, offset?: i32): i32; + /** Writes an inputted unsigned 64-bit integer at the designated offset, stored in Little Endian format */ + writeBigUInt64LE(value: u64, offset?: i32): i32; + /** Writes an inputted unsigned 64-bit integer at the designated offset, stored in Big Endian format */ + writeBigUInt64BE(value: u64, offset?: i32): i32; + /** Reads a signed 64-bit double, stored in Little Endian format at the designated offset. */ + readDoubleLE(offset?: i32): f64; + /** Reads a signed 64-bit double, stored in Big Endian format at the designated offset. */ + readDoubleBE(offset?: i32): f64; + /** Writes an inputted 64-bit double at the designated offset, stored in Little Endian format */ + writeDoubleLE(value: f64, offset?: i32): i32; + /** Writes an inputted 64-bit double at the designated offset, stored in Big Endian format */ + writeDoubleBE(value: f64, offset?: i32): i32; + /** Swaps every group of two bytes in a Buffer in-place */ + swap16(): Buffer; + /** Swaps every group of four bytes in a Buffer in-place */ + swap32(): Buffer; + /** Swaps every group of eight bytes in a Buffer in-place */ + swap64(): Buffer; +} + +declare namespace Buffer { + /** The HEX encoding and decoding namespace. */ + export namespace HEX { + /** Creates an ArrayBuffer from a given string that is encoded in the hex format. */ + export function encode(str: string): ArrayBuffer; + /** Creates a string from a given ArrayBuffer that is decoded into hex format. */ + export function decode(buffer: ArrayBuffer): string; + /** Decodes a chunk of memory to a utf16le encoded string in hex format. */ + export function decodeUnsafe(ptr: usize, byteLength: i32): string; + } + /** The ASCII encoding and decoding namespace. */ + export namespace ASCII { + /** Creates an ArrayBuffer from a given string that is encoded in the ASCII format. */ + export function encode(str: string): ArrayBuffer; + /** Creates a string from a given ArrayBuffer that is decoded into ASCII format. */ + export function decode(buffer: ArrayBuffer): string; + /** Decodes a chunk of memory to a utf16le encoded string in ASCII format. */ + export function decodeUnsafe(ptr: usize, byteLength: i32): string; + } } diff --git a/package-lock.json b/package-lock.json index 039989d..5911184 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,271 +1,343 @@ { "name": "@assemblyscript/node", "version": "0.1.0", - "lockfileVersion": 1, + "lockfileVersion": 3, "requires": true, - "dependencies": { - "@as-pect/assembly": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@as-pect/assembly/-/assembly-2.2.0.tgz", - "integrity": "sha512-Md50OTJRH6uTCqNJpcJu8/W9qNGZixzIHLktTeK5Ot5UEiWqd/JoQlTAM5V5+Bp1cI5fCqmUld6Dpq+ixDraPA==", - "dev": true + "packages": { + "": { + "version": "0.1.0", + "license": "Apache-2.0", + "devDependencies": { + "@as-pect/core": "^3.2.2", + "assemblyscript": "0.10.0", + "glob": "^7.1.6" + } + }, + "node_modules/@as-pect/assembly": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@as-pect/assembly/-/assembly-3.2.1.tgz", + "integrity": "sha512-qok+WPvKV1BLQ+nnpn+hc0PLSZ69Pim4eT72PruA1C+hvMu6HCbNKDFcj4lrL7XNMKuibPf0633SW14asC0//w==", + "dev": true, + "peerDependencies": { + "assemblyscript": "^0.10.0" + } }, - "@as-pect/core": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@as-pect/core/-/core-2.2.0.tgz", - "integrity": "sha512-a1I142/J1JOa4mLeRI0tKT9KrGlHgLNHn7ZkLlkp9v/n9pE4Zuh9rGYzGuUZg285ze+0yGQfYVmRqBLJkS+IlQ==", + "node_modules/@as-pect/core": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@as-pect/core/-/core-3.2.2.tgz", + "integrity": "sha512-Gr6ha3WGS/omSLvquDC6WPqZt1vP/hxvWovxgUuqNJ1APymMTjbvP2W86pjKLqvSaZj1gETAr5703PxhnnoL4g==", "dev": true, - "requires": { - "@as-pect/assembly": "^2.2.0", - "chalk": "^2.4.2", - "csv-stringify": "^5.3.0", + "dependencies": { + "@as-pect/assembly": "^3.2.1", + "@as-pect/snapshots": "^3.2.2", + "chalk": "^4.0.0", "long": "^4.0.0" + }, + "peerDependencies": { + "assemblyscript": "^0.10.0" } }, - "@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=", + "node_modules/@as-pect/snapshots": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@as-pect/snapshots/-/snapshots-3.2.2.tgz", + "integrity": "sha512-uJQwwbgX0gGRVD4Au8r3g9TbPCseBuChSDVjfaNAZifaQ0JKrrzB4tga2PVDrWrZHIgYvajTph5tsN3x9pJ5nA==", + "dev": true, + "dependencies": { + "diff": "^4.0.2", + "nearley": "^2.19.3" + } + }, + "node_modules/@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "dev": true, - "requires": { - "color-convert": "^1.9.0" + "dependencies": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "assemblyscript": { - "version": "github:assemblyscript/assemblyscript#7c775d1bccbe08fec5d820b9d53ae44ff6bd1e49", - "from": "github:assemblyscript/assemblyscript#7c775d1bccbe08fec5d820b9d53ae44ff6bd1e49", + "node_modules/assemblyscript": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/assemblyscript/-/assemblyscript-0.10.0.tgz", + "integrity": "sha512-ErUNhHboD+zsB4oG6X1YICDAIo27Gq7LeNX6jVe+Q0W5cI51/fHwC8yJ68IukqvupmZgYPdp1JqqRXlS+BrUfA==", "dev": true, - "requires": { - "@protobufjs/utf8": "^1.1.0", - "binaryen": "87.0.0-nightly.20190716", - "glob": "^7.1.4", - "long": "^4.0.0", - "opencollective-postinstall": "^2.0.0", - "source-map-support": "^0.5.12" + "dependencies": { + "binaryen": "93.0.0-nightly.20200514", + "long": "^4.0.0" + }, + "bin": { + "asc": "bin/asc", + "asinit": "bin/asinit" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/assemblyscript" } }, - "balanced-match": { + "node_modules/balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, - "binaryen": { - "version": "87.0.0-nightly.20190716", - "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-87.0.0-nightly.20190716.tgz", - "integrity": "sha512-qRGfV8cLV4HVVo1oUCtTaDmOhbwctaW7vyW0G6HKftywWOJI9t9IsCrUEFKya50RqyEnanuS2w3nfOg4bxTGqg==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "node_modules/binaryen": { + "version": "93.0.0-nightly.20200514", + "resolved": "https://registry.npmjs.org/binaryen/-/binaryen-93.0.0-nightly.20200514.tgz", + "integrity": "sha512-SRRItmNvhRVfoWWbRloO4i8IqkKH8rZ7/0QWRgLpM3umupK8gBpo9MY7Zp3pDysRSp+rVoqxvM5x4tFyCSa9zw==", "dev": true, - "requires": { - "file-uri-to-path": "1.0.0" + "bin": { + "wasm-opt": "bin/wasm-opt" } }, - "brace-expansion": { + "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "requires": { + "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "requires": { - "color-name": "1.1.3" + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, - "concat-map": { + "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "csv-stringify": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-5.3.0.tgz", - "integrity": "sha512-VMYPbE8zWz475smwqb9VbX9cj0y4J0PBl59UdcqzLkzXHZZ8dh4Rmbb0ZywsWEtUml4A96Hn7Q5MW9ppVghYzg==", + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, - "optional": true, - "requires": { - "lodash.get": "~4.4.2" + "engines": { + "node": ">=0.3.1" } }, - "diff": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", - "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "file-uri-to-path": { + "node_modules/discontinuous-range": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz", + "integrity": "sha1-44Mx8IRLukm5qctxx3FYWqsbxlo=", "dev": true }, - "fs.realpath": { + "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, - "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, - "requires": { + "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "inflight": { + "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, - "requires": { + "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, - "inherits": { + "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", - "dev": true, - "optional": true - }, - "long": { + "node_modules/long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", "dev": true }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/moo": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.1.tgz", + "integrity": "sha512-I1mnb5xn4fO80BH9BLcF0yLypy2UKl+Cb01Fu0hJRkJjlCRtxZMWkTdAtDd5ZqCOxtCkhmRwyI57vWT+1iZ67w==", + "dev": true + }, + "node_modules/nearley": { + "version": "2.19.3", + "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.19.3.tgz", + "integrity": "sha512-FpAy1PmTsUpOtgxr23g4jRNvJHYzZEW2PixXeSzksLR/ykPfwKhAodc2+9wQhY+JneWLcvkDw6q7FJIsIdF/aQ==", + "dev": true, + "dependencies": { + "commander": "^2.19.0", + "moo": "^0.5.0", + "railroad-diagrams": "^1.0.0", + "randexp": "0.4.6", + "semver": "^5.4.1" + }, + "bin": { + "nearley-railroad": "bin/nearley-railroad.js", + "nearley-test": "bin/nearley-test.js", + "nearley-unparse": "bin/nearley-unparse.js", + "nearleyc": "bin/nearleyc.js" } }, - "once": { + "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, - "requires": { + "dependencies": { "wrappy": "1" } }, - "opencollective-postinstall": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz", - "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==", - "dev": true - }, - "path-is-absolute": { + "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/railroad-diagrams": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz", + "integrity": "sha1-635iZ1SN3t+4mcG5Dlc3RVnN234=", "dev": true }, - "source-map-support": { - "version": "0.5.12", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", - "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", + "node_modules/randexp": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz", + "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==", + "dev": true, + "dependencies": { + "discontinuous-range": "1.0.0", + "ret": "~0.1.10" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "engines": { + "node": ">=0.12" } }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true, - "requires": { - "has-flag": "^3.0.0" + "bin": { + "semver": "bin/semver" } }, - "wasi": { - "version": "github:devsnek/node-wasi#12a0985a46589587facd8d8e161911650ef15f3b", - "from": "github:devsnek/node-wasi", + "node_modules/supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", "dev": true, - "requires": { - "bindings": "^1.5.0" + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "wrappy": { + "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", diff --git a/package.json b/package.json index 831c9c0..3265e45 100644 --- a/package.json +++ b/package.json @@ -12,14 +12,12 @@ "url": "https://github.com/AssemblyScript/node/issues" }, "devDependencies": { - "@as-pect/core": "^2.2.0", - "assemblyscript": "github:assemblyscript/assemblyscript#7c775d1bccbe08fec5d820b9d53ae44ff6bd1e49", - "diff": "^4.0.1", - "glob": "^7.1.4", - "wasi": "github:devsnek/node-wasi" + "@as-pect/core": "^3.2.2", + "assemblyscript": "0.10.0", + "glob": "^7.1.6" }, "scripts": { - "test": "node tests/node" + "test": "node --experimental-wasi-unstable-preview1 --experimental-wasm-bigint tests/node" }, "dependencies": {} } diff --git a/tests/buffer.spec.ts b/tests/buffer.spec.ts index 1596845..dcd4177 100644 --- a/tests/buffer.spec.ts +++ b/tests/buffer.spec.ts @@ -11,35 +11,557 @@ */ import { BLOCK_MAXSIZE } from "rt/common"; +// Helper function to quickly create a Buffer from an array. +//@ts-ignore +function create(values: valueof[]): T { + let result = instantiate(values.length); + //@ts-ignore + for (let i = 0; i < values.length; i++) result[i] = values[i]; + return result; +} + describe("buffer", () => { test("#constructor", () => { - expect(new Buffer(0)).toBeTruthy(); - expect(new Buffer(10)).toHaveLength(10); + expect(new Buffer(0)).toBeTruthy(); + expect(new Buffer(10)).toHaveLength(10); let myBuffer = new Buffer(10); - expect(myBuffer.buffer).toBeTruthy(); - expect(myBuffer.buffer).toHaveLength(10); - // TODO: expectFn(() => { new Buffer(-1); }).toThrow(); - // TODO: expectFn(() => { new Buffer(BLOCK_MAXSIZE + 1); }).toThrow(); + expect(myBuffer.buffer).toBeTruthy(); + expect(myBuffer.buffer).toHaveLength(10); + expect(() => { new Buffer(-1); }).toThrow(); + // TODO: figure out how to test block maxsize + // expect(() => { new Buffer(1 + BLOCK_MAXSIZE); }).toThrow(); }); test("#alloc", () => { - expect(Buffer.alloc(10)).toBeTruthy(); - expect(Buffer.alloc(10)).toHaveLength(10); + expect(Buffer.alloc(10)).toBeTruthy(); + expect(Buffer.alloc(10)).toHaveLength(10); let buff = Buffer.alloc(100); for (let i = 0; i < buff.length; i++) expect(buff[i]).toBe(0); - expect(buff.buffer).not.toBeNull(); - expect(buff.byteLength).toBe(100); - // TODO: expectFn(() => { Buffer.alloc(-1); }).toThrow(); - // TODO: expectFn(() => { Buffer.alloc(BLOCK_MAXSIZE + 1); }).toThrow(); + expect(buff.buffer).not.toBeNull(); + expect(buff.byteLength).toBe(100); + expect(() => { Buffer.alloc(-1); }).toThrow(); + // TODO: figure out how to test block maxsize + // expect(() => { Buffer.alloc(1 + BLOCK_MAXSIZE); }).toThrow(); }); test("#allocUnsafe", () => { - expect(Buffer.allocUnsafe(10)).toBeTruthy(); - expect(Buffer.allocUnsafe(10)).toHaveLength(10); + expect(Buffer.allocUnsafe(10)).toBeTruthy(); + expect(Buffer.allocUnsafe(10)).toHaveLength(10); let buff = Buffer.allocUnsafe(100); - expect(buff.buffer).not.toBeNull(); - expect(buff.byteLength).toBe(100); - // TODO: expectFn(() => { Buffer.allocUnsafe(-1); }).toThrow(); - // TODO: expectFn(() => { Buffer.allocUnsafe(BLOCK_MAXSIZE + 1); }).toThrow(); + expect(buff.buffer).not.toBeNull(); + expect(buff.byteLength).toBe(100); + expect(() => { Buffer.allocUnsafe(-1); }).toThrow(); + // TODO: figure out how to test block maxsize + // expect(() => { Buffer.allocUnsafe(BLOCK_MAXSIZE + 1); }).toThrow(); + }); + + test("#isBuffer", () => { + let a = ""; + let b = new Uint8Array(0); + let c = 0; + let d = 1.1; + let e = new Buffer(0); + let f: Buffer | null = null; + + expect(Buffer.isBuffer(a)).toBeFalsy(); + expect(Buffer.isBuffer(b)).toBeFalsy(); + expect(Buffer.isBuffer(c)).toBeFalsy(); + expect(Buffer.isBuffer(d)).toBeFalsy(); + expect(Buffer.isBuffer(e)).toBeTruthy(); + expect(Buffer.isBuffer(f)).toBeFalsy(); + }); + + test("#readInt8", () => { + let buff = create([0x5,0x0,0x0,0x0,0xFF]); + expect(buff.readInt8()).toBe(5); + // Testing offset, and casting between u8 and i8. + expect(buff.readInt8(4)).toBe(-1); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readInt8(5); + }).toThrow(); + }); + + test("#readUInt8", () => { + let buff = create([0xFE,0x0,0x0,0x0,0x2F]); + // Testing casting between u8 and i8. + expect(buff.readUInt8()).toBe(254); + // Testing offset + expect(buff.readUInt8(4)).toBe(47); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readUInt8(5); + }).toThrow(); + }); + + test("#writeInt8", () => { + let buff = new Buffer(5); + expect(buff.writeInt8(9)).toBe(1); + expect(buff.writeInt8(-3,4)).toBe(5); + let result = create([0x09, 0x0, 0x0, 0x0, 0xFD]); + expect(buff).toStrictEqual(result); + // TODO: + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeInt8(5,10); + }).toThrow(); + }); + + test("#writeUInt8", () => { + let buff = new Buffer(5); + expect(buff.writeUInt8(4)).toBe(1); + expect(buff.writeUInt8(252,4)).toBe(5); + let result = create([0x04, 0x0, 0x0, 0x0, 0xFC]); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeUInt8(5,10); + }).toThrow(); + }); + + test("#readInt16LE", () => { + let buff = create([0x0,0x05,0x0]); + expect(buff.readInt16LE()).toBe(1280); + expect(buff.readInt16LE(1)).toBe(5); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readInt16LE(0); + }).toThrow(); + }); + + test("#readInt16BE", () => { + let buff = create([0x0,0x05,0x0]); + expect(buff.readInt16BE()).toBe(5); + expect(buff.readInt16BE(1)).toBe(1280); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readInt16BE(0); + }).toThrow(); + }); + + test("#readUInt16LE", () => { + let buff = create([0x0,0x05,0x0]); + expect(buff.readUInt16LE()).toBe(1280); + expect(buff.readUInt16LE(1)).toBe(5); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readUInt16LE(0); + }).toThrow(); + }); + + test("#readUInt16BE", () => { + let buff = create([0x0,0x05,0x0]); + expect(buff.readUInt16BE()).toBe(5); + expect(buff.readUInt16BE(1)).toBe(1280); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readUInt16BE(0); + }).toThrow(); + }); + + test("#writeInt16LE", () => { + let buff = new Buffer(4); + expect(buff.writeInt16LE(5)).toBe(2); + expect(buff.writeInt16LE(1280,2)).toBe(4); + let result = create([0x05, 0x0, 0x0, 0x5]); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeInt16LE(0); + }).toThrow(); + }); + + test("#writeInt16BE", () => { + let buff = new Buffer(4); + expect(buff.writeInt16BE(1280)).toBe(2); + expect(buff.writeInt16BE(5,2)).toBe(4); + let result = create([0x05, 0x0, 0x0, 0x5]); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeInt16BE(0); + }).toThrow(); + }); + + test("#writeUInt16LE", () => { + let buff = new Buffer(4); + expect(buff.writeUInt16LE(5)).toBe(2); + expect(buff.writeUInt16LE(1280,2)).toBe(4); + let result = create([0x05, 0x0, 0x0, 0x5]); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeUInt16LE(0); + }).toThrow(); + }); + + test("#writeUInt16BE", () => { + let buff = new Buffer(4); + expect(buff.writeUInt16BE(1280)).toBe(2); + expect(buff.writeUInt16BE(5,2)).toBe(4); + let result = create([0x05, 0x0, 0x0, 0x5]); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeUInt16BE(0); + }).toThrow(); + }); + + test("#readInt32LE", () => { + let buff = create([0xEF,0xBE,0xAD,0xDE,0x0d,0xc0,0xde,0x10]); + expect(buff.readInt32LE()).toBe(-559038737); + expect(buff.readInt32LE(4)).toBe(283033613); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readInt32LE(0); + }).toThrow(); + }); + + test("#readInt32BE", () => { + let buff = create([0xDE,0xAD,0xBE,0xEF,0x10,0xde,0xc0,0x0d]); + expect(buff.readInt32BE()).toBe(-559038737); + expect(buff.readInt32BE(4)).toBe(283033613); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readInt32BE(0); + }).toThrow(); + }); + + test("#readUInt32LE", () => { + let buff = create([0xEF,0xBE,0xAD,0xDE,0x0d,0xc0,0xde,0x10]); + expect(buff.readUInt32LE()).toBe(3735928559); + expect(buff.readUInt32LE(4)).toBe(283033613); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readUInt32LE(0); + }).toThrow(); + }); + + test("#readUInt32BE", () => { + let buff = create([0xDE,0xAD,0xBE,0xEF,0x10,0xde,0xc0,0x0d]); + expect(buff.readUInt32BE()).toBe(3735928559); + expect(buff.readUInt32BE(4)).toBe(283033613); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readUInt32BE(0); + }).toThrow(); + }); + + test("#writeInt32LE", () => { + let buff = new Buffer(8); + expect(buff.writeInt32LE(-559038737)).toBe(4); + expect(buff.writeInt32LE(283033613,4)).toBe(8); + let result = create([0xEF,0xBE,0xAD,0xDE,0x0d,0xc0,0xde,0x10]); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeInt32LE(0); + }).toThrow(); + }); + + test("#writeInt32BE", () => { + let buff = new Buffer(8); + expect(buff.writeInt32BE(-559038737)).toBe(4); + expect(buff.writeInt32BE(283033613,4)).toBe(8); + let result = create([0xDE,0xAD,0xBE,0xEF,0x10,0xde,0xc0,0x0d]); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeInt32BE(0); + }).toThrow(); + }); + + test("#writeUInt32LE", () => { + let buff = new Buffer(8); + expect(buff.writeUInt32LE(3735928559)).toBe(4); + expect(buff.writeUInt32LE(283033613,4)).toBe(8); + let result = create([0xEF,0xBE,0xAD,0xDE,0x0d,0xc0,0xde,0x10]);; + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeUInt32LE(0); + }).toThrow(); + }); + + test("#writeUInt32BE", () => { + let buff = new Buffer(8); + expect(buff.writeUInt32BE(3735928559)).toBe(4); + expect(buff.writeUInt32BE(283033613,4)).toBe(8); + let result = create([0xDE,0xAD,0xBE,0xEF,0x10,0xde,0xc0,0x0d]); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeUInt32BE(0); + }).toThrow(); + }); + + test("#readFloatLE", () => { + let buff = create([0xbb,0xfe,0x4a,0x4f,0x01,0x02,0x03,0x04]); + expect(buff.readFloatLE()).toBe(0xcafebabe); + expect(buff.readFloatLE(4)).toBe(1.539989614439558e-36); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readFloatLE(0); + }).toThrow(); + }); + + test("#readFloatBE", () => { + let buff = create([0x4f,0x4a,0xfe,0xbb,0x01,0x02,0x03,0x04]); + expect(buff.readFloatBE()).toBe(0xcafebabe); + expect(buff.readFloatBE(4)).toBe(2.387939260590663e-38); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readFloatBE(0); + }).toThrow(); + }); + + test("#writeFloatLE", () => { + let buff = new Buffer(8); + expect(buff.writeFloatLE(0xcafebabe)).toBe(4); + expect(buff.writeFloatLE(1.539989614439558e-36,4)).toBe(8); + let result = create([0xbb,0xfe,0x4a,0x4f,0x01,0x02,0x03,0x04]); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeFloatLE(0); + }).toThrow(); + }); + + test("#writeFloatBE", () => { + let buff = new Buffer(8); + expect(buff.writeFloatBE(0xcafebabe)).toBe(4); + expect(buff.writeFloatBE(2.387939260590663e-38,4)).toBe(8); + let result = create([0x4f,0x4a,0xfe,0xbb,0x01,0x02,0x03,0x04]); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeFloatBE(0); + }).toThrow(); + }); + + test("#readBigInt64LE", () => { + let buff = create([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00]); + expect(buff.readBigInt64LE()).toBe(-4294967296); + expect(buff.readBigInt64LE(8)).toBe(4294967295); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readBigInt64LE(0); + }).toThrow(); + }); + + test("#readBigInt64BE", () => { + let buff = create([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00]); + expect(buff.readBigInt64BE()).toBe(4294967295); + expect(buff.readBigInt64BE(8)).toBe(-4294967296); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readBigInt64BE(0); + }).toThrow(); + }); + + test("#readBigUInt64LE", () => { + let buff = create([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00]); + expect(buff.readBigUInt64LE()).toBe(18446744069414584320); + expect(buff.readBigUInt64LE(8)).toBe(4294967295); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readBigUInt64LE(0); + }).toThrow(); + }); + + test("#readBigUInt64BE", () => { + let buff = create([0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00]); + expect(buff.readBigUInt64BE()).toBe(4294967295); + expect(buff.readBigUInt64BE(8)).toBe(18446744069414584320); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readBigUInt64BE(0); + }).toThrow(); + }); + + test("#writeBigInt64LE", () => { + let buff = new Buffer(16); + expect(buff.writeBigInt64LE(-559038737)).toBe(8); + expect(buff.writeBigInt64LE(283033613,8)).toBe(16); + let result = create([0xEF,0xBE,0xAD,0xDE,0xFF,0xFF,0xFF,0xFF,0x0d,0xc0,0xde,0x10,0x00,0x00,0x00,0x00]); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeBigInt64LE(0); + }).toThrow(); + }); + + test("#writeBigInt64BE", () => { + let buff = new Buffer(16); + expect(buff.writeBigInt64BE(-559038737)).toBe(8); + expect(buff.writeBigInt64BE(283033613,8)).toBe(16); + let result = create([0xFF,0xFF,0xFF,0xFF,0xDE,0xAD,0xBE,0xEF,0x00,0x00,0x00,0x00,0x10,0xde,0xc0,0x0d]); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeBigInt64BE(0); + }).toThrow(); + }); + + test("#writeBigUInt64LE", () => { + let buff = new Buffer(16); + expect(buff.writeBigUInt64LE(3735928559)).toBe(8); + expect(buff.writeBigUInt64LE(283033613,8)).toBe(16); + let result = create([0xEF,0xBE,0xAD,0xDE,0x00,0x00,0x00,0x00,0x0d,0xc0,0xde,0x10,0x00,0x00,0x00,0x00]); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeBigUInt64LE(0); + }).toThrow(); + }); + + test("#writeBigUInt64BE", () => { + let buff = new Buffer(16); + expect(buff.writeBigUInt64BE(3735928559)).toBe(8); + expect(buff.writeBigUInt64BE(283033613,8)).toBe(16); + let result = create([0x00,0x00,0x00,0x00,0xDE,0xAD,0xBE,0xEF,0x00,0x00,0x00,0x00,0x10,0xde,0xc0,0x0d]); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeBigUInt64BE(0); + }).toThrow(); + }); + + test("#readDoubleLE", () => { + let buff = create([0x77, 0xbe, 0x9f, 0x1a, 0x2f, 0xdd, 0x5e, 0x40, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]); + expect(buff.readDoubleLE()).toBe(123.456); + expect(buff.readDoubleLE(8)).toBe(5.447603722011605e-270); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readDoubleLE(0); + }).toThrow(); + }); + + test("#readDoubleBE", () => { + let buff = create([0x40, 0x5e, 0xdd, 0x2f, 0x1a, 0x9f, 0xbe, 0x77, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]); + expect(buff.readDoubleBE()).toBe(123.456); + expect(buff.readDoubleBE(8)).toBe(8.20788039913184e-304); + expect(() => { + let newBuff = new Buffer(1); + newBuff.readDoubleBE(0); + }).toThrow(); + }); + + test("#writeDoubleLE", () => { + let buff = new Buffer(16); + expect(buff.writeDoubleLE(123.456)).toBe(8); + expect(buff.writeDoubleLE(5.447603722011605e-270,8)).toBe(16); + let result = create([0x77, 0xbe, 0x9f, 0x1a, 0x2f, 0xdd, 0x5e, 0x40, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeDoubleLE(0); + }).toThrow(); + }); + + test("#writeDoubleBE", () => { + let buff = new Buffer(16); + expect(buff.writeDoubleBE(123.456)).toBe(8); + expect(buff.writeDoubleBE(8.20788039913184e-304,8)).toBe(16); + let result = create([0x40, 0x5e, 0xdd, 0x2f, 0x1a, 0x9f, 0xbe, 0x77, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]); + expect(buff).toStrictEqual(result); + expect(() => { + let newBuff = new Buffer(1); + newBuff.writeDoubleBE(0); + }).toThrow(); + }); + + test("#subarray", () => { + let example = create([1, 2, 3, 4, 5, 6, 7, 8]); + + // no parameters means copy the Buffer + let actual = example.subarray(); + expect(actual).toStrictEqual(example); + expect(actual.buffer).toBe(example.buffer); // should use the same buffer + + // start at offset 5 + actual = example.subarray(5); + let expected = create([6, 7, 8]); + // trace("length", 1, expected.length); + expect(actual).toStrictEqual(expected); + + // negative start indicies, start at (8 - 5) + actual = example.subarray(-5); + expected = create([4, 5, 6, 7, 8]); + expect(actual).toStrictEqual(expected); + + // two parameters + actual = example.subarray(2, 6); + expected = create([3, 4, 5, 6]); + expect(actual).toStrictEqual(expected); + + // negative end index + actual = example.subarray(4, -1); + expected = create([5, 6, 7]); + expect(actual).toStrictEqual(expected); + }); + + test("#swap16", () => { + let actual = create([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]); + let expected = create([0x2, 0x1, 0x4, 0x3, 0x6, 0x5, 0x8, 0x7]); + let swapped = actual.swap16(); + expect(actual).toStrictEqual(expected); + expect(swapped).toBe(actual); + expect(() => { + let newBuff = create([0x1, 0x2, 0x3]); + newBuff.swap16(); + }).toThrow(); + }); + + test("#swap32", () => { + let actual = create([0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8]); + let expected = create([0x4, 0x3, 0x2, 0x1, 0x8, 0x7, 0x6, 0x5]); + let swapped = actual.swap32(); + expect(actual).toStrictEqual(expected); + expect(swapped).toBe(actual); + expect(() => { + let newBuff = create([0x1, 0x2, 0x3]); + newBuff.swap64(); + }).toThrow(); + }); + + test("#swap64", () => { + let actual = create([0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf]); + let expected = create([0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0, 0xf, 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x8]); + let swapped = actual.swap64(); + expect(actual).toStrictEqual(expected); + expect(swapped).toBe(actual); + expect(() => { + let newBuff = create([0x1, 0x2, 0x3]); + newBuff.swap64(); + }).toThrow(); + }); + + test("#Hex.encode", () => { + let actual = "000102030405060708090a0b0c0d0e0f102030405060708090a0b0c0d0e0f0"; + let exampleBuffer = create([0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0]); + let encoded = Buffer.HEX.encode(actual); + expect(encoded).toStrictEqual(exampleBuffer.buffer); + }); + + test("#Hex.decode", () => { + let expected = "000102030405060708090a0b0c0d0e0f102030405060708090a0b0c0d0e0f0"; + let exampleBuffer = create([0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0]); + let decoded = Buffer.HEX.decode(exampleBuffer.buffer); + expect(decoded).toStrictEqual(expected); + }); + + test("#ASCII.encode", () => { + let actual = "D34dB3eF"; + let exampleBuffer = create([0x44, 0x33, 0x34, 0x64, 0x42, 0x33, 0x65, 0x46]); + let encoded = Buffer.ASCII.encode(actual); + expect(encoded).toStrictEqual(exampleBuffer.buffer); + }); + + test("#ASCII.decode", () => { + let expected = create([0x44, 0x33, 0x34, 0x64, 0x42, 0x33, 0x65, 0x46]); + let example = "D34dB3eF"; + let encoded = Buffer.ASCII.decode(expected.buffer); + expect(encoded).toStrictEqual(example); }); }); diff --git a/tests/fs.spec.ts b/tests/fs.spec.ts new file mode 100644 index 0000000..84315f6 --- /dev/null +++ b/tests/fs.spec.ts @@ -0,0 +1,3 @@ +test("an empty test", () => { + +}); diff --git a/tests/fs.spec.wasi.js b/tests/fs.spec.wasi.js new file mode 100644 index 0000000..afa6f72 --- /dev/null +++ b/tests/fs.spec.wasi.js @@ -0,0 +1,7 @@ +module.exports = { + env: process.env, + argv: process.argv, + preopens: { + "./tests/sandbox": "./tests/sandbox" + } +}; diff --git a/tests/node.js b/tests/node.js index 5117ef9..f6b7e5e 100644 --- a/tests/node.js +++ b/tests/node.js @@ -1,13 +1,15 @@ -const { TestContext, EmptyReporter } = require("@as-pect/core"); -const { instantiateBuffer } = require("assemblyscript/lib/loader"); +const { TestContext, VerboseReporter } = require("@as-pect/core"); const glob = require("glob"); +const { instantiateSync } = require("assemblyscript/lib/loader"); const { main } = require("assemblyscript/cli/asc"); const { parse } = require("assemblyscript/cli/util/options"); const path = require("path"); -const fs = require("fs"); -const Wasi = require("wasi"); -const wasi = new Wasi({}); -const diff = require("diff"); +const fssync = require("fs"); +const fs = fssync.promises; +const { WASI } = require("wasi"); + +const promises = []; +let pass = true; const options = parse(process.argv.slice(2), { "help": { @@ -20,6 +22,12 @@ const options = parse(process.argv.slice(2), { "type": "b", "alias": "u" }, + "preopens": { + "description": "A set of preopened directories for wasi. Ex. ./dir=./dir", + "type": "S", + "alias": "p", + "default": [], + }, }); if (options.unknown.length > 1) { @@ -27,41 +35,19 @@ if (options.unknown.length > 1) { process.exit(1); } -class Reporter extends EmptyReporter { - onGroupFinish(group) { - if (group.name) { - if (group.pass) process.stdout.write("Group : " + group.name + " -> ✔ PASS"); - else process.stdout.write("Group : " + group.name + " -> ❌ FAIL"); - process.stdout.write("\n"); - } - } - - onTestFinish(group, test) { - if (test.pass) process.stdout.write("Test : " + group.name + " -> " + test.name + " ✔ PASS\n"); - else process.stdout.write("Test : " + group.name + " -> " + test.name + " ❌ FAIL\n"); - - if (!test.pass) { - process.stdout.write("Actual : " + test.actual.message + "\n"); - process.stdout.write("Expected : " + test.expected.message + "\n"); - } - - if (test.logs.length > 0) { - test.logs.forEach((e, i) => { - if (i > 0) process.stdout.write("\n"); - process.stdout.write("Log : " + e.value); - }); - process.stdout.write("\n"); - } - } - onFinish(context) { - const passed = context.testGroups.filter(e => !e.pass).length === 0; - if (passed) process.stdout.write("Suite : ✔ PASS"); - else process.stdout.write("Suite : ❌ FAIL"); - process.stdout.write("\n"); - } -} +// calculate default preopens from cli +const preopens = options.options.preopens.reduce( + (obj, value) => { + const [_, dir1, dir2] = /([^=])*=(.*)/.exec(value); + obj[dir1] = dir2; + return obj; + }, + {} +); -const reporter = new Reporter(); +const reporter = new VerboseReporter(); +reporter.stderr = process.stderr; +reporter.stdout = process.stdout; function relativeFromCwd(location) { return path.relative(process.cwd(), location); @@ -71,10 +57,9 @@ const ascOptions = [ relativeFromCwd(require.resolve("@as-pect/assembly/assembly/index.ts")), "--use", "ASC_RTRACE=1", "--explicitStart", - "--validate", - "--debug", "--measure", "--lib", "assembly", + "--transform", require.resolve("@as-pect/core/lib/transform/index.js"), ]; const files = glob.sync("tests/**/*.spec.ts") @@ -108,10 +93,15 @@ for (const file of files) { const ext = path.extname(file); const wasmFileName = path.join(path.dirname(file), path.basename(file, ext)) + ".wasm"; const watFileName = path.join(path.dirname(file), path.basename(file, ext)) + ".wat"; - const cliOptions = ascOptions.concat([file, "--binaryFile", wasmFileName, "--textFile", watFileName]); + + const cliOptions = ascOptions.concat([ + file, + "--binaryFile", wasmFileName, + "--textFile", watFileName, + ]); process.stdout.write("Test File : " + file + " (untouched)\n"); - main(cliOptions, untouchedAscOptions, (err) => { + main(cliOptions.concat(["--debug"]), untouchedAscOptions, (err) => { if (err) { console.error(err); errors.push(err); @@ -138,18 +128,56 @@ for (const file of files) { process.stdout.write("\n"); } -function runTest(file, type, binary, wat) { +function runTest(fileName, type, binary, wat) { + const dirname = path.dirname(fileName); + const basename = path.basename(fileName, ".ts"); + const fullName = path.join(dirname, basename) + const watPath = `${fullName}.${type}.wat`; + const wasiPath = `${fullName}.wasi.js`; + const fileNamePath = `${fullName}.${type}.ts`; + + // use either a custom wasi configuration, or the default one + const wasiOptions = fssync.existsSync(wasiPath) + ? require(path.resolve(wasiPath)) + : { + args: process.argv, + env: process.env, + preopens, + }; + + // should not block testing + promises.push(fs.writeFile(watPath, wat)); + + const wasi = new WASI(wasiOptions); + const context = new TestContext({ - fileName: file, - reporter, - stderr: process.stderr, - stdout: process.stdout, + fileName: fileNamePath, // set the fileName + reporter, // use verbose reporter + binary, // pass the binary to get function names + wasi, }); + const imports = context.createImports({ - wasi_unstable: wasi.exports, + wasi_snapshot_preview1: wasi.wasiImport, }); - const wasm = instantiateBuffer(binary, imports); - wasi.setMemory(wasm.memory); - wasi.view = new DataView(wasm.memory.buffer); - context.run(wasm); + + const instance = instantiateSync(binary, imports); + + process.stdout.write("\n"); + context.run(instance); + + if (!context.pass) pass = false; } + +// await for all the file writes to occur for the wat files +Promise.all(promises) + .then(() => { + // if the file writes were successful, inspect errors and pass + process.exit(pass && errors.length === 0 ? 0 : 1); + }) + .catch((error) => { + // report the file write error and exit 1 + console.error(error); + process.exit(1); + }); + diff --git a/tests/sandbox/test.txt b/tests/sandbox/test.txt new file mode 100644 index 0000000..e69de29