Files
DiceCloud/app/imports/api/engine/action/applyProperties/applyBranchProperty.test.ts
2024-09-06 17:12:04 +02:00

377 lines
9.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { assert } from 'chai';
import {
allMutations,
createTestCreature,
getRandomIds,
removeAllCreaturesAndProps,
runActionById
} from '/imports/api/engine/action/functions/actionEngineTest.testFn';
const [
creatureId, targetCreatureId, ifTrueBranchId, ifFalseBranchId, indexBranchId, attackHitId, attackMissId, saveSucceedId, saveFailId, randomBranchId, targetCreature2Id, eachTargetBranchId, choiceBranchId,
] = getRandomIds(100);
const actionTestCreature = {
_id: creatureId,
props: [
// If branch
{
_id: ifTrueBranchId,
type: 'branch',
branchType: 'if',
condition: { calculation: 'true' },
children: [
{
type: 'note',
summary: { text: 'this should run' },
},
],
},
{
_id: ifFalseBranchId,
type: 'branch',
branchType: 'if',
condition: { calculation: 'false' },
children: [
{
type: 'note',
summary: { text: 'this should not run' },
},
],
},
// index branch
{
_id: indexBranchId,
type: 'branch',
branchType: 'index',
condition: { calculation: '1 + 1' },
children: [
{
type: 'note',
summary: { text: 'FAIL: index child 1 should not run' },
},
{
type: 'note',
summary: { text: 'Child 2 should run' },
},
{
type: 'note',
summary: { text: 'FAIL: index child 3 should not run' },
},
],
},
// Hit and miss branches
{
_id: attackHitId,
type: 'action',
attackRoll: { calculation: '1' },
children: [
{
type: 'branch',
branchType: 'hit',
children: [{
type: 'note',
summary: { text: 'attack hit branch' }
}],
},
{
type: 'branch',
branchType: 'miss',
children: [{
type: 'note',
summary: { text: 'attack miss branch' }
}],
},
]
},
{
_id: attackMissId,
type: 'action',
attackRoll: { calculation: '-1' },
children: [
{
type: 'branch',
branchType: 'hit',
children: [{
type: 'note',
summary: { text: 'attack hit branch' }
}],
},
{
type: 'branch',
branchType: 'miss',
children: [{
type: 'note',
summary: { text: 'attack miss branch' }
}],
},
]
},
// Save and fail save branch
{
_id: saveSucceedId,
type: 'savingThrow',
dc: { calculation: '10' },
target: 'target',
stat: 'strengthSave',
children: [
{
type: 'branch',
branchType: 'successfulSave',
children: [{
type: 'note',
summary: { text: 'made save branch' }
}],
},
{
type: 'branch',
branchType: 'failedSave',
children: [{
type: 'note',
summary: { text: 'failed save branch' }
}],
},
]
},
{
_id: saveFailId,
type: 'savingThrow',
dc: { calculation: '15' },
target: 'target',
stat: 'strengthSave',
children: [
{
type: 'branch',
branchType: 'successfulSave',
children: [{
type: 'note',
summary: { text: 'made save branch' }
}],
},
{
type: 'branch',
branchType: 'failedSave',
children: [{
type: 'note',
summary: { text: 'failed save branch' }
}],
},
]
},
// Random branch
{
_id: randomBranchId,
type: 'branch',
branchType: 'random',
children: [
{
type: 'note',
summary: { text: 'FAIL: random child 1 should not run' },
},
{
type: 'note',
summary: { text: 'Random child 2 should run' },
},
{
type: 'note',
summary: { text: 'FAIL: random child 3 should not run' },
},
],
},
// Each target branch
{
_id: eachTargetBranchId,
type: 'branch',
branchType: 'eachTarget',
children: [
{
type: 'note',
summary: { text: 'some note' }
}
]
},
// Choice branch
{
_id: choiceBranchId,
type: 'branch',
branchType: 'choice',
children: [
{
type: 'note',
summary: { text: 'Choice child 1 should run' },
},
{
type: 'note',
summary: { text: 'Fail: choice child 2 should not run' },
},
{
type: 'note',
summary: { text: 'Fail: choice child 3 should not run' },
},
],
},
],
}
const actionTargetCreature = {
_id: targetCreatureId,
props: [
{
type: 'attribute',
attributeType: 'stat',
variableName: 'armor',
baseValue: { calculation: '10' },
},
{
type: 'skill',
skillType: 'save',
variableName: 'strengthSave',
baseValue: { calculation: '3' },
},
]
}
const actionTargetCreature2 = {
_id: targetCreature2Id,
props: [
{
type: 'attribute',
attributeType: 'stat',
variableName: 'armor',
baseValue: { calculation: '15' },
},
]
}
describe('Apply Branch Properties', function () {
// Increase timeout
this.timeout(8000);
before(async function () {
await removeAllCreaturesAndProps();
await createTestCreature(actionTestCreature);
await createTestCreature(actionTargetCreature);
await createTestCreature(actionTargetCreature2);
});
// If branch
it('Runs an if branch with a true condition', async function () {
const action = await runActionById(ifTrueBranchId);
assert.deepEqual(allMutations(action), [{
contents: [{ value: 'this should run' }],
targetIds: [],
}]);
});
it('runs an if branch with a false condition', async function () {
const action = await runActionById(ifFalseBranchId);
assert.deepEqual(allMutations(action), []);
});
it('runs an if branch and chooses the correct child', async function () {
const action = await runActionById(indexBranchId);
assert.deepEqual(allMutations(action), [{
contents: [{ value: 'Child 2 should run' }],
targetIds: [],
}]);
});
// Hit and miss branch
it('Runs only hit branches on an attack that hits', async function () {
const action = await runActionById(attackHitId, [targetCreatureId]);
assert.deepEqual(allMutations(action), [{
contents: [{ name: 'Action' }],
targetIds: [targetCreatureId],
}, {
contents: [{ inline: true, name: 'Hit!', value: '1d20 [10] + 1\n**11**' }],
targetIds: [targetCreatureId],
}, {
contents: [{ value: 'attack hit branch' }],
targetIds: [targetCreatureId],
}]);
});
it('Runs only miss branches on an attack that misses', async function () {
const action = await runActionById(attackMissId, [targetCreatureId]);
assert.deepEqual(allMutations(action), [{
contents: [{ name: 'Action' }],
targetIds: [targetCreatureId],
}, {
contents: [{ inline: true, name: 'Miss!', value: '1d20 [10] 1\n**9**' }],
targetIds: [targetCreatureId],
}, {
contents: [{ value: 'attack miss branch' }],
targetIds: [targetCreatureId],
}]);
});
// Save succeed and fail branches
it('Runs only miss branches on an attack that misses', async function () {
const action = await runActionById(saveSucceedId, [targetCreatureId]);
assert.deepEqual(allMutations(action), [{
contents: [{
name: 'Saving throw',
value: 'DC **10**',
inline: true
}, {
name: 'Successful save',
value: '1d20 [ 10 ] + 3\n**13**',
inline: true
}],
targetIds: [targetCreatureId],
}, {
contents: [{ value: 'made save branch' }],
targetIds: [targetCreatureId],
}]);
});
it('Runs only miss branches on an attack that misses', async function () {
const action = await runActionById(saveFailId, [targetCreatureId]);
assert.deepEqual(allMutations(action), [{
contents: [{
name: 'Saving throw',
value: 'DC **15**',
inline: true
}, {
name: 'Failed save',
value: '1d20 [ 10 ] + 3\n**13**',
inline: true
}],
targetIds: [targetCreatureId],
}, {
contents: [{ value: 'failed save branch' }],
targetIds: [targetCreatureId],
}]);
});
// Random branches, RNG is fixed at average for testing, so child 2 should run
it('runs a random branch and chooses the correct child', async function () {
const action = await runActionById(randomBranchId);
assert.deepEqual(allMutations(action), [{
contents: [{ value: 'Random child 2 should run' }],
targetIds: [],
}]);
});
// Branches can split actions across targets
it('Can split actions to targets using a branch', async function () {
const action = await runActionById(eachTargetBranchId, [targetCreatureId, targetCreature2Id]);
assert.deepEqual(allMutations(action), [{
contents: [{ value: 'some note' }],
targetIds: [targetCreatureId],
}, {
contents: [{ value: 'some note' }],
targetIds: [targetCreature2Id],
}]);
});
// Choice branches, choices are fixed to first option for testing
it('runs a choice branch and chooses the correct child', async function () {
const action = await runActionById(choiceBranchId);
assert.deepEqual(allMutations(action), [{
contents: [{ value: 'Choice child 1 should run' }],
targetIds: [],
}]);
});
});