feat(import): expose additional BpmnTreeWalker functionality
* expose API needed for lazy sub-process imports * also changes #handleDeferred to NOT expect deferred as a parameter anymore Related to bpmn-io/bpmn-js-signavio-compat#1
This commit is contained in:
parent
a74ed871a4
commit
12a38da9c7
|
@ -10,6 +10,7 @@ import {
|
|||
elementToString
|
||||
} from './Util';
|
||||
|
||||
// TODO: should be configurable: true as well which would allow to remove binding
|
||||
var diRefs = new Refs({ name: 'bpmnElement', enumerable: true }, { name: 'di' });
|
||||
|
||||
/**
|
||||
|
@ -230,7 +231,7 @@ export default function BpmnTreeWalker(handler, translate) {
|
|||
handleDeferred(deferred);
|
||||
}
|
||||
|
||||
function handleDeferred(deferred) {
|
||||
function handleDeferred() {
|
||||
|
||||
var fn;
|
||||
|
||||
|
@ -453,6 +454,9 @@ export default function BpmnTreeWalker(handler, translate) {
|
|||
// API //////////////////////
|
||||
|
||||
return {
|
||||
handleDefinitions: handleDefinitions
|
||||
handleDeferred: handleDeferred,
|
||||
handleDefinitions: handleDefinitions,
|
||||
handleSubProcess: handleSubProcess,
|
||||
registerDi: registerDi
|
||||
};
|
||||
}
|
|
@ -0,0 +1,176 @@
|
|||
/* global sinon */
|
||||
|
||||
import BpmnTreeWalker from 'lib/import/BpmnTreeWalker';
|
||||
|
||||
import BpmnModdle from 'bpmn-moddle';
|
||||
|
||||
import { find } from 'min-dash';
|
||||
|
||||
import simpleXML from 'test/fixtures/bpmn/simple.bpmn';
|
||||
|
||||
|
||||
describe('import - BpmnTreeWalker', function() {
|
||||
|
||||
it('should expose functions', function() {
|
||||
|
||||
// when
|
||||
const walker = createWalker();
|
||||
|
||||
// then
|
||||
expect(walker.handleDeferred).to.exist;
|
||||
expect(walker.handleDefinitions).to.exist;
|
||||
expect(walker.handleSubProcess).to.exist;
|
||||
expect(walker.registerDi).to.exist;
|
||||
});
|
||||
|
||||
|
||||
it('should walk bpmn:Definitions', function(done) {
|
||||
|
||||
// given
|
||||
const elementSpy = sinon.spy(),
|
||||
rootSpy = sinon.spy(),
|
||||
errorSpy = sinon.spy();
|
||||
|
||||
const walker = createWalker({
|
||||
element: elementSpy,
|
||||
root: rootSpy,
|
||||
error: errorSpy
|
||||
});
|
||||
|
||||
createModdle(simpleXML, (err, definitions, context, moddle) => {
|
||||
|
||||
// when
|
||||
walker.handleDefinitions(definitions);
|
||||
|
||||
// then
|
||||
expect(elementSpy.callCount).to.equal(8);
|
||||
expect(rootSpy.calledOnce).to.be.true;
|
||||
expect(errorSpy.notCalled).to.be.true;
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should walk bpmn:SubProcess', function(done) {
|
||||
|
||||
// given
|
||||
const elementSpy = sinon.spy(),
|
||||
rootSpy = sinon.spy(),
|
||||
errorSpy = sinon.spy();
|
||||
|
||||
const walker = createWalker({
|
||||
element: elementSpy,
|
||||
root: rootSpy,
|
||||
error: errorSpy
|
||||
});
|
||||
|
||||
createModdle(simpleXML, (err, definitions, context, moddle) => {
|
||||
const subProcess = findElementWithId(definitions, 'SubProcess_1');
|
||||
|
||||
const plane = definitions.diagrams[0].plane,
|
||||
planeElements = plane.planeElement;
|
||||
|
||||
// register DI
|
||||
planeElements.forEach(walker.registerDi);
|
||||
|
||||
// when
|
||||
walker.handleSubProcess(subProcess);
|
||||
|
||||
walker.handleDeferred();
|
||||
|
||||
// then
|
||||
expect(elementSpy.callCount).to.equal(3);
|
||||
expect(rootSpy.notCalled).to.be.true;
|
||||
expect(errorSpy.notCalled).to.be.true;
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should error', function(done) {
|
||||
|
||||
// given
|
||||
const elementSpy = sinon.spy(),
|
||||
rootSpy = sinon.spy(),
|
||||
errorSpy = sinon.spy();
|
||||
|
||||
const walker = createWalker({
|
||||
element: elementSpy,
|
||||
root: rootSpy,
|
||||
error: errorSpy
|
||||
});
|
||||
|
||||
createModdle(simpleXML, (err, definitions, context, moddle) => {
|
||||
|
||||
const element = findElementWithId(definitions, 'SubProcess_1');
|
||||
|
||||
// will error
|
||||
element.di = 'DI';
|
||||
|
||||
// when
|
||||
walker.handleDefinitions(definitions);
|
||||
|
||||
// then
|
||||
expect(elementSpy.callCount).to.equal(8);
|
||||
expect(rootSpy.calledOnce).to.be.true;
|
||||
expect(errorSpy.calledOnce).to.be.true;
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
// helpers //////////
|
||||
|
||||
function createModdle(xml, done) {
|
||||
const moddle = new BpmnModdle();
|
||||
|
||||
moddle.fromXML(xml, 'bpmn:Definitions', (err, definitions, context) => {
|
||||
done(err, definitions, context, moddle);
|
||||
});
|
||||
}
|
||||
|
||||
function createWalker(listeners = {}) {
|
||||
const visitor = {
|
||||
element(element, parent) {
|
||||
listeners.element && listeners.element(element, parent);
|
||||
},
|
||||
root(root) {
|
||||
listeners.root && listeners.root(root);
|
||||
},
|
||||
error(message, context) {
|
||||
listeners.error && listeners.error(message, context);
|
||||
}
|
||||
};
|
||||
|
||||
return new BpmnTreeWalker(visitor, function() {});
|
||||
}
|
||||
|
||||
function findElementWithId(definitions, id) {
|
||||
|
||||
function findElement(element) {
|
||||
if (element.id === id) {
|
||||
return element;
|
||||
}
|
||||
|
||||
if (element.flowElements) {
|
||||
return find(element.flowElements, flowElement => {
|
||||
const foundElement = findElement(flowElement);
|
||||
|
||||
return foundElement && foundElement.id === id;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return definitions.rootElements.reduce((foundElement, rootElement) => {
|
||||
if (rootElement.id === id) {
|
||||
return rootElement;
|
||||
} else {
|
||||
return findElement(rootElement) || foundElement;
|
||||
}
|
||||
}, null);
|
||||
}
|
Loading…
Reference in New Issue