From 462dd664f0b9f04569bb05255608a8bd6b369bb3 Mon Sep 17 00:00:00 2001 From: b4rtaz Date: Thu, 27 Jul 2023 23:23:13 +0200 Subject: [PATCH] 0.2.0. --- CHANGELOG.md | 8 +++ package.json | 2 +- .../definition-walker.spec.ts | 47 +++++++++--- src/definition-walker/definition-walker.ts | 71 ++++++++++--------- 4 files changed, 86 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7eac55d..4ce59b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 0.2.0 + +* Added the `forEachChildren` method to the `DefinitionWalker` class. + +### Breaking Changes + +* The `forEach` method doesn't accept a sequence anymore. To foreach over a sequence, use the `forEachSequence` method. + ## 0.1.4 * Added the `forEach()` method to the `DefinitionWalker` class. diff --git a/package.json b/package.json index e6f8aae..3f9684a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "sequential-workflow-model", "description": "Extendable data model of sequential workflow.", - "version": "0.1.4", + "version": "0.2.0", "homepage": "https://nocode-js.com/", "author": { "name": "NoCode JS", diff --git a/src/definition-walker/definition-walker.spec.ts b/src/definition-walker/definition-walker.spec.ts index 5504b93..f9a9689 100644 --- a/src/definition-walker/definition-walker.spec.ts +++ b/src/definition-walker/definition-walker.spec.ts @@ -164,10 +164,25 @@ describe('DefinitionWalker', () => { expect(count).toEqual(6); }); + it('stops when callback returns false', () => { + let count = 0; + + walker.forEach(definition, () => { + count++; + if (count === 2) { + return false; + } + }); + + expect(count).toEqual(2); + }); + }); + + describe('forEachSequence', () => { it('iterates over sequence', () => { const steps: Step[] = []; - walker.forEach(loop.sequence, step => { + walker.forEachSequence(loop.sequence, step => { steps.push(step); }); @@ -176,18 +191,32 @@ describe('DefinitionWalker', () => { expect(steps[1]).toBe(ifAlfa); expect(steps[2]).toBe(taskFoo); }); + }); - it('stops when callback returns false', () => { - let count = 0; + describe('forEachChildren', () => { + it('iterates when sequential step is passed', () => { + const steps: Step[] = []; - walker.forEach(definition, () => { - count++; - if (count === 2) { - return false; - } + walker.forEachChildren(loop, step => { + steps.push(step); }); - expect(count).toEqual(2); + expect(steps.length).toEqual(3); + expect(steps[0]).toBe(ifBeta); + expect(steps[1]).toBe(ifAlfa); + expect(steps[2]).toBe(taskFoo); + }); + + it('iterates when branched step is passed', () => { + const steps: Step[] = []; + + walker.forEachChildren(ifBeta, step => { + steps.push(step); + }); + + expect(steps.length).toEqual(2); + expect(steps[0]).toBe(ifAlfa); + expect(steps[1]).toBe(taskFoo); }); }); }); diff --git a/src/definition-walker/definition-walker.ts b/src/definition-walker/definition-walker.ts index a93c555..98ac1e3 100644 --- a/src/definition-walker/definition-walker.ts +++ b/src/definition-walker/definition-walker.ts @@ -104,9 +104,16 @@ export class DefinitionWalker { return this.getParentSequence(definition, stepId).step; } - public forEach(sequenceOrDefinition: Sequence | Definition, callback: StepForEachCallback) { - const sequence = Array.isArray(sequenceOrDefinition) ? sequenceOrDefinition : sequenceOrDefinition.sequence; - this.iterate(sequence, callback); + public forEach(definition: Definition, callback: StepForEachCallback) { + this.iterateSequence(definition.sequence, callback); + } + + public forEachSequence(sequence: Sequence, callback: StepForEachCallback) { + this.iterateSequence(sequence, callback); + } + + public forEachChildren(step: Step, callback: StepForEachCallback) { + this.iterateStep(step, callback); } private find( @@ -138,7 +145,6 @@ export class DefinitionWalker { } } break; - case StepChildrenType.branches: { const branches = children.items as Branches; @@ -153,51 +159,52 @@ export class DefinitionWalker { } } break; - default: - throw new Error(`Step children type ${children.type} is not supported`); + throw new Error(`Not supported step children type: ${children.type}`); } } } return false; } - private iterate(sequence: Sequence, callback: StepForEachCallback): boolean { + private iterateSequence(sequence: Sequence, callback: StepForEachCallback): boolean { const count = sequence.length; for (let index = 0; index < count; index++) { const step = sequence[index]; if (callback(step, index, sequence) === false) { return false; } + if (!this.iterateStep(step, callback)) { + return false; + } + } + return true; + } - const children = this.getChildren(step); - if (children) { - switch (children.type) { - case StepChildrenType.sequence: - { - const childSequence = children.items as Sequence; - if (this.iterate(childSequence, callback) === false) { - return false; - } + private iterateStep(step: Step, callback: StepForEachCallback): boolean { + const children = this.getChildren(step); + if (children) { + switch (children.type) { + case StepChildrenType.sequence: + { + const sequence = children.items as Sequence; + if (!this.iterateSequence(sequence, callback)) { + return false; } - break; - - case StepChildrenType.branches: - { - const branches = children.items as Branches; - const branchNames = Object.keys(branches); - for (const branchName of branchNames) { - const parentSequence = branches[branchName]; - if (this.iterate(parentSequence, callback) === false) { - return false; - } + } + break; + case StepChildrenType.branches: + { + const sequences = Object.values(children.items as Branches); + for (const sequence of sequences) { + if (!this.iterateSequence(sequence, callback)) { + return false; } } - break; - - default: - throw new Error(`Step children type ${children.type} is not supported`); - } + } + break; + default: + throw new Error(`Not supported step children type: ${children.type}`); } } return true;