blueshell
Version:
A Behavior Tree implementation in modern Javascript
151 lines • 6.29 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
/**
* Created by josh on 1/10/16.
*/
const chai_1 = require("chai");
const lib_1 = require("../../lib");
const Behavior = __importStar(require("../../lib"));
const Base = Behavior.Action;
const Decorator = Behavior.Decorator;
class TestState {
}
class TestAction extends Base {
constructor(name, preconditionStatus = true) {
super(name);
this.preconditionStatus = preconditionStatus;
}
precondition() {
return this.preconditionStatus;
}
}
describe('Base', function () {
describe('#name', function () {
it('has a name', function () {
chai_1.assert.equal(new TestAction().name, 'TestAction');
chai_1.assert.equal(new TestAction('override').name, 'override');
});
});
describe('#path', function () {
it('sets a simple path', function () {
const node = new Base('test');
chai_1.assert.equal(node.path, 'test', 'Node Name');
});
it('builds hierarchical paths', function () {
const leaf = new TestAction('leaf');
const parent1 = new Decorator('parent1', leaf);
const parent2 = new Decorator('parent2_foo', parent1);
chai_1.assert.ok(parent2);
chai_1.assert.equal(leaf.path, 'parent2_foo_parent1_leaf');
chai_1.assert.equal(parent1.path, 'parent2_foo_parent1');
});
});
describe('#getNodeStorage', function () {
it('has separate storage for each state', function () {
const node = new Base('test');
const state1 = new TestState();
const state2 = new TestState();
const storage = node.getNodeStorage(state1);
storage.testData = 'Node Data';
chai_1.assert.equal(node.getNodeStorage(state1).testData, 'Node Data', 'Testing Storage');
chai_1.assert.ok(node.getNodeStorage(state2), 'state2 storage found');
chai_1.assert.notOk(node.getNodeStorage(state2).testData, 'state2 testData not found');
});
});
describe('#handleEvent', function () {
it('handles events', function () {
const action = new TestAction();
const res = action.handleEvent(new TestState(), 'testEvent');
// console.log('TestAction completed', res);
chai_1.assert.equal(res, lib_1.rc.SUCCESS);
});
});
describe('#precondition', function () {
it('should return FAILURE if the precondition fails', function () {
const action = new TestAction('will fail', false);
const res = action.handleEvent(new TestState(), 'testEvent');
// console.log('TestAction completed', res);
chai_1.assert.equal(res, lib_1.rc.FAILURE);
});
});
describe('#EventCounter', function () {
it('Parent Node Counter', function () {
const root = new Base('root');
const state = new TestState();
root.handleEvent(state, {});
root.handleEvent(state, {});
chai_1.assert.equal(root.getTreeEventCounter(state), 2);
chai_1.assert.equal(root.getLastEventSeen(state), 2);
});
it('Child Node Counter', function () {
const child = new Base('child');
const root = new Behavior.Decorator('root', child);
const state = new TestState();
// Since it has a parent, it should increment
// the local node but not the eventCounter
root.handleEvent(state, {});
root.handleEvent(state, {});
chai_1.assert.equal(root.getTreeEventCounter(state), 2);
chai_1.assert.equal(root.getLastEventSeen(state), 2);
chai_1.assert.equal(child.getTreeEventCounter(state), 2);
chai_1.assert.equal(child.getLastEventSeen(state), 2, 'last event seen should be updated');
chai_1.assert.equal(child.parent, root.name);
});
});
describe('publisher', function () {
it('Has a non publisher by default', function () {
chai_1.assert.isTrue(Base.treePublisher instanceof Behavior.TreeNonPublisher);
});
it('We can make a publisher', function () {
const action = new TestAction();
let published = false;
const publisher = {
publishResult(_state, _event, _topLevel) {
published = true;
},
configure(_options) {
// no-op
return;
},
};
Base.registerTreePublisher(publisher);
const res = action.handleEvent(new TestState(), 'testEvent');
chai_1.assert.equal(res, lib_1.rc.SUCCESS);
chai_1.assert.isTrue(published);
});
});
});
//# sourceMappingURL=Base.test.js.map