From 52d992c7e82a87b6a6d430ce565fad14ed7952c6 Mon Sep 17 00:00:00 2001 From: Louis Pilfold Date: Mon, 10 Apr 2023 10:28:56 +0100 Subject: [PATCH] PMap property test --- .vscode/settings.json | 3 ++ deno.jsonc | 10 +++++ deno.lock | 11 ++++++ properties/main_test.ts | 76 +++++++++++++++++++++++++++++++++++++ src/persistent-hash-map.mjs | 3 +- test/gleam/map_test.gleam | 14 +++++++ 6 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 deno.jsonc create mode 100644 deno.lock create mode 100644 properties/main_test.ts diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..cbac5697 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "deno.enable": true +} diff --git a/deno.jsonc b/deno.jsonc new file mode 100644 index 00000000..6cb36e86 --- /dev/null +++ b/deno.jsonc @@ -0,0 +1,10 @@ +{ + "tasks": { + "test": "deno test" + }, + "test": { + "files": { + "exclude": ["src/", "build/"] + } + } +} diff --git a/deno.lock b/deno.lock new file mode 100644 index 00000000..d6f2a4e3 --- /dev/null +++ b/deno.lock @@ -0,0 +1,11 @@ +{ + "version": "2", + "remote": { + "https://cdn.skypack.dev/-/base64-js@v1.5.1-W9sqY0mF5INkRg7HAvxn/dist=es2019,mode=imports/optimized/base64-js.js": "4566964bb37bf2a057d872b75540c57b181afddb4d1a3360e8f25e9f98259f50", + "https://cdn.skypack.dev/-/buffer@v6.0.3-9TXtXoOPyENPVOx2wqZk/dist=es2019,mode=imports/optimized/buffer.js": "5a22e1261b940a44afc1294308fd878c87d44af792552cb3042cbbb0217461dd", + "https://cdn.skypack.dev/-/fast-check@v3.8.0-U4avbB5v775QpW4w1Uh8/dist=es2019,mode=imports/optimized/fast-check.js": "673cb5a18367e9a9ce8a4a587d05d76383fc6d45c70c16431ad1358ea15e3d7e", + "https://cdn.skypack.dev/-/ieee754@v1.2.1-wxdRuKvQQOTpW1dpWzFI/dist=es2019,mode=imports/optimized/ieee754.js": "d2f73784b95c354f399103302c65c5d0fe52bc869379d322a0b2e1185d2ad3f8", + "https://cdn.skypack.dev/-/pure-rand@v6.0.1-KvQkqCnRiKNyIC849MPk/dist=es2019,mode=imports/optimized/pure-rand.js": "6e69f9dd41453a1065cc69b4597ebb33891f88ea0ce25fcc4c171e76f0fd769d", + "https://cdn.skypack.dev/fast-check": "51c7664b6c79f7b5fd64edcc3f1325e4ca6dabe4cf125858a925f41e467b52d0" + } +} diff --git a/properties/main_test.ts b/properties/main_test.ts new file mode 100644 index 00000000..669e1d98 --- /dev/null +++ b/properties/main_test.ts @@ -0,0 +1,76 @@ +import fc from "https://cdn.skypack.dev/fast-check"; +import PMap from "../build/dev/javascript/gleam_stdlib/persistent-hash-map.mjs"; + +const options = Object.freeze({ + numRuns: 1000_000, +}); + +Deno.test("all inserted numbers must exist within", () => { + const property = (numbers: Array) => { + let map = PMap.new(); + + // Insert all numbers + for (const number of numbers) { + map = map.set(number, 1); + } + + // Check that all numbers are in the map + for (const number of numbers) { + if (!map.has(number)) { + console.log(`Number ${number} not found`); + return false; + } + } + }; + + const arbitrary = fc.array(fc.integer()); + fc.assert(fc.property(arbitrary, property), options); +}); + +Deno.test("all inserted values can be got", () => { + const property = (numbers: Array<[number, number]>) => { + const reference = new Map(); + let map = PMap.new(); + + // Insert all pairs + for (const [k, v] of numbers) { + reference.set(k, v); + map = map.set(k, v); + } + + // Check that all keys have the correct value + for (const [k, _] of numbers) { + const expected = reference.get(k); + const found = map.get(k, undefined); + if (found !== expected) { + console.log(`${k} was ${found} not ${expected}`); + return false; + } + } + }; + + const arbitrary = fc.array(fc.tuple(fc.integer(), fc.integer())); + fc.assert(fc.property(arbitrary, property), options); +}); + +Deno.test("size", () => { + const property = (numbers: Array) => { + const reference = new Map(); + let map = PMap.new(); + + // Insert all values + for (const k of numbers) { + reference.set(k, 1); + map = map.set(k, 1); + } + + // Map size should match reference + if (map.size !== reference.size) { + console.log(`size was ${map.size} not ${reference.size}`); + return false; + } + }; + + const arbitrary = fc.array(fc.integer()); + fc.assert(fc.property(arbitrary, property), options); +}); diff --git a/src/persistent-hash-map.mjs b/src/persistent-hash-map.mjs index 911da056..ff849d8d 100644 --- a/src/persistent-hash-map.mjs +++ b/src/persistent-hash-map.mjs @@ -77,7 +77,7 @@ function hashObject(o) { try { const code = o.hashCode(o); if (typeof code === "number") { - return code + return code; } } catch {} } @@ -955,4 +955,3 @@ export default class PMap { return equal; } } - diff --git a/test/gleam/map_test.gleam b/test/gleam/map_test.gleam index 5cfb37d1..75fb78d5 100644 --- a/test/gleam/map_test.gleam +++ b/test/gleam/map_test.gleam @@ -361,3 +361,17 @@ pub fn peters_bug_test() { |> map.get(0) |> should.equal(Error(Nil)) } + +pub fn zero_must_be_contained_test() { + let map = + map.new() + |> map.insert(0, Nil) + + map + |> map.get(0) + |> should.equal(Ok(Nil)) + + map + |> map.has_key(0) + |> should.equal(True) +}