From ec649bd8bbbbc7f1cdf02ed5eabc15261206bd82 Mon Sep 17 00:00:00 2001 From: Revone Date: Sat, 30 Dec 2023 11:49:59 +0800 Subject: [PATCH] test: reorgnization. docs: improved a lit bit --- CHANGELOG.md | 2 +- README.md | 26 +- .../data-structures/hash/hash-map.test.ts | 764 +++++++++--------- 3 files changed, 396 insertions(+), 396 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bad3641..78a8dd5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ All notable changes to this project will be documented in this file. - [Semantic Versioning](https://semver.org/spec/v2.0.0.html) - [`auto-changelog`](https://github.com/CookPete/auto-changelog) -## [v1.50.0](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming) +## [v1.50.1](https://github.com/zrwusa/data-structure-typed/compare/v1.35.0...main) (upcoming) ### Changes diff --git a/README.md b/README.md index 04d4b67..a17da64 100644 --- a/README.md +++ b/README.md @@ -38,58 +38,58 @@ Heap, Binary Tree, Red Black Tree, Linked List, Deque, Trie, Directed Graph, Und Method - Time Taken (ms) - Scale + Time Taken + Data Scale Belongs To - Time Complexity + Complexity Queue.push & shift - 5.83 + 5.83 ms 100,000 - data-structure-typed + Ours O(1) Array.push & shift - 2829.59 + 2829.59 ms 100,000 Native JS O(n) Deque.unshift & shift - 2.44 + 2.44 ms 100,000 - data-structure-typed + Ours O(1) Array.unshift & shift - 4750.37 + 4750.37 ms 100,000 Native JS O(n) HashMap.set - 122.51 + 122.51 ms 1,000,000 - data-structure-typed + Ours O(1) Map.set - 223.80 + 223.80 ms 1,000,000 Native JS O(1) Set.add - 185.06 + 185.06 ms 1,000,000 Native JS O(1) diff --git a/test/unit/data-structures/hash/hash-map.test.ts b/test/unit/data-structures/hash/hash-map.test.ts index 5591dd2..fe23133 100644 --- a/test/unit/data-structures/hash/hash-map.test.ts +++ b/test/unit/data-structures/hash/hash-map.test.ts @@ -1,7 +1,7 @@ import { HashMap, LinkedHashMap } from '../../../../src'; import { getRandomInt, getRandomIntArray } from '../../../utils'; -describe('HashMap Test1', () => { +describe('HashMap', () => { let hashMap: HashMap; beforeEach(() => { @@ -84,335 +84,233 @@ describe('HashMap Test1', () => { // Make sure they are stored separately. // expect(hashMap.table[0].length).toBe(2); }); -}); -describe('HashMap Test2', () => { - let hashMap: HashMap; + describe('HashMap Test2', () => { + let hashMap: HashMap; - beforeEach(() => { - hashMap = new HashMap(); - }); + beforeEach(() => { + hashMap = new HashMap(); + }); - it('should create an empty map', () => { - expect(hashMap.size).toBe(0); - }); + it('should create an empty map', () => { + expect(hashMap.size).toBe(0); + }); - it('should add a key-value pair', () => { - hashMap.set('key1', 'value1'); - expect(hashMap.get('key1')).toBe('value1'); - }); + it('should add a key-value pair', () => { + hashMap.set('key1', 'value1'); + expect(hashMap.get('key1')).toBe('value1'); + }); - it('should handle object keys correctly', () => { - const keyObj = { id: 1 }; - hashMap.set(keyObj, 'objectValue'); - expect(hashMap.get(keyObj)).toBe('objectValue'); - }); + it('should handle object keys correctly', () => { + const keyObj = { id: 1 }; + hashMap.set(keyObj, 'objectValue'); + expect(hashMap.get(keyObj)).toBe('objectValue'); + }); - test('Inheritability test', () => { - class ExtendedHashMap extends HashMap { - someOtherParam?: string; + test('Inheritability test', () => { + class ExtendedHashMap extends HashMap { + someOtherParam?: string; - constructor( - elements: Iterable<[K, V]> = [], - options?: { - hashFn?: (key: K) => string; - someOtherParam: string; + constructor( + elements: Iterable<[K, V]> = [], + options?: { + hashFn?: (key: K) => string; + someOtherParam: string; + } + ) { + const { someOtherParam, ...restOptions } = options || {}; + super(elements, restOptions); + this.someOtherParam = someOtherParam; } - ) { - const { someOtherParam, ...restOptions } = options || {}; - super(elements, restOptions); - this.someOtherParam = someOtherParam; } - } - const eHM = new ExtendedHashMap([], { someOtherParam: 'someOtherParam' }); - eHM.set('one', 1); - expect(eHM.get('one')).toBe(1); - }); - - test('should raw elements toEntry', () => { - const rawCollection = [ - { id: 1, name: 'item 1' }, - { id: 2, name: 'item 2' } - ]; - const hm = new HashMap(rawCollection, { - toEntryFn: rawElement => [rawElement.id, rawElement.name] + const eHM = new ExtendedHashMap([], { someOtherParam: 'someOtherParam' }); + eHM.set('one', 1); + expect(eHM.get('one')).toBe(1); }); - expect(hm.has(1)).toBe(true); - expect(hm.get(2)).toBe('item 2'); - expect(hm.size).toBe(2); - }); + test('should raw elements toEntry', () => { + const rawCollection = [ + { id: 1, name: 'item 1' }, + { id: 2, name: 'item 2' } + ]; + const hm = new HashMap(rawCollection, { + toEntryFn: rawElement => [rawElement.id, rawElement.name] + }); - it('should update the value for an existing key', () => { - hashMap.set('key1', 'value1'); - hashMap.set('key1', 'newValue'); - expect(hashMap.get('key1')).toBe('newValue'); - }); - - it('should return undefined for a non-existent key', () => { - expect(hashMap.get('nonExistentKey')).toBeUndefined(); - }); - - it('should remove a key-value pair', () => { - hashMap.set('key1', 'value1'); - hashMap.delete('key1'); - expect(hashMap.get('key1')).toBeUndefined(); - }); - - it('should clear the map', () => { - hashMap.set('key1', 'value1'); - expect(hashMap.size).toBe(1); - - hashMap.clear(); - expect(hashMap.size).toBe(0); - }); - - it('should iterate over values', () => { - hashMap.set('key1', 'value1'); - hashMap.set('key2', 'value2'); - const values = []; - for (const value of hashMap) { - values.push(value); - } - expect(values).toEqual([ - ['key1', 'value1'], - ['key2', 'value2'] - ]); - }); - - function compareHashMaps(hashMap: HashMap, stdMap: Map) { - expect(hashMap.size).toEqual(stdMap.size); - stdMap.forEach((value, key) => { - expect(hashMap.get(key)).toEqual(value); + expect(hm.has(1)).toBe(true); + expect(hm.get(2)).toBe('item 2'); + expect(hm.size).toBe(2); }); - } - const stdMap: Map = new Map(); - const arr: number[] = getRandomIntArray(1000, 1, 10000); + it('should update the value for an existing key', () => { + hashMap.set('key1', 'value1'); + hashMap.set('key1', 'newValue'); + expect(hashMap.get('key1')).toBe('newValue'); + }); - it('delete test', () => { - for (const item of arr) { - stdMap.set(item, item); - hashMap.set(item, item); - } - for (const item of arr) { - if (Math.random() > 0.6) { - expect(hashMap.delete(item)).toEqual(stdMap.delete(item)); + it('should return undefined for a non-existent key', () => { + expect(hashMap.get('nonExistentKey')).toBeUndefined(); + }); + + it('should remove a key-value pair', () => { + hashMap.set('key1', 'value1'); + hashMap.delete('key1'); + expect(hashMap.get('key1')).toBeUndefined(); + }); + + it('should clear the map', () => { + hashMap.set('key1', 'value1'); + expect(hashMap.size).toBe(1); + + hashMap.clear(); + expect(hashMap.size).toBe(0); + }); + + it('should iterate over values', () => { + hashMap.set('key1', 'value1'); + hashMap.set('key2', 'value2'); + const values = []; + for (const value of hashMap) { + values.push(value); } + expect(values).toEqual([ + ['key1', 'value1'], + ['key2', 'value2'] + ]); + }); + + function compareHashMaps(hashMap: HashMap, stdMap: Map) { + expect(hashMap.size).toEqual(stdMap.size); + stdMap.forEach((value, key) => { + expect(hashMap.get(key)).toEqual(value); + }); } - compareHashMaps(hashMap, stdMap); - for (let i = 0; i < 1000; ++i) { - const random = getRandomInt(0, 100); - expect(hashMap.delete(random)).toEqual(stdMap.delete(random)); - } - compareHashMaps(hashMap, stdMap); - }); -}); + const stdMap: Map = new Map(); + const arr: number[] = getRandomIntArray(1000, 1, 10000); -describe('HashMap for coordinate object keys', () => { - const hashMap: HashMap<[number, number], number> = new HashMap(); - const codObjs: [number, number][] = []; - - test('set elements in hash map', () => { - for (let i = 0; i < 1000; i++) { - const codObj: [number, number] = [getRandomInt(-10000, 10000), i]; - codObjs.push(codObj); - hashMap.set(codObj, i); - } - }); - - test('get elements in hash map', () => { - for (let i = 0; i < 1000; i++) { - const codObj = codObjs[i]; - if (codObj) { - expect(hashMap.get(codObj)).toBe(i); + it('delete test', () => { + for (const item of arr) { + stdMap.set(item, item); + hashMap.set(item, item); } - } + for (const item of arr) { + if (Math.random() > 0.6) { + expect(hashMap.delete(item)).toEqual(stdMap.delete(item)); + } + } + compareHashMaps(hashMap, stdMap); + + for (let i = 0; i < 1000; ++i) { + const random = getRandomInt(0, 100); + expect(hashMap.delete(random)).toEqual(stdMap.delete(random)); + } + compareHashMaps(hashMap, stdMap); + }); }); - test('delete elements in hash map', () => { - for (let i = 0; i < 1000; i++) { - if (i === 500) expect(hashMap.size).toBe(500); - const codObj = codObjs[i]; - if (codObj) hashMap.delete(codObj); - } - expect(hashMap.size).toBe(0); + describe('HashMap for coordinate object keys', () => { + const hashMap: HashMap<[number, number], number> = new HashMap(); + const codObjs: [number, number][] = []; + + test('set elements in hash map', () => { + for (let i = 0; i < 1000; i++) { + const codObj: [number, number] = [getRandomInt(-10000, 10000), i]; + codObjs.push(codObj); + hashMap.set(codObj, i); + } + }); + + test('get elements in hash map', () => { + for (let i = 0; i < 1000; i++) { + const codObj = codObjs[i]; + if (codObj) { + expect(hashMap.get(codObj)).toBe(i); + } + } + }); + + test('delete elements in hash map', () => { + for (let i = 0; i < 1000; i++) { + if (i === 500) expect(hashMap.size).toBe(500); + const codObj = codObjs[i]; + if (codObj) hashMap.delete(codObj); + } + expect(hashMap.size).toBe(0); + }); + }); + + describe('HashMap setMany, keys, values', () => { + const hm: HashMap = new HashMap(); + + beforeEach(() => { + hm.clear(); + hm.setMany([ + [2, 2], + [3, 3], + [4, 4], + [5, 5] + ]); + hm.setMany([ + [2, 2], + [3, 3], + [4, 4], + [6, 6] + ]); + }); + + test('keys', () => { + expect([...hm.keys()]).toEqual([2, 3, 4, 5, 6]); + }); + + test('values', () => { + expect([...hm.values()]).toEqual([2, 3, 4, 5, 6]); + }); + }); + + describe('HashMap HOF', () => { + let hashMap: HashMap; + + beforeEach(() => { + hashMap = new HashMap(); + hashMap.set('key1', 'value1'); + hashMap.set('key2', 'value2'); + hashMap.set('key3', 'value3'); + }); + + test('every() returns true if all elements match the condition', () => { + expect(hashMap.every(value => typeof value === 'string')).toBe(true); + }); + + test('some() returns true if any element matches the condition', () => { + expect(hashMap.some((value, key) => key === 'key1')).toBe(true); + }); + + test('forEach() should execute a function for each element', () => { + const mockCallback = jest.fn(); + hashMap.forEach(mockCallback); + expect(mockCallback.mock.calls.length).toBe(3); + }); + + test('map() should transform each element', () => { + const newHashMap = hashMap.map(value => value.toUpperCase()); + expect(newHashMap.get('key1')).toBe('VALUE1'); + }); + + test('filter() should remove elements that do not match the condition', () => { + const filteredHashMap = hashMap.filter((value, key) => key !== 'key1'); + expect(filteredHashMap.has('key1')).toBe(false); + }); + + test('reduce() should accumulate values', () => { + const result = hashMap.reduce((acc, value) => acc + value, ''); + expect(result).toBe('value1value2value3'); + }); }); }); -describe('HashMap setMany, keys, values', () => { - const hm: HashMap = new HashMap(); - - beforeEach(() => { - hm.clear(); - hm.setMany([ - [2, 2], - [3, 3], - [4, 4], - [5, 5] - ]); - hm.setMany([ - [2, 2], - [3, 3], - [4, 4], - [6, 6] - ]); - }); - - test('keys', () => { - expect([...hm.keys()]).toEqual([2, 3, 4, 5, 6]); - }); - - test('values', () => { - expect([...hm.values()]).toEqual([2, 3, 4, 5, 6]); - }); -}); - -describe('HashMap HOF', () => { - let hashMap: HashMap; - - beforeEach(() => { - hashMap = new HashMap(); - hashMap.set('key1', 'value1'); - hashMap.set('key2', 'value2'); - hashMap.set('key3', 'value3'); - }); - - test('every() returns true if all elements match the condition', () => { - expect(hashMap.every(value => typeof value === 'string')).toBe(true); - }); - - test('some() returns true if any element matches the condition', () => { - expect(hashMap.some((value, key) => key === 'key1')).toBe(true); - }); - - test('forEach() should execute a function for each element', () => { - const mockCallback = jest.fn(); - hashMap.forEach(mockCallback); - expect(mockCallback.mock.calls.length).toBe(3); - }); - - test('map() should transform each element', () => { - const newHashMap = hashMap.map(value => value.toUpperCase()); - expect(newHashMap.get('key1')).toBe('VALUE1'); - }); - - test('filter() should remove elements that do not match the condition', () => { - const filteredHashMap = hashMap.filter((value, key) => key !== 'key1'); - expect(filteredHashMap.has('key1')).toBe(false); - }); - - test('reduce() should accumulate values', () => { - const result = hashMap.reduce((acc, value) => acc + value, ''); - expect(result).toBe('value1value2value3'); - }); -}); - -describe('LinkedHashMap Test1', () => { - let hashMap: LinkedHashMap; - - beforeEach(() => { - hashMap = new LinkedHashMap(); - }); - - it('should initialize correctly', () => { - expect(hashMap.size).toBe(0); - // expect(hashMap.table.length).toBe(16); - // expect(hashMap.loadFactor).toBe(0.75); - // expect(hashMap.capacityMultiplier).toBe(2); - // expect(hashMap.initialCapacity).toBe(16); - expect(hashMap.isEmpty()).toBe(true); - }); - - it('should put and get values', () => { - hashMap.set('one', 1); - hashMap.set('two', 2); - hashMap.set('three', 3); - - expect(hashMap.get('one')).toBe(1); - expect(hashMap.get('two')).toBe(2); - expect(hashMap.get('three')).toBe(3); - }); - - it('should handle key collisions', () => { - // Force a collision by setting two different keys to the same bucket - hashMap.set('key1', 1); - hashMap.set('key2', 2); - - expect(hashMap.get('key1')).toBe(1); - expect(hashMap.get('key2')).toBe(2); - }); - - it('should delete values', () => { - hashMap.set('one', 1); - hashMap.set('two', 2); - - hashMap.delete('one'); - expect(hashMap.get('one')).toBeUndefined(); - expect(hashMap.size).toBe(1); - }); - - it('should clear the LinkedHashMap', () => { - hashMap.set('one', 1); - hashMap.set('two', 2); - - hashMap.clear(); - expect(hashMap.size).toBe(0); - expect(hashMap.isEmpty()).toBe(true); - }); - - it('should iterate over entries', () => { - hashMap.set('one', 1); - hashMap.set('two', 2); - hashMap.set('three', 3); - - // const entries = Array.from(hashMap.entries()); - // expect(entries).toContainEqual(['one', 1]); - // expect(entries).toContainEqual(['two', 2]); - // expect(entries).toContainEqual(['three', 3]); - }); - - it('should resize the table when load factor is exceeded', () => { - // Set a small initial capacity for testing resizing - hashMap = new LinkedHashMap(); - - hashMap.set('one', 1); - hashMap.set('two', 2); - hashMap.set('three', 3); - hashMap.set('four', 4); // This should trigger a resize - - // expect(hashMap.table.length).toBe(8); - expect(hashMap.get('one')).toBe(1); - expect(hashMap.get('two')).toBe(2); - expect(hashMap.get('three')).toBe(3); - expect(hashMap.get('four')).toBe(4); - }); - - it('should allow using a custom hash function', () => { - hashMap = new LinkedHashMap(); - - hashMap.set('one', 1); - hashMap.set('two', 2); - - expect(hashMap.get('one')).toBe(1); - expect(hashMap.get('two')).toBe(2); - // Since the custom hash function always returns 0, these keys will collide. - // Make sure they are stored separately. - // expect(hashMap.table[0].length).toBe(2); - }); - - // it('should handle number keys correctly', () => { - // const hm = new LinkedHashMap(); - // hm.set(999, { a: '999Value' }); - // hm.set('999', {a: '999StrValue'}) - // expect(hm.get(999)).toEqual({ a: '999Value' }); - // expect(hm.get('999')).toEqual({ a: '999StrValue1' }); - // }); -}); - -describe('LinkedHashMap Test2', () => { +describe('LinkedHashMap', () => { let hashMap: LinkedHashMap; beforeEach(() => { @@ -538,90 +436,192 @@ describe('LinkedHashMap Test2', () => { hashMap.set('key2', 'value2'); expect(hashMap.getAt(1)).toBe('value2'); }); -}); -describe('LinkedHashMap for coordinate object keys', () => { - const hashMap: LinkedHashMap<[number, number], number> = new LinkedHashMap(); - const codObjs: [number, number][] = []; + describe('LinkedHashMap basic', () => { + let hashMap: LinkedHashMap; - test('set elements in hash map', () => { - for (let i = 0; i < 1000; i++) { - const codObj: [number, number] = [getRandomInt(-10000, 10000), i]; - codObjs.push(codObj); - hashMap.set(codObj, i); - } + beforeEach(() => { + hashMap = new LinkedHashMap(); + }); + + it('should initialize correctly', () => { + expect(hashMap.size).toBe(0); + // expect(hashMap.table.length).toBe(16); + // expect(hashMap.loadFactor).toBe(0.75); + // expect(hashMap.capacityMultiplier).toBe(2); + // expect(hashMap.initialCapacity).toBe(16); + expect(hashMap.isEmpty()).toBe(true); + }); + + it('should put and get values', () => { + hashMap.set('one', 1); + hashMap.set('two', 2); + hashMap.set('three', 3); + + expect(hashMap.get('one')).toBe(1); + expect(hashMap.get('two')).toBe(2); + expect(hashMap.get('three')).toBe(3); + }); + + it('should handle key collisions', () => { + // Force a collision by setting two different keys to the same bucket + hashMap.set('key1', 1); + hashMap.set('key2', 2); + + expect(hashMap.get('key1')).toBe(1); + expect(hashMap.get('key2')).toBe(2); + }); + + it('should delete values', () => { + hashMap.set('one', 1); + hashMap.set('two', 2); + + hashMap.delete('one'); + expect(hashMap.get('one')).toBeUndefined(); + expect(hashMap.size).toBe(1); + }); + + it('should clear the LinkedHashMap', () => { + hashMap.set('one', 1); + hashMap.set('two', 2); + + hashMap.clear(); + expect(hashMap.size).toBe(0); + expect(hashMap.isEmpty()).toBe(true); + }); + + it('should iterate over entries', () => { + hashMap.set('one', 1); + hashMap.set('two', 2); + hashMap.set('three', 3); + + // const entries = Array.from(hashMap.entries()); + // expect(entries).toContainEqual(['one', 1]); + // expect(entries).toContainEqual(['two', 2]); + // expect(entries).toContainEqual(['three', 3]); + }); + + it('should resize the table when load factor is exceeded', () => { + // Set a small initial capacity for testing resizing + hashMap = new LinkedHashMap(); + + hashMap.set('one', 1); + hashMap.set('two', 2); + hashMap.set('three', 3); + hashMap.set('four', 4); // This should trigger a resize + + // expect(hashMap.table.length).toBe(8); + expect(hashMap.get('one')).toBe(1); + expect(hashMap.get('two')).toBe(2); + expect(hashMap.get('three')).toBe(3); + expect(hashMap.get('four')).toBe(4); + }); + + it('should allow using a custom hash function', () => { + hashMap = new LinkedHashMap(); + + hashMap.set('one', 1); + hashMap.set('two', 2); + + expect(hashMap.get('one')).toBe(1); + expect(hashMap.get('two')).toBe(2); + // Since the custom hash function always returns 0, these keys will collide. + // Make sure they are stored separately. + // expect(hashMap.table[0].length).toBe(2); + }); + + // it('should handle number keys correctly', () => { + // const hm = new LinkedHashMap(); + // hm.set(999, { a: '999Value' }); + // hm.set('999', {a: '999StrValue'}) + // expect(hm.get(999)).toEqual({ a: '999Value' }); + // expect(hm.get('999')).toEqual({ a: '999StrValue1' }); + // }); }); - test('get elements in hash map', () => { - for (let i = 0; i < 1000; i++) { - const codObj = codObjs[i]; - if (codObj) { - expect(hashMap.get(codObj)).toBe(i); + describe('coordinate object keys', () => { + const hashMap: LinkedHashMap<[number, number], number> = new LinkedHashMap(); + const codObjs: [number, number][] = []; + + test('set elements in hash map', () => { + for (let i = 0; i < 1000; i++) { + const codObj: [number, number] = [getRandomInt(-10000, 10000), i]; + codObjs.push(codObj); + hashMap.set(codObj, i); } - } + }); + + test('get elements in hash map', () => { + for (let i = 0; i < 1000; i++) { + const codObj = codObjs[i]; + if (codObj) { + expect(hashMap.get(codObj)).toBe(i); + } + } + }); + + test('delete elements in hash map', () => { + for (let i = 0; i < 1000; i++) { + if (i === 500) expect(hashMap.size).toBe(500); + const codObj = codObjs[i]; + if (codObj) hashMap.delete(codObj); + } + expect(hashMap.size).toBe(0); + }); }); - test('delete elements in hash map', () => { - for (let i = 0; i < 1000; i++) { - if (i === 500) expect(hashMap.size).toBe(500); - const codObj = codObjs[i]; - if (codObj) hashMap.delete(codObj); - } - expect(hashMap.size).toBe(0); - }); -}); - -describe('LinkedHashMap setMany, keys, values', () => { - const hm: LinkedHashMap = new LinkedHashMap(); - - beforeEach(() => { - hm.clear(); - hm.setMany([ - [2, 2], - [3, 3], - [4, 4], - [5, 5] - ]); - hm.setMany([ - [2, 2], - [3, 3], - [4, 4], - [6, 6] - ]); - }); - - test('keys', () => { - expect([...hm.keys()]).toEqual([2, 3, 4, 5, 6]); - }); - - test('values', () => { - expect([...hm.values()]).toEqual([2, 3, 4, 5, 6]); - }); - - test('entries', () => { - expect([...hm.entries()]).toEqual([ - [2, 2], - [3, 3], - [4, 4], - [5, 5], - [6, 6] - ]); - }); - - test('every', () => { - expect(hm.every(value => value > 4)).toBe(false); - }); - - test('some', () => { - expect(hm.some(value => value > 6)).toBe(false); - }); - - test('hasValue', () => { - expect(hm.hasValue(3)).toBe(true); - expect(hm.hasValue(7)).toBe(false); - }); - - test('print', () => { - // hm.print(); + describe('setMany, keys, values', () => { + const hm: LinkedHashMap = new LinkedHashMap(); + + beforeEach(() => { + hm.clear(); + hm.setMany([ + [2, 2], + [3, 3], + [4, 4], + [5, 5] + ]); + hm.setMany([ + [2, 2], + [3, 3], + [4, 4], + [6, 6] + ]); + }); + + test('keys', () => { + expect([...hm.keys()]).toEqual([2, 3, 4, 5, 6]); + }); + + test('values', () => { + expect([...hm.values()]).toEqual([2, 3, 4, 5, 6]); + }); + + test('entries', () => { + expect([...hm.entries()]).toEqual([ + [2, 2], + [3, 3], + [4, 4], + [5, 5], + [6, 6] + ]); + }); + + test('every', () => { + expect(hm.every(value => value > 4)).toBe(false); + }); + + test('some', () => { + expect(hm.some(value => value > 6)).toBe(false); + }); + + test('hasValue', () => { + expect(hm.hasValue(3)).toBe(true); + expect(hm.hasValue(7)).toBe(false); + }); + + test('print', () => { + // hm.print(); + }); }); });