Files
gridpilot.gg/core/shared/domain/Option.test.ts
Marc Mintel 093eece3d7
Some checks failed
Contract Testing / contract-tests (pull_request) Failing after 5m47s
Contract Testing / contract-snapshot (pull_request) Has been skipped
core tests
2026-01-22 18:20:33 +01:00

121 lines
4.2 KiB
TypeScript

import { describe, it, expect } from 'vitest';
import { coalesce, present } from './Option';
describe('Option', () => {
describe('coalesce()', () => {
it('should return the value when it is defined', () => {
expect(coalesce('defined', 'fallback')).toBe('defined');
expect(coalesce(42, 0)).toBe(42);
expect(coalesce(true, false)).toBe(true);
});
it('should return the fallback when value is undefined', () => {
expect(coalesce(undefined, 'fallback')).toBe('fallback');
expect(coalesce(undefined, 42)).toBe(42);
expect(coalesce(undefined, true)).toBe(true);
});
it('should return the fallback when value is null', () => {
expect(coalesce(null, 'fallback')).toBe('fallback');
expect(coalesce(null, 42)).toBe(42);
expect(coalesce(null, true)).toBe(true);
});
it('should handle complex fallback values', () => {
const fallback = { id: 0, name: 'default' };
expect(coalesce(undefined, fallback)).toEqual(fallback);
expect(coalesce(null, fallback)).toEqual(fallback);
expect(coalesce({ id: 1, name: 'actual' }, fallback)).toEqual({ id: 1, name: 'actual' });
});
it('should handle array values', () => {
const fallback = [1, 2, 3];
expect(coalesce(undefined, fallback)).toEqual([1, 2, 3]);
expect(coalesce([4, 5], fallback)).toEqual([4, 5]);
});
it('should handle zero and empty string as valid values', () => {
expect(coalesce(0, 999)).toBe(0);
expect(coalesce('', 'fallback')).toBe('');
expect(coalesce(false, true)).toBe(false);
});
});
describe('present()', () => {
it('should return the value when it is defined and not null', () => {
expect(present('value')).toBe('value');
expect(present(42)).toBe(42);
expect(present(true)).toBe(true);
expect(present({})).toEqual({});
expect(present([])).toEqual([]);
});
it('should return undefined when value is undefined', () => {
expect(present(undefined)).toBe(undefined);
});
it('should return undefined when value is null', () => {
expect(present(null)).toBe(undefined);
});
it('should handle zero and empty string as valid values', () => {
expect(present(0)).toBe(0);
expect(present('')).toBe('');
expect(present(false)).toBe(false);
});
it('should handle complex objects', () => {
const obj = { id: 1, name: 'test', nested: { value: 'data' } };
expect(present(obj)).toEqual(obj);
});
it('should handle arrays', () => {
const arr = [1, 2, 3, 'test'];
expect(present(arr)).toEqual(arr);
});
});
describe('Option behavior', () => {
it('should work together for optional value handling', () => {
// Example: providing a default when value might be missing
const maybeValue: string | undefined = undefined;
const result = coalesce(maybeValue, 'default');
expect(result).toBe('default');
// Example: filtering out null/undefined
const values: (string | null | undefined)[] = ['a', null, 'b', undefined, 'c'];
const filtered = values.map(present).filter((v): v is string => v !== undefined);
expect(filtered).toEqual(['a', 'b', 'c']);
});
it('should support conditional value assignment', () => {
const config: { timeout?: number } = {};
const timeout = coalesce(config.timeout, 5000);
expect(timeout).toBe(5000);
config.timeout = 3000;
const timeout2 = coalesce(config.timeout, 5000);
expect(timeout2).toBe(3000);
});
it('should handle nested optional properties', () => {
interface User {
profile?: {
name?: string;
email?: string;
};
}
const user1: User = {};
const user2: User = { profile: {} };
const user3: User = { profile: { name: 'John' } };
const user4: User = { profile: { name: 'John', email: 'john@example.com' } };
expect(coalesce(user1.profile?.name, 'Anonymous')).toBe('Anonymous');
expect(coalesce(user2.profile?.name, 'Anonymous')).toBe('Anonymous');
expect(coalesce(user3.profile?.name, 'Anonymous')).toBe('John');
expect(coalesce(user4.profile?.name, 'Anonymous')).toBe('John');
});
});
});