40 lines
2.6 KiB
JavaScript
40 lines
2.6 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { pathToFileURL } from 'node:url';
|
|
import { resolve } from 'node:path';
|
|
const root=process.env.MOSAIC_REVIEW_ROOT ?? new URL('./wt/',import.meta.url).pathname;
|
|
const moduleAt=path=>import(pathToFileURL(resolve(root,path)));
|
|
const { world }=await moduleAt('packages/tasks/tests/world.mjs');
|
|
const { loadRequirements, checkRequirements, RequirementsError }=await moduleAt('packages/tasks/src/requirements.mjs');
|
|
const { turnRequest }=await moduleAt('packages/harness/src/runner.mjs');
|
|
const raw=()=>structuredClone(loadRequirements());
|
|
test('every approved requirement creates, preserving its id', async t=>{
|
|
const w=await world(t); await w.adapter.start('demo'); const pm=w.agent('pm');
|
|
const {requirements}=loadRequirements();
|
|
for(const {id} of requirements) await w.call(pm,'task.create',{title:id,request:w.instruction(),requirement:id});
|
|
assert.deepEqual(w.events('task.created').map(e=>e.body.requirement),requirements.map(r=>r.id));
|
|
});
|
|
test('the received human request is visible in the runner header and creates a task',async t=>{
|
|
const w=await world(t); await w.adapter.start('demo'); const pm=w.agent('pm');
|
|
w.broker.request(w.human,{verb:'message.send',args:{to:'pm',body:'do this'}});
|
|
const [message]=w.broker.request(pm,{verb:'message.receive'});
|
|
const header=turnRequest(message); assert.ok(header.includes(`request ${message.request}`));
|
|
const request=header.match(/, request ([^:]+):\n/)[1]; assert.equal(request,message.request);
|
|
await w.call(pm,'task.create',{title:'header request',request,requirement:'REQ-TASK-1'});
|
|
});
|
|
test('inherited top keys refuse',()=>{
|
|
const l=raw(); const inherited=Object.create({prd:l.prd}); inherited.version=l.version; inherited.requirements=l.requirements;
|
|
assert.throws(()=>checkRequirements(inherited), e=>e instanceof RequirementsError && e.message==='list: missing prd');
|
|
});
|
|
test('inherited entry keys refuse',()=>{
|
|
const l=raw(); const r=l.requirements[0]; l.requirements[0]=Object.assign(Object.create({id:r.id}),{title:r.title});
|
|
assert.throws(()=>checkRequirements(l),e=>e instanceof RequirementsError && e.message==='requirements[0]: missing id');
|
|
});
|
|
test('null prototypes are accepted when all required keys are own',()=>{
|
|
const l=Object.assign(Object.create(null),raw()); l.requirements=l.requirements.map(r=>Object.assign(Object.create(null),r));
|
|
assert.equal(checkRequirements(l),l);
|
|
});
|
|
test('carriage return is accepted in a title (documented minor boundary)',()=>{
|
|
const l=raw(); l.requirements[0].title='one\rtwo'; assert.equal(checkRequirements(l),l);
|
|
});
|