Files
Nitro_Render_V3/packages/utils/src/__tests__/AdvancedMap.test.ts
T
DuckieTM eb4fe80612 🆙 Updates
- Added Test Coverage
- Fix Potential Memory Leaks
2026-01-31 13:21:59 +01:00

284 lines
7.1 KiB
TypeScript

import { describe, it, expect, beforeEach } from 'vitest';
import { AdvancedMap } from '../AdvancedMap';
describe('AdvancedMap', () =>
{
let map: AdvancedMap<string, number>;
beforeEach(() =>
{
map = new AdvancedMap<string, number>();
});
describe('constructor', () =>
{
it('should create an empty map', () =>
{
expect(map.length).toBe(0);
});
it('should initialize from existing Map', () =>
{
const source = new Map<string, number>([
['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<string, number>;
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<string, number>();
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);
});
});
});