Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { describe, expect, it } from 'vitest';

import {
AGENT_RADIUS,
ART_H,
ART_W,
CANVAS_H,
CANVAS_W,
CATWALK_Y,
CHUTE_BOT,
CHUTE_TOP,
GATE_W,
GROUND_Y,
LAYOUT_MARGIN,
ORCH_RADIUS,
STATION_GAP,
} from '../dimensions.js';

describe('canvas dimensions', () => {
it('has CANVAS_W equal to 1400', () => {
expect(CANVAS_W).toBe(1400);
});

it('has CANVAS_H equal to 540', () => {
expect(CANVAS_H).toBe(540);
});
});

describe('derived vertical positions', () => {
it('derives CHUTE_TOP as CATWALK_Y + 48', () => {
expect(CHUTE_TOP).toBe(CATWALK_Y + 48);
});

it('derives CHUTE_BOT as GROUND_Y - 20', () => {
expect(CHUTE_BOT).toBe(GROUND_Y - 20);
});
});

describe('anchor values', () => {
it('has CATWALK_Y equal to 100', () => {
expect(CATWALK_Y).toBe(100);
});

it('has GROUND_Y equal to 340', () => {
expect(GROUND_Y).toBe(340);
});
});

describe('entity sizing', () => {
it('has positive AGENT_RADIUS', () => {
expect(AGENT_RADIUS).toBeGreaterThan(0);
});

it('has ORCH_RADIUS greater than AGENT_RADIUS', () => {
expect(ORCH_RADIUS).toBeGreaterThan(AGENT_RADIUS);
});

it('has positive artifact dimensions', () => {
expect(ART_W).toBeGreaterThan(0);
expect(ART_H).toBeGreaterThan(0);
});

it('has positive GATE_W', () => {
expect(GATE_W).toBeGreaterThan(0);
});
});

describe('layout margins', () => {
it('has positive LAYOUT_MARGIN', () => {
expect(LAYOUT_MARGIN).toBeGreaterThan(0);
});

it('has positive STATION_GAP', () => {
expect(STATION_GAP).toBeGreaterThan(0);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { describe, expect, it } from 'vitest';

import { CHUTE_DURATION, PAUSE_DURATION, WALK_SPEED, WORK_DURATION } from '../timing.js';

describe('timing constants', () => {
it('has WALK_SPEED equal to 400 pixels per second', () => {
expect(WALK_SPEED).toBe(400);
});

it('has CHUTE_DURATION equal to 600 milliseconds', () => {
expect(CHUTE_DURATION).toBe(600);
});

it('has WORK_DURATION equal to 1200 milliseconds', () => {
expect(WORK_DURATION).toBe(1200);
});

it('has PAUSE_DURATION equal to 300 milliseconds', () => {
expect(PAUSE_DURATION).toBe(300);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Canvas dimensions
export const CANVAS_W = 1400;
export const CANVAS_H = 540;

// Vertical positions
export const CATWALK_Y = 100;
export const GROUND_Y = 340;
export const CHUTE_TOP = CATWALK_Y + 48;
export const CHUTE_BOT = GROUND_Y - 20;

// Entity sizing
export const AGENT_RADIUS = 14;
export const ORCH_RADIUS = 16;
export const ART_W = 40;
export const ART_H = 16;
export const GATE_W = 6;

// Layout margins
export const LAYOUT_MARGIN = 100;
export const STATION_GAP = 30;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/** Walk speed in pixels per second. */
export const WALK_SPEED = 400;

/** Duration of a chute animation in milliseconds. */
export const CHUTE_DURATION = 600;

/** Duration of a work animation in milliseconds. */
export const WORK_DURATION = 1200;

/** Duration of a pause between actions in milliseconds. */
export const PAUSE_DURATION = 300;
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { describe, expect, it } from 'vitest';

import { ARTIFACT_COLORS, type ArtifactColorKey } from '../artifact-colors.js';

const EXPECTED_KEYS: readonly ArtifactColorKey[] = [
'reqs',
'xplan',
'arch',
'plan',
'code',
'review',
'fixes',
'clean',
'holi',
'summary',
];

describe('ARTIFACT_COLORS', () => {
it('contains exactly the expected set of keys', () => {
// eslint-disable-next-line unicorn/no-array-sort -- toSorted() unavailable in configured Node range
expect(Object.keys(ARTIFACT_COLORS).sort()).toEqual([...EXPECTED_KEYS].sort());
});

it('maps every key to a valid 6-digit hex color', () => {
for (const value of Object.values(ARTIFACT_COLORS)) {
expect(value).toMatch(/^#[0-9a-f]{6}$/i);
}
});

it('maps each key to a distinct color', () => {
const values = Object.values(ARTIFACT_COLORS);
expect(new Set(values).size).toBe(values.length);
});
});
15 changes: 15 additions & 0 deletions packages/factory/src/shared/constants/artifact-colors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/** Mapping from artifact type to pastel display color. */
export const ARTIFACT_COLORS = {
reqs: '#dee2e6',
xplan: '#d0ebff',
arch: '#a5d8ff',
plan: '#b2f2bb',
code: '#fff3bf',
review: '#ffc9c9',
fixes: '#ffe8cc',
clean: '#f3d9fa',
holi: '#c3fae8',
summary: '#f8f9fa',
} as const;

export type ArtifactColorKey = keyof typeof ARTIFACT_COLORS;