diff options
Diffstat (limited to 'test/bun.js')
-rw-r--r-- | test/bun.js/napi-test.c | 3 | ||||
-rw-r--r-- | test/bun.js/napi.test.ts | 0 | ||||
-rwxr-xr-x | test/bun.js/third-party/napi_create_external/bun.lockb | bin | 0 -> 1584 bytes | |||
-rw-r--r-- | test/bun.js/third-party/napi_create_external/napi-create-external.test.ts | 199 | ||||
-rw-r--r-- | test/bun.js/third-party/napi_create_external/package.json | 12 |
5 files changed, 214 insertions, 0 deletions
diff --git a/test/bun.js/napi-test.c b/test/bun.js/napi-test.c new file mode 100644 index 000000000..dac40c83d --- /dev/null +++ b/test/bun.js/napi-test.c @@ -0,0 +1,3 @@ +#include "../../src/napi/node_api.h" + +void
\ No newline at end of file diff --git a/test/bun.js/napi.test.ts b/test/bun.js/napi.test.ts new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/test/bun.js/napi.test.ts diff --git a/test/bun.js/third-party/napi_create_external/bun.lockb b/test/bun.js/third-party/napi_create_external/bun.lockb Binary files differnew file mode 100755 index 000000000..f091c506b --- /dev/null +++ b/test/bun.js/third-party/napi_create_external/bun.lockb diff --git a/test/bun.js/third-party/napi_create_external/napi-create-external.test.ts b/test/bun.js/third-party/napi_create_external/napi-create-external.test.ts new file mode 100644 index 000000000..055b488f9 --- /dev/null +++ b/test/bun.js/third-party/napi_create_external/napi-create-external.test.ts @@ -0,0 +1,199 @@ +import { test, it, describe, expect } from "bun:test"; +import * as _ from "lodash"; + +function rebase(str, inBase, outBase) { + const mapBase = (b) => (b === 2 ? 32 : b === 16 ? 8 : null); + const stride = mapBase(inBase); + const pad = mapBase(outBase); + if (!stride) throw new Error(`Bad inBase ${inBase}`); + if (!pad) throw new Error(`Bad outBase ${outBase}`); + if (str.length % stride) throw new Error(`Bad string length ${str.length}`); + const out = []; + for (let i = 0; i < str.length; i += stride) + out.push( + parseInt(str.slice(i, i + stride), inBase) + .toString(outBase) + .padStart(pad, "0"), + ); + return out.join(""); +} + +function expectDeepEqual(a, b) { + expect(JSON.stringify(a)).toBe(JSON.stringify(b)); +} +class HashMaker { + constructor(length) { + this.length = length; + this._dist = {}; + } + length: number; + _dist: any; + + binToHex(binHash) { + if (binHash.length !== this.length) + throw new Error( + `Hash length mismatch ${this.length} != ${binHash.length}`, + ); + return rebase(binHash, 2, 16); + } + + makeBits() { + const bits = []; + for (let i = 0; i < this.length; i++) bits.push(i); + return _.shuffle(bits); + } + + makeRandom() { + const bits = []; + for (let i = 0; i < this.length; i++) + bits.push(Math.random() < 0.5 ? 1 : 0); + return bits; + } + + get keySet() { + return (this._set = this._set || new Set(this.data)); + } + + randomKey() { + while (true) { + const hash = this.binToHex(this.makeRandom().join("")); + if (!this.keySet.has(hash)) return hash; + } + } + + get data() { + return (this._data = + this._data || + (() => { + const bits = this.makeBits(); + const base = this.makeRandom(); + const data = []; + for (let stride = 0; bits.length; stride++) { + const flip = bits.splice(0, stride); + for (const bit of flip) base[bit] = 1 - base[bit]; + data.push(this.binToHex(base.join(""))); + } + return data; + })()); + } + + get random() { + const d = this.data; + return d[Math.floor(Math.random() * d.length)]; + } + + distance(a, b) { + const bitCount = (n) => { + n = n - ((n >> 1) & 0x55555555); + n = (n & 0x33333333) + ((n >> 2) & 0x33333333); + return (((n + (n >> 4)) & 0xf0f0f0f) * 0x1010101) >> 24; + }; + + if (a === b) return 0; + if (a > b) return this.distance(b, a); + const hash = a + "-" + b; + return (this._dist[hash] = + this._dist[hash] || + (() => { + let dist = 0; + for (let i = 0; i < a.length; i += 8) { + const va = parseInt(a.slice(i, i + 8), 16); + const vb = parseInt(b.slice(i, i + 8), 16); + dist += bitCount(va ^ vb); + } + return dist; + })()); + } + + query(baseKey, maxDist) { + const out = []; + for (const key of this.data) { + const distance = this.distance(key, baseKey); + if (distance <= maxDist) out.push({ key, distance }); + } + return out.sort((a, b) => a.distance - b.distance); + } +} + +const treeClass = require("bktree-fast/native"); + +for (let keyLen = 64; keyLen <= 512; keyLen += 64) { + const hm = new HashMaker(keyLen); + describe(`Key length: ${keyLen}`, () => { + it("should compute distance", () => { + const tree = new treeClass(keyLen); + for (const a of hm.data) + for (const b of hm.data) + expect(tree.distance(a, b)).toBe(hm.distance(a, b)); + }); + + it("should know which keys it has", () => { + const tree = new treeClass(keyLen).add(hm.data); + expectDeepEqual( + hm.data.map((hash) => tree.has(hash)), + hm.data.map(() => true), + ); + // Not interested in the hash + for (const hash of hm.data) expect(tree.has(hm.randomKey())).toBe(false); + }); + + it("should know the tree size", () => { + const tree = new treeClass(keyLen, { foo: 1 }); + expect(tree.size).toBe(0); + tree.add(hm.data); + expect(tree.size).toBe(hm.data.length); + tree.add(hm.data); + expect(tree.size).toBe(hm.data.length); + }); + + it("should walk the tree", () => { + const tree = new treeClass(keyLen).add(hm.data); + const got = []; + tree.walk((hash, depth) => got.push(hash)); + expectDeepEqual(got.sort(), hm.data.slice(0).sort()); + }); + + it("should query", () => { + Bun.gc(true); + ((treeClass, expectDeepEqual) => { + const tree = new treeClass(keyLen).add(hm.data); + + for (let dist = 0; dist <= hm.length; dist++) { + for (const baseKey of [hm.random, hm.data[0]]) { + const baseKey = hm.random; + const got = []; + tree.query(baseKey, dist, (key, distance) => + got.push({ key, distance }), + ); + const want = hm.query(baseKey, dist); + expectDeepEqual( + got.sort((a, b) => a.distance - b.distance), + want, + ); + expectDeepEqual(tree.find(baseKey, dist), want); + } + } + })(treeClass, expectDeepEqual); + Bun.gc(true); + }); + }); +} + +describe("Misc functions", () => { + it("should pad keys", () => { + const tree = new treeClass(64); + expect(tree.padKey("1")).toBe("0000000000000001"); + tree.add(["1", "2", "3"]); + + const got = []; + tree.query("2", 3, (hash, distance) => got.push({ hash, distance })); + const res = got.sort((a, b) => a.distance - b.distance); + const want = [ + { hash: "0000000000000002", distance: 0 }, + { hash: "0000000000000003", distance: 1 }, + { hash: "0000000000000001", distance: 2 }, + ]; + + expectDeepEqual(res, want); + }); +}); diff --git a/test/bun.js/third-party/napi_create_external/package.json b/test/bun.js/third-party/napi_create_external/package.json new file mode 100644 index 000000000..82b0ef58d --- /dev/null +++ b/test/bun.js/third-party/napi_create_external/package.json @@ -0,0 +1,12 @@ +{ + "name": "napi-create-external-test", + "version": "1.0.0", + "description": "Test for napi_create_external", + "dependencies": { + "bktree-fast": "0.0.7", + "lodash": "^4.17.21" + }, + "scripts": { + "postinstall": "cd node_modules/bktree-fast && node-gyp configure" + } +} |