behaviortree
Version:
A JavaScript implementation of Behavior Trees. They are useful for implementing AIs. For Browsers and NodeJS.
153 lines (152 loc) • 6.14 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/* eslint-env jest */
/* eslint-disable @typescript-eslint/no-explicit-any */
const constants_1 = require("./constants");
const ParallelComplete_1 = __importDefault(require("./ParallelComplete"));
const Task_1 = __importDefault(require("./Task"));
describe('ParallelComplete', () => {
let countSuccess = 0;
const successTask = new Task_1.default({
run: function () {
++countSuccess;
return constants_1.SUCCESS;
}
});
let countFail = 0;
const failTask = new Task_1.default({
run: function () {
++countFail;
return constants_1.FAILURE;
}
});
let countRunning = 0;
const runningTask = new Task_1.default({
run: function () {
++countRunning;
return constants_1.RUNNING;
}
});
beforeEach(() => {
countSuccess = 0;
countFail = 0;
countRunning = 0;
});
it('runs all child nodes and returns running as long as all nodes are running', () => {
const parallelComplete = new ParallelComplete_1.default({
nodes: [runningTask, runningTask, runningTask]
});
const result = parallelComplete.run();
expect(countRunning).toEqual(3);
expect(result).toEqual({ total: constants_1.RUNNING, state: [constants_1.RUNNING, constants_1.RUNNING, constants_1.RUNNING] });
});
it('runs success if one node is success, and not one failing', () => {
const parallelComplete = new ParallelComplete_1.default({
nodes: [runningTask, successTask, runningTask]
});
const result = parallelComplete.run();
expect(countSuccess).toEqual(1);
expect(countRunning).toEqual(2);
expect(result).toEqual(constants_1.SUCCESS);
});
it('runs failure if one node is failure', () => {
const parallelComplete = new ParallelComplete_1.default({
nodes: [runningTask, successTask, failTask]
});
const result = parallelComplete.run();
expect(countSuccess).toEqual(1);
expect(countFail).toEqual(1);
expect(countRunning).toEqual(1);
expect(result).toEqual(constants_1.FAILURE);
});
describe('running tasks', () => {
const switchTask = new Task_1.default({
run: function (blackboard) {
++blackboard.switchCounter1;
return blackboard.switchResult1;
}
});
const switchTask2 = new Task_1.default({
run: function (blackboard) {
++blackboard.switchCounter2;
return blackboard.switchResult2;
}
});
const switchTask3 = new Task_1.default({
run: function (blackboard) {
++blackboard.switchCounter3;
return blackboard.switchResult3;
}
});
const parallelComplete = new ParallelComplete_1.default({
nodes: [switchTask, switchTask2, switchTask3]
});
it('returns running as long as one task is running and stops if at least one task is returning a result', () => {
const blackboard = {
switchCounter1: 0,
switchResult1: constants_1.RUNNING,
switchCounter2: 0,
switchResult2: constants_1.RUNNING,
switchCounter3: 0,
switchResult3: constants_1.RUNNING
};
let result = parallelComplete.run(blackboard);
expect(blackboard.switchCounter1).toEqual(1);
expect(blackboard.switchCounter2).toEqual(1);
expect(blackboard.switchCounter3).toEqual(1);
expect(result).toEqual({ total: constants_1.RUNNING, state: [constants_1.RUNNING, constants_1.RUNNING, constants_1.RUNNING] });
blackboard.switchResult2 = constants_1.SUCCESS;
result = parallelComplete.run(blackboard, { lastRun: result });
expect(blackboard.switchCounter1).toEqual(2);
expect(blackboard.switchCounter2).toEqual(2);
expect(blackboard.switchCounter3).toEqual(2);
expect(result).toEqual(constants_1.SUCCESS);
});
});
describe('start and end callbacks', () => {
const switchTask = new Task_1.default({
start: function (blackboard) {
++blackboard.start;
},
run: function (blackboard) {
++blackboard.run;
return blackboard.switchResult;
},
end: function (blackboard) {
++blackboard.end;
}
});
const runningTask = new Task_1.default({
run: function () {
return constants_1.RUNNING;
}
});
it('start is not called again on further running node', () => {
const parallelComplete = new ParallelComplete_1.default({
nodes: [runningTask, switchTask, runningTask]
});
const blackboard = {
switchResult: constants_1.RUNNING,
start: 0,
run: 0,
end: 0
};
const result = parallelComplete.run(blackboard);
expect(blackboard.start).toEqual(1);
expect(blackboard.run).toEqual(1);
expect(blackboard.end).toEqual(0);
const result2 = parallelComplete.run(blackboard, { lastRun: result, rerun: true });
expect(blackboard.start).toEqual(1);
expect(blackboard.run).toEqual(2);
expect(blackboard.end).toEqual(0);
blackboard.switchResult = constants_1.SUCCESS;
parallelComplete.run(blackboard, { lastRun: result2, rerun: true });
expect(blackboard.start).toEqual(1);
expect(blackboard.run).toEqual(3);
expect(blackboard.end).toEqual(1);
});
});
});