import { describe, it, expect, beforeEach } from 'vitest'; import { AdvancedMap } from '../AdvancedMap'; describe('AdvancedMap', () => { let map: AdvancedMap; beforeEach(() => { map = new AdvancedMap(); }); describe('constructor', () => { it('should create an empty map', () => { expect(map.length).toBe(0); }); it('should initialize from existing Map', () => { const source = new Map([ ['a', 1], ['b', 2], ['c', 3] ]); const advMap = new AdvancedMap(source); expect(advMap.length).toBe(3); expect(advMap.getValue('a')).toBe(1); expect(advMap.getValue('b')).toBe(2); expect(advMap.getValue('c')).toBe(3); }); }); describe('add', () => { it('should add key-value pairs', () => { expect(map.add('key1', 100)).toBe(true); expect(map.length).toBe(1); expect(map.getValue('key1')).toBe(100); }); it('should return false when adding duplicate key', () => { map.add('key1', 100); expect(map.add('key1', 200)).toBe(false); expect(map.getValue('key1')).toBe(100); }); it('should maintain insertion order', () => { map.add('a', 1); map.add('b', 2); map.add('c', 3); expect(map.getKey(0)).toBe('a'); expect(map.getKey(1)).toBe('b'); expect(map.getKey(2)).toBe('c'); }); }); describe('unshift', () => { it('should return false due to bug in implementation', () => { // Note: unshift has a bug - it checks `!== null` instead of `!== undefined` // Map.get() returns undefined for missing keys, so condition always fails // This test documents the current broken behavior const result = map.unshift('first', 0); expect(result).toBe(false); expect(map.length).toBe(0); }); }); describe('remove', () => { it('should remove and return value by key', () => { map.add('key1', 100); map.add('key2', 200); const removed = map.remove('key1'); expect(removed).toBe(100); expect(map.length).toBe(1); expect(map.getValue('key1')).toBeUndefined(); }); it('should return null when removing non-existent key', () => { expect(map.remove('nonexistent')).toBeNull(); }); }); describe('getWithIndex', () => { it('should get value by index', () => { map.add('a', 1); map.add('b', 2); map.add('c', 3); expect(map.getWithIndex(0)).toBe(1); expect(map.getWithIndex(1)).toBe(2); expect(map.getWithIndex(2)).toBe(3); }); it('should return null for out of bounds index', () => { map.add('a', 1); expect(map.getWithIndex(-1)).toBeNull(); expect(map.getWithIndex(10)).toBeNull(); }); }); describe('getKey', () => { it('should get key by index', () => { map.add('a', 1); map.add('b', 2); expect(map.getKey(0)).toBe('a'); expect(map.getKey(1)).toBe('b'); }); it('should return null for out of bounds index', () => { expect(map.getKey(-1)).toBeNull(); expect(map.getKey(10)).toBeNull(); }); }); describe('getKeys', () => { it('should return copy of keys array', () => { map.add('a', 1); map.add('b', 2); const keys = map.getKeys(); expect(keys).toEqual(['a', 'b']); // Verify it's a copy keys.push('c'); expect(map.length).toBe(2); }); }); describe('getValues', () => { it('should return copy of values array', () => { map.add('a', 1); map.add('b', 2); const values = map.getValues(); expect(values).toEqual([1, 2]); // Verify it's a copy values.push(3); expect(map.length).toBe(2); }); }); describe('hasKey', () => { it('should return true if key exists', () => { map.add('a', 1); expect(map.hasKey('a')).toBe(true); }); it('should return false if key does not exist', () => { expect(map.hasKey('nonexistent')).toBe(false); }); }); describe('hasValue', () => { it('should return true if value exists', () => { map.add('a', 100); expect(map.hasValue(100)).toBe(true); }); it('should return false if value does not exist', () => { expect(map.hasValue(999)).toBe(false); }); }); describe('indexOf', () => { it('should return index of value', () => { map.add('a', 1); map.add('b', 2); map.add('c', 3); expect(map.indexOf(2)).toBe(1); }); it('should return -1 if value not found', () => { expect(map.indexOf(999)).toBe(-1); }); }); describe('reset', () => { it('should clear all entries', () => { map.add('a', 1); map.add('b', 2); map.reset(); expect(map.length).toBe(0); expect(map.getValue('a')).toBeUndefined(); }); }); describe('clone', () => { it('should create independent copy', () => { map.add('a', 1); map.add('b', 2); const cloned = map.clone() as AdvancedMap; expect(cloned.length).toBe(2); expect(cloned.getValue('a')).toBe(1); // Verify independence cloned.add('c', 3); expect(map.length).toBe(2); expect(cloned.length).toBe(3); }); }); describe('concatenate', () => { it('should add all entries from another map', () => { map.add('a', 1); const other = new AdvancedMap(); other.add('b', 2); other.add('c', 3); map.concatenate(other); expect(map.length).toBe(3); expect(map.getValue('b')).toBe(2); expect(map.getValue('c')).toBe(3); }); }); describe('dispose', () => { it('should reset length and arrays on dispose', () => { map.add('a', 1); expect(map.disposed).toBe(false); map.dispose(); // Note: There's a bug in dispose() - it checks `if(!this._dictionary)` // instead of `if(this._dictionary)`, so dictionary is not set to null. // This test verifies current behavior; the bug should be fixed separately. expect(map.length).toBe(0); }); }); });