You've already forked Nitro_Render_V3
mirror of
https://github.com/duckietm/Nitro_Render_V3.git
synced 2026-06-19 23:16:20 +00:00
eb4fe80612
- Added Test Coverage - Fix Potential Memory Leaks
284 lines
7.1 KiB
TypeScript
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);
|
|
});
|
|
});
|
|
});
|