Skip to content

Commit 717846f

Browse files
committed
feat(workflows): generate short machine-nature names
1 parent a27f376 commit 717846f

2 files changed

Lines changed: 294 additions & 412 deletions

File tree

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/**
2+
* @vitest-environment node
3+
*/
4+
import { beforeEach, describe, expect, it, vi } from 'vitest'
5+
6+
const { mockRandomItem } = vi.hoisted(() => ({
7+
mockRandomItem: vi.fn(),
8+
}))
9+
10+
vi.mock('@sim/utils/random', () => ({
11+
randomItem: mockRandomItem,
12+
}))
13+
14+
import { generateCreativeWorkflowName } from '@/stores/workflows/registry/utils'
15+
16+
function captureNamesForLength(targetLength: number): readonly string[] {
17+
let names: readonly string[] = []
18+
19+
mockRandomItem.mockImplementation((items: readonly unknown[]) => {
20+
if (typeof items[0] === 'number') return targetLength
21+
22+
names = items as readonly string[]
23+
return names[0]
24+
})
25+
26+
generateCreativeWorkflowName()
27+
return names
28+
}
29+
30+
describe('generateCreativeWorkflowName', () => {
31+
beforeEach(() => {
32+
vi.clearAllMocks()
33+
})
34+
35+
it('prefers seven-letter names and progressively disfavors longer totals', () => {
36+
let lengthChoices: readonly number[] = []
37+
38+
mockRandomItem.mockImplementation((items: readonly unknown[]) => {
39+
if (typeof items[0] === 'number') {
40+
lengthChoices = items as readonly number[]
41+
return 7
42+
}
43+
44+
return items[0]
45+
})
46+
47+
generateCreativeWorkflowName()
48+
49+
const weightFor = (length: number) => lengthChoices.filter((choice) => choice === length).length
50+
51+
expect(new Set(lengthChoices)).toEqual(new Set([6, 7, 8, 9, 10]))
52+
expect(weightFor(7)).toBeGreaterThan(weightFor(8))
53+
expect(weightFor(8)).toBeGreaterThan(weightFor(9))
54+
expect(weightFor(9)).toBeGreaterThan(weightFor(10))
55+
expect(weightFor(7)).toBeGreaterThan(weightFor(6))
56+
})
57+
58+
it('only offers short machine-nature pairs within the selected total length', () => {
59+
const names = [6, 7, 8, 9, 10].flatMap((targetLength) => {
60+
const candidates = captureNamesForLength(targetLength)
61+
62+
expect(candidates.length).toBeGreaterThan(0)
63+
for (const candidate of candidates) {
64+
const [machine, nature, extra] = candidate.split('-')
65+
expect(extra).toBeUndefined()
66+
expect(machine).toMatch(/^[a-z]+$/)
67+
expect(nature).toMatch(/^[a-z]+$/)
68+
expect(machine.length).toBeLessThanOrEqual(5)
69+
expect(nature.length).toBeLessThanOrEqual(5)
70+
expect(machine.length + nature.length).toBe(targetLength)
71+
}
72+
73+
return candidates
74+
})
75+
76+
expect(names).toEqual(
77+
expect.arrayContaining(['city-grove', 'bolt-ivy', 'nut-tree', 'gpu-moss'])
78+
)
79+
expect(names).toHaveLength(7050)
80+
})
81+
})

0 commit comments

Comments
 (0)