Files
gridpilot.gg/core/shared/domain/Entity.test.ts
2026-01-22 18:05:30 +01:00

175 lines
5.5 KiB
TypeScript

import { describe, it, expect } from 'vitest';
import { Entity, EntityProps, EntityAlias } from './Entity';
// Concrete implementation for testing
class TestEntity extends Entity<string> {
constructor(id: string) {
super(id);
}
}
describe('Entity', () => {
describe('EntityProps interface', () => {
it('should have readonly id property', () => {
const props: EntityProps<string> = { id: 'test-id' };
expect(props.id).toBe('test-id');
});
it('should support different id types', () => {
const stringProps: EntityProps<string> = { id: 'test-id' };
const numberProps: EntityProps<number> = { id: 123 };
const uuidProps: EntityProps<string> = { id: '550e8400-e29b-41d4-a716-446655440000' };
expect(stringProps.id).toBe('test-id');
expect(numberProps.id).toBe(123);
expect(uuidProps.id).toBe('550e8400-e29b-41d4-a716-446655440000');
});
});
describe('Entity class', () => {
it('should have id property', () => {
const entity = new TestEntity('entity-123');
expect(entity.id).toBe('entity-123');
});
it('should have equals method', () => {
const entity1 = new TestEntity('entity-123');
const entity2 = new TestEntity('entity-123');
const entity3 = new TestEntity('entity-456');
expect(entity1.equals(entity2)).toBe(true);
expect(entity1.equals(entity3)).toBe(false);
});
it('should return false when comparing with undefined', () => {
const entity = new TestEntity('entity-123');
expect(entity.equals(undefined)).toBe(false);
});
it('should return false when comparing with null', () => {
const entity = new TestEntity('entity-123');
expect(entity.equals(null)).toBe(false);
});
it('should return false when comparing with entity of different type', () => {
const entity1 = new TestEntity('entity-123');
const entity2 = new TestEntity('entity-123');
// Even with same ID, if they're different entity types, equals should work
// since it only compares IDs
expect(entity1.equals(entity2)).toBe(true);
});
it('should support numeric IDs', () => {
class NumericEntity extends Entity<number> {
constructor(id: number) {
super(id);
}
}
const entity1 = new NumericEntity(123);
const entity2 = new NumericEntity(123);
const entity3 = new NumericEntity(456);
expect(entity1.id).toBe(123);
expect(entity1.equals(entity2)).toBe(true);
expect(entity1.equals(entity3)).toBe(false);
});
it('should support UUID IDs', () => {
const uuid1 = '550e8400-e29b-41d4-a716-446655440000';
const uuid2 = '550e8400-e29b-41d4-a716-446655440000';
const uuid3 = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';
const entity1 = new TestEntity(uuid1);
const entity2 = new TestEntity(uuid2);
const entity3 = new TestEntity(uuid3);
expect(entity1.equals(entity2)).toBe(true);
expect(entity1.equals(entity3)).toBe(false);
});
it('should be immutable - id cannot be changed', () => {
const entity = new TestEntity('entity-123');
// Try to change id (should not work in TypeScript, but testing runtime)
// @ts-expect-error - Testing immutability
entity.id = 'new-id';
// ID should remain unchanged
expect(entity.id).toBe('entity-123');
});
});
describe('EntityAlias type', () => {
it('should be assignable to EntityProps', () => {
const alias: EntityAlias<string> = { id: 'test-id' };
expect(alias.id).toBe('test-id');
});
it('should work with different ID types', () => {
const stringAlias: EntityAlias<string> = { id: 'test' };
const numberAlias: EntityAlias<number> = { id: 42 };
const uuidAlias: EntityAlias<string> = { id: '550e8400-e29b-41d4-a716-446655440000' };
expect(stringAlias.id).toBe('test');
expect(numberAlias.id).toBe(42);
expect(uuidAlias.id).toBe('550e8400-e29b-41d4-a716-446655440000');
});
});
});
describe('Entity behavior', () => {
it('should support entity identity', () => {
// Entities are identified by their ID
const entity1 = new TestEntity('same-id');
const entity2 = new TestEntity('same-id');
const entity3 = new TestEntity('different-id');
// Same ID = same identity
expect(entity1.equals(entity2)).toBe(true);
// Different ID = different identity
expect(entity1.equals(entity3)).toBe(false);
});
it('should support entity reference equality', () => {
const entity = new TestEntity('entity-123');
// Same instance should equal itself
expect(entity.equals(entity)).toBe(true);
});
it('should work with complex ID types', () => {
interface ComplexId {
tenant: string;
sequence: number;
}
class ComplexEntity extends Entity<ComplexId> {
constructor(id: ComplexId) {
super(id);
}
equals(other?: Entity<ComplexId>): boolean {
if (!other) return false;
return (
this.id.tenant === other.id.tenant &&
this.id.sequence === other.id.sequence
);
}
}
const id1: ComplexId = { tenant: 'org-a', sequence: 1 };
const id2: ComplexId = { tenant: 'org-a', sequence: 1 };
const id3: ComplexId = { tenant: 'org-b', sequence: 1 };
const entity1 = new ComplexEntity(id1);
const entity2 = new ComplexEntity(id2);
const entity3 = new ComplexEntity(id3);
expect(entity1.equals(entity2)).toBe(true);
expect(entity1.equals(entity3)).toBe(false);
});
});