feat(m1): PR3.1 automation unlock and recipes #19
@@ -2,6 +2,7 @@ import { describe, expect, it } from 'vitest';
|
||||
import { buildContent } from '../../content/schema';
|
||||
import {
|
||||
addToAutomationQueue,
|
||||
automationUnlockThreshold,
|
||||
clearAutomationQueue,
|
||||
isAutomationUnlocked,
|
||||
removeFromAutomationQueue,
|
||||
@@ -32,10 +33,32 @@ function automationContent() {
|
||||
durationMs: 100,
|
||||
yields: [{ resourceId: 'renown', amount: 1 }],
|
||||
},
|
||||
{
|
||||
id: 'train',
|
||||
name: 'Train',
|
||||
group: DEFAULT_GROUP,
|
||||
durationMs: 100,
|
||||
yields: [{ resourceId: 'renown', amount: 1 }],
|
||||
automation: { unlockAfterManualCompletions: 2 },
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
describe('automationUnlockThreshold()', () => {
|
||||
it('returns the action-specific automation threshold when configured', () => {
|
||||
const content = automationContent();
|
||||
|
||||
expect(automationUnlockThreshold(content, 'train')).toBe(2);
|
||||
});
|
||||
|
||||
it('defaults to one manual completion when automation config is absent', () => {
|
||||
const content = automationContent();
|
||||
|
||||
expect(automationUnlockThreshold(content, 'survey')).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isAutomationUnlocked()', () => {
|
||||
it('returns false before the first manual completion when an action unlocks after one', () => {
|
||||
const content = automationContent();
|
||||
@@ -109,6 +132,15 @@ describe('automation queue CRUD', () => {
|
||||
expect(() => removeFromAutomationQueue(state, 1)).toThrow(RangeError);
|
||||
});
|
||||
|
||||
it('throws RangeError when removing a non-integer index', () => {
|
||||
const content = automationContent();
|
||||
const state = createGameState(content);
|
||||
state.automationQueue = ['forage'];
|
||||
|
||||
expect(() => removeFromAutomationQueue(state, 0.5)).toThrow(RangeError);
|
||||
expect(state.automationQueue).toEqual(['forage']);
|
||||
});
|
||||
|
||||
it('empties the queue', () => {
|
||||
const content = automationContent();
|
||||
const state = createGameState(content);
|
||||
|
||||
@@ -37,7 +37,7 @@ export function addToAutomationQueue(state: GameState, content: Content, actionI
|
||||
}
|
||||
|
||||
export function removeFromAutomationQueue(state: GameState, index: number): void {
|
||||
if (index < 0 || index >= state.automationQueue.length) {
|
||||
if (!Number.isInteger(index) || index < 0 || index >= state.automationQueue.length) {
|
||||
throw new RangeError(`Automation queue index ${index} is out of range`);
|
||||
}
|
||||
state.automationQueue.splice(index, 1);
|
||||
|
||||
+1
-5
@@ -103,11 +103,7 @@ function grantYields(state: GameState, content: Content, actionId: string): void
|
||||
}
|
||||
}
|
||||
|
||||
export function recordManualCompletion(
|
||||
state: GameState,
|
||||
content: Content,
|
||||
actionId: string,
|
||||
): void {
|
||||
export function recordManualCompletion(state: GameState, content: Content, actionId: string): void {
|
||||
if (!content.actionsById[actionId]) return;
|
||||
state.manualCompletionCounts[actionId] = (state.manualCompletionCounts[actionId] ?? 0) + 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user