diff --git a/package.json b/package.json index 4f55f1e..585bb12 100644 --- a/package.json +++ b/package.json @@ -22,8 +22,8 @@ "watch": "npm run build:node -- --watch", "test": "npm-run-all build test:unit-test", "build:format": "prettier --write \"src/**/*.ts\" \"test/**/*.js\"", - "build:node": "esbuild ./src/index.js --bundle --sourcemap --outdir=dist --platform=node", - "build:web": "esbuild ./src/index.js --bundle --sourcemap --platform=browser --global-name=mistreevous --outfile=dist/bundle.js", + "build:node": "esbuild ./src/index.ts --bundle --sourcemap --outdir=dist --platform=node", + "build:web": "esbuild ./src/index.ts --bundle --sourcemap --platform=browser --global-name=mistreevous --outfile=dist/bundle.js", "build:typecheck": "tsc --emitDeclarationOnly", "test:unit-test": "mocha \"test/**/*.js\"" }, diff --git a/test/nodes/composite/Lotto.test.js b/test/nodes/composite/Lotto.test.js index 7376e31..83af99b 100644 --- a/test/nodes/composite/Lotto.test.js +++ b/test/nodes/composite/Lotto.test.js @@ -418,7 +418,7 @@ describe("A Lotto node", () => { }); }); - describe("move to the RUNNING state if the selected child node does not move to the SUCCESS or FAILED state", () => { + describe("move to the RUNNING state if the selected child node is in the RUNNING state", () => { it("(MDSL)", () => { const definition = "root { lotto { action [someAction] } }"; const agent = { someAction: () => {} }; diff --git a/test/nodes/composite/Selector.test.js b/test/nodes/composite/Selector.test.js index e1cf352..99cf463 100644 --- a/test/nodes/composite/Selector.test.js +++ b/test/nodes/composite/Selector.test.js @@ -3,6 +3,9 @@ const chai = require("chai"); var assert = chai.assert; +const findNode = (tree, type, caption) => + tree.getFlattenedNodeDetails().find((node) => node.type === type && node.caption === caption); + describe("A Selector node", () => { describe("on tree initialisation", () => { describe("will error if the node does not have at least one child", () => { @@ -32,5 +35,79 @@ describe("A Selector node", () => { }); }); - describe("when updated as part of a tree step will", () => {}); + describe("when updated as part of a tree step will", () => { + describe("move to the FAILED state if all child nodes move to the FAILED state", () => {}); + + describe("move to the SUCCEEDED state if any child node moves to the SUCCEEDED state", () => {}); + + describe("move to the RUNNING state if any child node is in the RUNNING state", () => { + it("(MDSL)", () => { + const definition = + "root { selector { action [actionFail] action [actionRunning] action [actionSucceed] } }"; + const agent = { + actionSucceed: () => mistreevous.State.SUCCEEDED, + actionRunning: () => {}, + actionFail: () => mistreevous.State.FAILED + }; + const tree = new mistreevous.BehaviourTree(definition, agent); + + assert.strictEqual(findNode(tree, "root", "ROOT").state, mistreevous.State.READY); + assert.strictEqual(findNode(tree, "selector", "SELECTOR").state, mistreevous.State.READY); + assert.strictEqual(findNode(tree, "action", "actionFail").state, mistreevous.State.READY); + assert.strictEqual(findNode(tree, "action", "actionRunning").state, mistreevous.State.READY); + assert.strictEqual(findNode(tree, "action", "actionSucceed").state, mistreevous.State.READY); + + tree.step(); + + assert.strictEqual(findNode(tree, "root", "ROOT").state, mistreevous.State.RUNNING); + assert.strictEqual(findNode(tree, "selector", "SELECTOR").state, mistreevous.State.RUNNING); + assert.strictEqual(findNode(tree, "action", "actionFail").state, mistreevous.State.FAILED); + assert.strictEqual(findNode(tree, "action", "actionRunning").state, mistreevous.State.RUNNING); + assert.strictEqual(findNode(tree, "action", "actionSucceed").state, mistreevous.State.READY); + }); + + it("(JSON)", () => { + const definition = { + type: "root", + child: { + type: "selector", + children: [ + { + type: "action", + call: "actionFail" + }, + { + type: "action", + call: "actionRunning" + }, + { + type: "action", + call: "actionSucceed" + } + ] + } + }; + const agent = { + actionSucceed: () => mistreevous.State.SUCCEEDED, + actionRunning: () => {}, + actionFail: () => mistreevous.State.FAILED + }; + const tree = new mistreevous.BehaviourTree(definition, agent); + + assert.strictEqual(findNode(tree, "root", "ROOT").state, mistreevous.State.READY); + assert.strictEqual(findNode(tree, "selector", "SELECTOR").state, mistreevous.State.READY); + assert.strictEqual(findNode(tree, "action", "actionFail").state, mistreevous.State.READY); + assert.strictEqual(findNode(tree, "action", "actionRunning").state, mistreevous.State.READY); + assert.strictEqual(findNode(tree, "action", "actionSucceed").state, mistreevous.State.READY); + + tree.step(); + + assert.strictEqual(findNode(tree, "root", "ROOT").state, mistreevous.State.RUNNING); + assert.strictEqual(findNode(tree, "selector", "SELECTOR").state, mistreevous.State.RUNNING); + assert.strictEqual(findNode(tree, "action", "actionFail").state, mistreevous.State.FAILED); + assert.strictEqual(findNode(tree, "action", "actionRunning").state, mistreevous.State.RUNNING); + assert.strictEqual(findNode(tree, "action", "actionSucceed").state, mistreevous.State.READY); + }); + }); + }); }); diff --git a/test/nodes/decorator/Fail.test.js b/test/nodes/decorator/Fail.test.js index eaac606..1f0bc00 100644 --- a/test/nodes/decorator/Fail.test.js +++ b/test/nodes/decorator/Fail.test.js @@ -115,7 +115,7 @@ describe("A Fail node", () => { }); }); - describe("move to the RUNNING state if the child node does not move to the SUCCESS or FAILED state", () => { + describe("move to the RUNNING state if the child node moves to the RUNNING state", () => { it("(MDSL)", () => { const definition = "root { fail { action [someAction] } }"; const agent = { someAction: () => {} }; diff --git a/test/nodes/decorator/Succeed.test.js b/test/nodes/decorator/Succeed.test.js index 1296588..1205a85 100644 --- a/test/nodes/decorator/Succeed.test.js +++ b/test/nodes/decorator/Succeed.test.js @@ -115,7 +115,7 @@ describe("A Succeed node", () => { }); }); - describe("move to the RUNNING state if the child node does not move to the SUCCESS or FAILED state", () => { + describe("move to the RUNNING state if the child node moves to the RUNNING state", () => { it("(MDSL)", () => { const definition = "root { succeed { action [someAction] } }"; const agent = { someAction: () => {} };