import { describe, it, expect } from 'vitest'; import * as ArrayUtils from '../src/ox/core/Array.js'; import * as StringUtils from '../src/ox/core/String.js'; import * as MathUtils from '../src/ox/core/Math.js'; import * as ObjectUtils from '../src/ox/core/Object.js'; import * as FunctionUtils from '../src/ox/core/Function.js'; describe('Module Tests', () => { describe('Array utilities', () => { it('should compact arrays', () => { expect(ArrayUtils.compact([1, null, 2, undefined, 3, 0])).toEqual([1, 2, 3, 0]); }); it('should find unique values', () => { expect(ArrayUtils.unique([1, 2, 2, 3, 3, 3])).toEqual([1, 2, 3]); }); it('should zip arrays', () => { expect(ArrayUtils.zip([1, 2], ['a', 'b'])).toEqual([[1, 'a'], [2, 'b']]); }); }); describe('String utilities', () => { it('should capitalize strings', () => { expect(StringUtils.capitalize('hello')).toBe('Hello'); }); it('should check startsWith', () => { expect(StringUtils.startsWith('hello', 'he')).toBe(true); expect(StringUtils.startsWith('hello', 'hi')).toBe(false); }); it('should repeat strings', () => { expect(StringUtils.repeat('x', 3)).toBe('xxx'); }); it('should convert to camelCase', () => { expect(StringUtils.toCamelCase('foo-bar-baz')).toBe('fooBarBaz'); }); it('should clean whitespace', () => { expect(StringUtils.clean(' hello world ')).toBe('hello world'); }); }); describe('Math utilities', () => { it('should convert degrees to radians', () => { expect(MathUtils.rad(180)).toBeCloseTo(Math.PI); }); it('should convert radians to degrees', () => { expect(MathUtils.deg(Math.PI)).toBeCloseTo(180); }); it('should limit values', () => { expect(MathUtils.limit(5, 0, 10)).toBe(5); expect(MathUtils.limit(-5, 0, 10)).toBe(0); expect(MathUtils.limit(15, 0, 10)).toBe(10); }); it('should calculate modulo correctly', () => { expect(MathUtils.mod(5, 3)).toBe(2); expect(MathUtils.mod(-1, 3)).toBe(2); // Positive result }); it('should calculate sum', () => { expect(MathUtils.sum([1, 2, 3, 4])).toBe(10); }); }); describe('Object utilities', () => { it('should clone objects', () => { const obj = { a: 1, b: { c: 2 } }; const clone = ObjectUtils.clone(obj); expect(clone).toEqual(obj); expect(clone).not.toBe(obj); expect(clone.b).not.toBe(obj.b); }); it('should get object keys', () => { expect(ObjectUtils.keys({ a: 1, b: 2 })).toEqual(['a', 'b']); }); it('should get object values', () => { expect(ObjectUtils.values({ a: 1, b: 2 })).toEqual([1, 2]); }); it('should serialize objects', () => { expect(ObjectUtils.serialize({ foo: 'bar', baz: 123 })).toBe('foo=bar&baz=123'); }); it('should unserialize query strings', () => { expect(ObjectUtils.unserialize('foo=bar&baz=123')).toEqual({ foo: 'bar', baz: '123' }); }); }); describe('Function utilities', () => { it('should create identity function', () => { expect(FunctionUtils.identity(5)).toBe(5); expect(FunctionUtils.identity('test')).toBe('test'); }); it('should create constant function', () => { const fn = FunctionUtils.constant(42); expect(fn()).toBe(42); expect(fn('ignored')).toBe(42); }); it('should call function once', () => { let count = 0; const fn = FunctionUtils.once(() => ++count); expect(fn()).toBe(1); expect(fn()).toBe(1); // Still 1 expect(count).toBe(1); }); it('should memoize functions', () => { let calls = 0; const fn = FunctionUtils.memoize((x) => { calls++; return x * 2; }); expect(fn(5)).toBe(10); expect(fn(5)).toBe(10); // Cached expect(calls).toBe(1); expect(fn(6)).toBe(12); expect(calls).toBe(2); }); }); });