import { EventConductor } from '../src'; describe('Sort Kahn', () => { test('very simple #1', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const L1 = conductor.createEventHandler({ input: [A1], output: [A2], callback: () => null }); const L2 = conductor.createEventHandler({ input: [A2], output: [], callback: () => null }); const eventHandlers = [L1, L2]; conductor.addManySignalProcessors(eventHandlers); const sorted = conductor.getEventHandlers(); expect(sorted).toEqual([L1, L2]); // ok }); test('simple #1', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const A4 = conductor.createEvent('A4'); const A5 = conductor.createEvent('A5'); const L1 = conductor.createEventHandler({ input: [A1], output: [A2], callback: () => null }); const L2 = conductor.createEventHandler({ input: [A2], output: [A3], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3], output: [A4], callback: () => null }); const L4 = conductor.createEventHandler({ input: [A4], output: [A5], callback: () => null }); const L5 = conductor.createEventHandler({ input: [A5], output: [], callback: () => null }); const eventHandlers = [L2, L3, L5, L4, L1]; conductor.addManySignalProcessors(eventHandlers); const sorted = conductor.getEventHandlers(); expect(sorted).toEqual([L1, L2, L3, L4, L5]); // ok }); test('simple #2', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const A4 = conductor.createEvent('A4'); const A5 = conductor.createEvent('A5'); const A6 = conductor.createEvent('A6'); const L1 = conductor.createEventHandler({ input: [A1], output: [A2], callback: () => null }); const L2 = conductor.createEventHandler({ input: [A2], output: [A3], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3], output: [A4], callback: () => null }); const L4 = conductor.createEventHandler({ input: [A4], output: [A5], callback: () => null }); const L5 = conductor.createEventHandler({ input: [A5], output: [], callback: () => null }); const eventHandlers = [L3, L4, L1, L5, L2]; conductor.addManySignalProcessors(eventHandlers); const sorted = conductor.getEventHandlers(); expect(sorted).toEqual([L1, L2, L3, L4, L5]); // ok }); test('simple #3', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const A4 = conductor.createEvent('A4'); const A5 = conductor.createEvent('A5'); const A6 = conductor.createEvent('A6'); const L1 = conductor.createEventHandler({ input: [A1], output: [A2], callback: () => null }); const L2 = conductor.createEventHandler({ input: [A2], output: [A3], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3], output: [A4], callback: () => null }); const L4 = conductor.createEventHandler({ input: [A4], output: [A5], callback: () => null }); const L5 = conductor.createEventHandler({ input: [A5], output: [], callback: () => null }); const eventHandlers = [L1, L2, L3, L5, L4]; conductor.addManySignalProcessors(eventHandlers); const sorted = conductor.getEventHandlers(); expect(sorted).toEqual([L1, L2, L3, L4, L5]); // ok }); test('simple #4', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const A4 = conductor.createEvent('A4'); const A5 = conductor.createEvent('A5'); const L1 = conductor.createEventHandler({ input: [A1], output: [A2], callback: () => null }); const L2 = conductor.createEventHandler({ input: [A2], output: [A3], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3], output: [A4], callback: () => null }); const L4 = conductor.createEventHandler({ input: [A4], output: [A5], callback: () => null }); const L5 = conductor.createEventHandler({ input: [A5], output: [], callback: () => null }); const eventHandlers = [L1, L2, L3, L4, L5]; conductor.addManySignalProcessors(eventHandlers); const sorted = conductor.getEventHandlers(); expect(sorted).toEqual([L1, L2, L3, L4, L5]); // ok }); test('simple #5', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const A4 = conductor.createEvent('A4'); const A5 = conductor.createEvent('A5'); const L1 = conductor.createEventHandler({ input: [A1], output: [A2], callback: () => null }); const L2 = conductor.createEventHandler({ input: [A2], output: [A3], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3], output: [A4], callback: () => null }); const L4 = conductor.createEventHandler({ input: [A4], output: [A5], callback: () => null }); const L5 = conductor.createEventHandler({ input: [A5], output: [], callback: () => null }); const eventHandlers = [L3, L5, L2, L1, L4]; conductor.addManySignalProcessors(eventHandlers); const sorted = conductor.getEventHandlers(); expect(sorted).toEqual([L1, L2, L3, L4, L5]); // ok }); test('simple #6', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const A4 = conductor.createEvent('A4'); const A5 = conductor.createEvent('A5'); const L1 = conductor.createEventHandler({ input: [A1], output: [A2], callback: () => null }); const L2_v1 = conductor.createEventHandler({ input: [A2], output: [A3], callback: () => null }); const L2_v2 = conductor.createEventHandler({ input: [A2], output: [A3], callback: () => null }); const L2_v3 = conductor.createEventHandler({ input: [A2], output: [A3], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3], output: [A4], callback: () => null }); const L4 = conductor.createEventHandler({ input: [A4], output: [A5], callback: () => null }); const L5 = conductor.createEventHandler({ input: [A5], output: [], callback: () => null }); const eventHandlers = [L3, L5, L2_v1, L2_v2, L2_v3, L1, L4]; conductor.addManySignalProcessors(eventHandlers); const sorted = conductor.getEventHandlers(); expect(sorted).toEqual([L1, L2_v1, L2_v2, L2_v3, L3, L4, L5]); // ok }); test('multi input simple #1', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const L1 = conductor.createEventHandler({ input: [A1], output: [A2], callback: () => null }); const L2 = conductor.createEventHandler({ input: [A2], output: [A3], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3, A2], output: [], callback: () => null }); const eventHandlers = [L1, L2, L3]; conductor.addManySignalProcessors(eventHandlers); const sorted = conductor.getEventHandlers(); expect(sorted).toEqual([L1, L2, L3]); // ok }); test('multi input simple #2', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const L1 = conductor.createEventHandler({ input: [A1], output: [A2], callback: () => null }); const L2 = conductor.createEventHandler({ input: [A2], output: [A3], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3, A2], output: [], callback: () => null }); const eventHandlers = [L3, L2, L1]; conductor.addManySignalProcessors(eventHandlers); const sorted = conductor.getEventHandlers(); expect(sorted).toEqual([L1, L2, L3]); // ok }); test('multi input simple #3', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const L1 = conductor.createEventHandler({ input: [A1], output: [A2], callback: () => null }); const L2 = conductor.createEventHandler({ input: [A2], output: [A3], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3, A2], output: [], callback: () => null }); const eventHandlers = [L2, L3, L1]; conductor.addManySignalProcessors(eventHandlers); const sorted = conductor.getEventHandlers(); expect(sorted).toEqual([L1, L2, L3]); // ok }); test('multi input simple #4', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const L1 = conductor.createEventHandler({ input: [A1], output: [A2], callback: () => null }); const L2 = conductor.createEventHandler({ input: [A2], output: [A3], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3, A2], output: [], callback: () => null }); const eventHandlers = [L1, L3, L2]; conductor.addManySignalProcessors(eventHandlers); const sorted = conductor.getEventHandlers(); expect(sorted).toEqual([L1, L2, L3]); // ok }); test('multi input simple #5', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const L1 = conductor.createEventHandler({ input: [A1], output: [A2], callback: () => null }); const L2 = conductor.createEventHandler({ input: [A2], output: [A3], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3, A2], output: [], callback: () => null }); const eventHandlers = [L2, L1, L3]; conductor.addManySignalProcessors(eventHandlers); const sorted = conductor.getEventHandlers(); expect(sorted).toEqual([L1, L2, L3]); // ok }); test('multi output simple #1', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const L1 = conductor.createEventHandler({ input: [A1], output: [A2, A3], callback: () => null }); const L2 = conductor.createEventHandler({ input: [A2], output: [A3], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3], output: [], callback: () => null }); const eventHandlers = [L1, L2, L3]; conductor.addManySignalProcessors(eventHandlers); const sorted = conductor.getEventHandlers(); expect(sorted).toEqual([L1, L2, L3]); // ok }); test('multi output simple #2', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const L1 = conductor.createEventHandler({ input: [A1], output: [A2, A3], callback: () => null }); const L2 = conductor.createEventHandler({ input: [A2], output: [A3], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3], output: [], callback: () => null }); const eventHandlers = [L3, L2, L1]; conductor.addManySignalProcessors(eventHandlers); const sorted = conductor.getEventHandlers(); expect(sorted).toEqual([L1, L2, L3]); // ok }); test('multi output simple #3', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const L1 = conductor.createEventHandler({ input: [A1], output: [A2, A3], callback: () => null }); const L2 = conductor.createEventHandler({ input: [A2], output: [A3], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3], output: [], callback: () => null }); const eventHandlers = [L2, L3, L1]; conductor.addManySignalProcessors(eventHandlers); const sorted = conductor.getEventHandlers(); expect(sorted).toEqual([L1, L2, L3]); // ok }); test('multi output simple #4', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const L1 = conductor.createEventHandler({ input: [A1], output: [A2, A3], callback: () => null }); const L2 = conductor.createEventHandler({ input: [A2], output: [A3], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3], output: [], callback: () => null }); const eventHandlers = [L2, L1, L3]; conductor.addManySignalProcessors(eventHandlers); const sorted = conductor.getEventHandlers(); expect(sorted).toEqual([L1, L2, L3]); // ok }); test('multi output simple #5', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const L1 = conductor.createEventHandler({ input: [A1], output: [A2, A3], callback: () => null }); const L2 = conductor.createEventHandler({ input: [A2], output: [A3], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3], output: [], callback: () => null }); const eventHandlers = [L3, L1, L2]; conductor.addManySignalProcessors(eventHandlers); const sorted = conductor.getEventHandlers(); expect(sorted).toEqual([L1, L2, L3]); // ok }); test('multi output #1 (cyclic)', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const L1 = conductor.createEventHandler({ input: [A1], output: [A2, A3], callback: () => null }); const L2 = conductor.createEventHandler({ input: [A2], output: [A3, A1], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3], output: [], callback: () => null }); const eventHandlers = [L1, L2, L3]; expect(() => conductor.addManySignalProcessors(eventHandlers)).toThrow(); // const sorted = conductor.getEventHandlers(); // expect(sorted).toEqual([L1, L2, L3]); // ok }); test('multi output #2 (cyclic)', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const L1 = conductor.createEventHandler({ input: [A1], output: [A2, A3], callback: () => null }); const L2 = conductor.createEventHandler({ input: [A2], output: [A3, A1], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3], output: [], callback: () => null }); const eventHandlers = [L3, L2, L1]; expect(() => conductor.addManySignalProcessors(eventHandlers)).toThrow(); // const sorted = conductor.getEventHandlers(); // expect(sorted).toEqual([L2, L1, L3]); // ok - it doesn't matter if L1 or L2 is first (dfs will start from L2 so it will place L2 before L1) }); test('multi output #3 (cyclic)', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const L2 = conductor.createEventHandler({ input: [A2], output: [A3, A1], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3], output: [], callback: () => null }); const L1 = conductor.createEventHandler({ input: [A1], output: [A2, A3], callback: () => null }); const eventHandlers = [L2, L3, L1]; expect(() => conductor.addManySignalProcessors(eventHandlers)).toThrow(); // const sorted = conductor.getEventHandlers(); // expect(sorted).toEqual([L2, L1, L3]); // ok }); test('multi output #3v2 (cyclic)', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const L2 = conductor.createEventHandler({ input: [A2], output: [A1, A3], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3], output: [], callback: () => null }); const L1 = conductor.createEventHandler({ input: [A1], output: [A2, A3], callback: () => null }); const eventHandlers = [L2, L3, L1]; expect(() => conductor.addManySignalProcessors(eventHandlers)).toThrow(); // const sorted = conductor.getEventHandlers(); // expect(sorted).toEqual([L2, L1, L3]); // ok }); test('multi output #4 (cyclic)', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const A4 = conductor.createEvent('A4'); const A5 = conductor.createEvent('A5'); const L1 = conductor.createEventHandler({ input: [A1], output: [A2, A3], callback: () => null }); const L2 = conductor.createEventHandler({ input: [A2], output: [A3, A1], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3], output: [], callback: () => null }); const eventHandlers = [L3, L1, L2]; expect(() => conductor.addManySignalProcessors(eventHandlers)).toThrow(); // const sorted = conductor.getEventHandlers(); // expect(sorted).toEqual([L1, L2, L3]); // ok }); test('multi output #5 (cyclic)', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const L2 = conductor.createEventHandler({ input: [A2], output: [A3, A1], callback: () => null }); const L1 = conductor.createEventHandler({ input: [A1], output: [A2, A3], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3], output: [], callback: () => null }); const eventHandlers = [L2, L1, L3]; expect(() => conductor.addManySignalProcessors(eventHandlers)).toThrow(); // const sorted = conductor.getEventHandlers(); // expect(sorted).toEqual([L2, L1, L3]); // ok }); test('multi output #2 - #1 (cyclic)', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const A4 = conductor.createEvent('A4'); const L3 = conductor.createEventHandler({ input: [A3], output: [A1, A4], callback: () => null }); const L4 = conductor.createEventHandler({ input: [A4], output: [A1], callback: () => null }); const L1 = conductor.createEventHandler({ input: [A1], output: [A2], callback: () => null }); const L2 = conductor.createEventHandler({ input: [A2], output: [A3], callback: () => null }); const eventHandlers = [L3, L1, L2, L4]; expect(() => conductor.addManySignalProcessors(eventHandlers)).toThrow(); // const sorted = conductor.getEventHandlers(); // expect(sorted).toEqual([L3, L4, L1, L2]); // ok }); test('multi output #2 - #2 (cyclic)', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const A4 = conductor.createEvent('A4'); const L1 = conductor.createEventHandler({ input: [A1], output: [A2], callback: () => null }); const L2 = conductor.createEventHandler({ input: [A2], output: [A3], callback: () => null }); const L4 = conductor.createEventHandler({ input: [A4], output: [A1], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3], output: [A1, A4], callback: () => null }); const eventHandlers = [L1, L2, L4, L3]; expect(() => conductor.addManySignalProcessors(eventHandlers)).toThrow(); // const sorted = conductor.getEventHandlers(); // expect(sorted).toEqual([L1, L2, L3, L4]); // ok }); test('final #1 (cyclic)', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const A4 = conductor.createEvent('A4'); const L1 = conductor.createEventHandler({ input: [A1], output: [A2], callback: () => null }); const L2 = conductor.createEventHandler({ input: [A2, A4], output: [A1], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3], output: [A4], callback: () => null }); const L4 = conductor.createEventHandler({ input: [A4], output: [], callback: () => null }); const eventHandlers = [L1, L2, L3, L4]; expect(() => conductor.addManySignalProcessors(eventHandlers)).toThrow(); // expect(L2.getOutput()).toEqual([]); // removed by cyclic check // const sorted = conductor.getEventHandlers(); // //expect(sorted).toEqual([L3, L4, L1, L2]); // old dfs // expect(sorted).toEqual([L1, L3, L2, L4]); // ok }); test('order when not connected', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const A4 = conductor.createEvent('A4'); const X1 = conductor.createEvent('X1'); const X2 = conductor.createEvent('X2'); const X3 = conductor.createEvent('X3'); const X4 = conductor.createEvent('X4'); const L1 = conductor.createEventHandler({ input: [A1], output: [X1], callback: () => null }); const L2 = conductor.createEventHandler({ input: [A2], output: [X2], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3], output: [X3], callback: () => null }); const L4 = conductor.createEventHandler({ input: [A4], output: [X4], callback: () => null }); const eventHandlers = [L1, L2, L3, L4]; conductor.addManySignalProcessors(eventHandlers); const sorted = conductor.getEventHandlers(); // expect(sorted).toEqual([L4, L3, L2, L1]); // old dfs will reverse the order but it doesn't matter expect(sorted).toEqual([L1, L2, L3, L4]); // ok }); test('cyclic #1', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const A4 = conductor.createEvent('A4'); const A5 = conductor.createEvent('A5'); const L1 = conductor.createEventHandler({ input: [A1], output: [A2], callback: () => null }); const L2 = conductor.createEventHandler({ input: [A2], output: [A3], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3], output: [A4, A1], callback: () => null }); const L4 = conductor.createEventHandler({ input: [A4], output: [A5], callback: () => null }); const L5 = conductor.createEventHandler({ input: [A5], output: [], callback: () => null }); const eventHandlers = [L1, L2, L3, L4, L5]; expect(() => conductor.addManySignalProcessors(eventHandlers)).toThrow(); // expect(L3.getOutput()).toEqual([A4]); // cyclic removed // expect(L1.getOutput()).toEqual([A2]); // expect(L2.getOutput()).toEqual([A3]); // const sorted = conductor.getEventHandlers(); // expect(sorted).toEqual([L1, L2, L3, L4, L5]); // ok }); test('couple movements', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const A4 = conductor.createEvent('A4'); const A5 = conductor.createEvent('A5'); const L2 = conductor.createEventHandler({ input: [A2], output: [A3], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3], output: [A4], callback: () => null }); const L4 = conductor.createEventHandler({ input: [A4], output: [A5], callback: () => null }); const L1 = conductor.createEventHandler({ input: [A1], output: [A4, A2], callback: () => null }); const L5 = conductor.createEventHandler({ input: [A5], output: [], callback: () => null }); const eventHandlers = [L2, L3, L4, L1, L5]; conductor.addManySignalProcessors(eventHandlers); const sorted = conductor.getEventHandlers(); expect(sorted).toEqual([L1, L2, L3, L4, L5]); // ok }); test('two branches', () => { const conductor = new EventConductor({ preserveOrder: true }); const Branch1 = conductor.createEvent('Branch1'); const Branch1_1 = conductor.createEvent('Branch1_1'); const Branch2 = conductor.createEvent('Branch2'); const Branch2_1 = conductor.createEvent('Branch2_1'); const L1 = conductor.createEventHandler({ input: [Branch1], output: [Branch1_1], callback: () => null }); // 2,1,4,3 const L2 = conductor.createEventHandler({ input: [Branch1_1], output: [], callback: () => null }); const L3 = conductor.createEventHandler({ input: [Branch2], output: [Branch2_1], callback: () => null }); const L4 = conductor.createEventHandler({ input: [Branch2_1], output: [], callback: () => null }); const eventHandlers = [L1, L2, L3, L4]; conductor.addManySignalProcessors(eventHandlers); const sorted = conductor.getEventHandlers(); //expect(sorted).toEqual([L3, L4, L1, L2]); // old dfs - it could be L1, L2, L3, L4 also but it doesn't matter // Kahn adds those with zero dependence first, // but it does not matter because the order of execution will be preserved // and will be in line with the order in which they were added expect(sorted).toEqual([L1, L3, L2, L4]); }); test('two branches (cyclic)', () => { const conductor = new EventConductor({ preserveOrder: true }); const Branch1 = conductor.createEvent('Branch1'); const Branch1_1 = conductor.createEvent('Branch1_1'); const Branch2 = conductor.createEvent('Branch2'); const Branch2_1 = conductor.createEvent('Branch2_1'); const L1 = conductor.createEventHandler({ input: [Branch1], output: [Branch1_1], callback: () => null }); const L2 = conductor.createEventHandler({ input: [Branch1_1], output: [], callback: () => null }); const L3 = conductor.createEventHandler({ input: [Branch1_1], output: [Branch1], callback: () => null }); // cyclic const L5 = conductor.createEventHandler({ input: [Branch2_1], output: [], callback: () => null }); const L4 = conductor.createEventHandler({ input: [Branch2], output: [Branch2_1], callback: () => null }); const eventHandlers = [L1, L2, L5, L3, L4]; expect(() => conductor.addManySignalProcessors(eventHandlers)).toThrow(); // expect(L3.getOutput()).toEqual([]); // cyclic removed // const sorted = conductor.getEventHandlers(); // //expect(sorted).toEqual([L4, L5, L1, L3, L2]); // old dfs // expect(sorted).toEqual([L1, L4, L2, L3, L5]); // ok - order doesn't matter - look at the comment in the previous test - the same situation }); test('cycle and couple of independent', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const B1 = conductor.createEvent('B1'); const X1 = conductor.createEvent('X1'); const C1 = conductor.createEvent('C1'); const L2 = conductor.createEventHandler({ input: [A2], output: [A3], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3], output: [A1], callback: () => null }); const L4 = conductor.createEventHandler({ input: [B1], output: [X1], callback: () => null }); const L1 = conductor.createEventHandler({ input: [A1], output: [A2], callback: () => null }); const L5 = conductor.createEventHandler({ input: [C1], output: [], callback: () => null }); const eventHandlers = [L2, L3, L4, L1, L5]; expect(() => conductor.addManySignalProcessors(eventHandlers)).toThrow(); // expect(L1.getOutput()).toEqual([]); // cyclic removed // const sorted = conductor.getEventHandlers(); // //expect(sorted).toEqual([L5, L4, L2, L3, L1]); // old dfs // expect(sorted).toEqual([L2, L4, L5, L3, L1]); // execution order will remain (2,3,1 | 4 | 5) }); test('cycle and couple of independent (at different loop point)', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const B1 = conductor.createEvent('B1'); const X1 = conductor.createEvent('X1'); const C1 = conductor.createEvent('C1'); const L1 = conductor.createEventHandler({ input: [A1], output: [A2], callback: () => null }); const L2 = conductor.createEventHandler({ input: [A2], output: [A1], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3], output: [], callback: () => null }); const L4 = conductor.createEventHandler({ input: [B1], output: [X1], callback: () => null }); const L5 = conductor.createEventHandler({ input: [C1], output: [], callback: () => null }); // 2,1,3,4,5 const eventHandlers = [L2, L3, L4, L1, L5]; expect(() => conductor.addManySignalProcessors(eventHandlers)).toThrow(); // expect(L1.getOutput()).toEqual([]); // cyclic removed from L1 because it was added later // const sorted = conductor.getEventHandlers(); // //expect(sorted).toEqual([L5, L4, L3, L2, L1]); // ok - it could be L1, L2, L3, L4, L5 also but it doesn't matter // expect(sorted).toEqual([L2, L3, L4, L5, L1]); // ok }); test('preserve order (cyclic)', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const A4 = conductor.createEvent('A4'); const L1 = conductor.createEventHandler({ input: [A1], output: [A4], callback: () => null }); const L2 = conductor.createEventHandler({ input: [A2], output: [A4], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3], output: [A4], callback: () => null }); const L4 = conductor.createEventHandler({ input: [A4], output: [A1], callback: () => null }); const L5 = conductor.createEventHandler({ input: [A4], output: [A1], callback: () => null }); const L6 = conductor.createEventHandler({ input: [A4], output: [A1], callback: () => null }); const eventHandlers = [L1, L2, L3, L4, L5, L6]; expect(() => conductor.addManySignalProcessors(eventHandlers)).toThrow(); // expect(L1.getOutput()).toEqual([A4]); // expect(L2.getOutput()).toEqual([A4]); // expect(L3.getOutput()).toEqual([A4]); // expect(L4.getOutput()).toEqual([]); // expect(L5.getOutput()).toEqual([]); // expect(L6.getOutput()).toEqual([]); // const sorted = conductor.getEventHandlers(); // expect(sorted).toEqual([L1, L2, L3, L4, L5, L6]); // ok }); test('preserve order 2 (cyclic)', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const A4 = conductor.createEvent('A4'); const L1 = conductor.createEventHandler({ input: [A1], output: [A4, A1], callback: () => null }); const L2 = conductor.createEventHandler({ input: [A2], output: [A4, A1], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3], output: [A4], callback: () => null }); const L4 = conductor.createEventHandler({ input: [A4], output: [A1, A2, A3, A4], callback: () => null }); const L5 = conductor.createEventHandler({ input: [A4], output: [A2], callback: () => null }); const L6 = conductor.createEventHandler({ input: [A4], output: [A3, A1], callback: () => null }); const eventHandlers = [L1, L2, L3, L4, L5, L6]; expect(() => conductor.addManySignalProcessors(eventHandlers)).toThrow(); // expect(L1.getOutput()).toEqual([A4]); // expect(L2.getOutput()).toEqual([A4]); // expect(L3.getOutput()).toEqual([A4]); // expect(L4.getOutput()).toEqual([]); // expect(L5.getOutput()).toEqual([]); // expect(L6.getOutput()).toEqual([]); // const sorted = conductor.getEventHandlers(); // expect(sorted).toEqual([L1, L2, L3, L4, L5, L6]); // ok }); test('cycle and couple of independent (with multiple loop points)', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const B1 = conductor.createEvent('B1'); const X1 = conductor.createEvent('X1'); const C1 = conductor.createEvent('C1'); const L2 = conductor.createEventHandler({ input: [A2], output: [A3, A1], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3], output: [A1], callback: () => null }); const L4 = conductor.createEventHandler({ input: [B1], output: [X1], callback: () => null }); const L1 = conductor.createEventHandler({ input: [A1], output: [A2], callback: () => null }); const L5 = conductor.createEventHandler({ input: [C1], output: [], callback: () => null }); const eventHandlers = [L2, L3, L4, L1, L5]; expect(() => conductor.addManySignalProcessors(eventHandlers)).toThrow(); // expect(L1.getOutput()).toEqual([]); // cyclic removed // const sorted = conductor.getEventHandlers(); // //expect(sorted).toEqual([L5, L4, L2, L3, L1]); // ok // expect(sorted).toEqual([L2, L4, L5, L3, L1]); // ok }); test('preserve order 3', () => { const conductor = new EventConductor({ preserveOrder: true }); const X = conductor.createEvent('X'); const A = conductor.createEvent('A'); const B = conductor.createEvent('B'); const C = conductor.createEvent('C'); const X1 = conductor.createEventHandler({ input: [X], output: [A], callback: () => null }); const X2 = conductor.createEventHandler({ input: [X], output: [B], callback: () => null }); const X3 = conductor.createEventHandler({ input: [X], output: [C], callback: () => null }); const L1 = conductor.createEventHandler({ input: [A, B], output: [], callback: () => null }); const L2 = conductor.createEventHandler({ input: [A, C], output: [], callback: () => null }); const eventHandlers = [X1, X2, X3, L1, L2]; conductor.addManySignalProcessors(eventHandlers); const sorted = conductor.getEventHandlers(); expect(sorted).toEqual([X1, X2, X3, L1, L2]); // ok }); test('preserve order 3v2', () => { const conductor = new EventConductor({ preserveOrder: true }); const X = conductor.createEvent('X'); const A = conductor.createEvent('A'); const B = conductor.createEvent('B'); const C = conductor.createEvent('C'); const X1 = conductor.createEventHandler({ input: [X], output: [A], callback: () => null }); const X2 = conductor.createEventHandler({ input: [X], output: [B], callback: () => null }); const X3 = conductor.createEventHandler({ input: [X], output: [C], callback: () => null }); const L1 = conductor.createEventHandler({ input: [B, A], output: [], callback: () => null }); const L2 = conductor.createEventHandler({ input: [C, A], output: [], callback: () => null }); const eventHandlers = [X1, X2, X3, L1, L2]; conductor.addManySignalProcessors(eventHandlers); const sorted = conductor.getEventHandlers(); expect(sorted).toEqual([X1, X2, X3, L1, L2]); // ok }); test('preserve order 3v2', () => { const conductor = new EventConductor({ preserveOrder: true }); const X = conductor.createEvent('X'); const A = conductor.createEvent('A'); const B = conductor.createEvent('B'); const C = conductor.createEvent('C'); const X1 = conductor.createEventHandler({ input: [X], output: [A], callback: () => null }); const X2 = conductor.createEventHandler({ input: [X], output: [B], callback: () => null }); const X3 = conductor.createEventHandler({ input: [X], output: [C], callback: () => null }); const L1 = conductor.createEventHandler({ input: [B, A], output: [], callback: () => null }); const L2 = conductor.createEventHandler({ input: [A, C], output: [], callback: () => null }); const eventHandlers = [X1, X2, X3, L1, L2]; conductor.addManySignalProcessors(eventHandlers); const sorted = conductor.getEventHandlers(); expect(sorted).toEqual([X1, X2, X3, L1, L2]); // ok }); test('preserve order 3v3', () => { const conductor = new EventConductor({ preserveOrder: true }); const X = conductor.createEvent('X'); const A = conductor.createEvent('A'); const B = conductor.createEvent('B'); const C = conductor.createEvent('C'); const X1 = conductor.createEventHandler({ input: [X], output: [A], callback: () => null }); const X2 = conductor.createEventHandler({ input: [X], output: [B], callback: () => null }); const X3 = conductor.createEventHandler({ input: [X], output: [C], callback: () => null }); const L1 = conductor.createEventHandler({ input: [A, B], output: [], callback: () => null }); const L2 = conductor.createEventHandler({ input: [C, A], output: [], callback: () => null }); const eventHandlers = [X1, X2, X3, L1, L2]; conductor.addManySignalProcessors(eventHandlers); const sorted = conductor.getEventHandlers(); expect(sorted).toEqual([X1, X2, X3, L1, L2]); // ok }); test('preserve order 3v5', () => { const conductor = new EventConductor({ preserveOrder: true }); const X = conductor.createEvent('X'); const Y = conductor.createEvent('Y'); const A = conductor.createEvent('A'); const B = conductor.createEvent('B'); const C = conductor.createEvent('C'); const X1 = conductor.createEventHandler({ input: [X], output: [A, C, B], callback: () => null }); const X2 = conductor.createEventHandler({ input: [X], output: [B, A, C], callback: () => null }); const X3 = conductor.createEventHandler({ input: [X], output: [Y, C, A, B], callback: () => null }); // must be sorted to CBAY due to the order of listeners and this order is crucial for kahn sorting const L1 = conductor.createEventHandler({ input: [C, B], output: [], callback: () => null }); const L2 = conductor.createEventHandler({ input: [C, A], output: [], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A, B], output: [], callback: () => null }); const L4 = conductor.createEventHandler({ input: [A, C], output: [], callback: () => null }); const L5 = conductor.createEventHandler({ input: [Y], output: [], callback: () => null }); const eventHandlers = [X1, X2, X3, L1, L2, L3, L4, L5]; conductor.addManySignalProcessors(eventHandlers); const sorted = conductor.getEventHandlers(); expect(X3.getInput()).toEqual([C, B, A, Y]); expect(sorted).toEqual([X1, X2, X3, L1, L2, L3, L4, L5]); // ok }); test('preserve order 3v6', () => { const conductor = new EventConductor({ preserveOrder: true }); const X = conductor.createEvent('X'); const Y = conductor.createEvent('Y'); const A = conductor.createEvent('A'); const B = conductor.createEvent('B'); const C = conductor.createEvent('C'); const X1 = conductor.createEventHandler({ input: [X], output: [A, C, B], callback: () => null }); const X2 = conductor.createEventHandler({ input: [X], output: [Y, C, A, B], callback: () => null }); // must be sorted to CBAY due to the order of listeners and this order is crucial for kahn sorting const X3 = conductor.createEventHandler({ input: [X], output: [B, A, C], callback: () => null }); const L1 = conductor.createEventHandler({ input: [C, B], output: [], callback: () => null }); const L2 = conductor.createEventHandler({ input: [C, A], output: [], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A, B], output: [], callback: () => null }); const L4 = conductor.createEventHandler({ input: [A, C], output: [], callback: () => null }); const YL = conductor.createEventHandler({ input: [Y], output: [], callback: () => null }); const eventHandlers = [X1, X2, X3, L1, L2, L3, L4, YL]; conductor.addManySignalProcessors(eventHandlers); const sorted = conductor.getEventHandlers(); expect(X2.getInput()).toEqual([C, B, A, Y]); expect(sorted).toEqual([X1, X2, X3, YL, L1, L2, L3, L4]); // ok }); test('preserve order 3v7', () => { const conductor = new EventConductor({ preserveOrder: true }); const X = conductor.createEvent('X'); const Y = conductor.createEvent('Y'); const A = conductor.createEvent('A'); const B = conductor.createEvent('B'); const C = conductor.createEvent('C'); const X1 = conductor.createEventHandler({ input: [X], output: [A, C, B], callback: () => null }); const X2 = conductor.createEventHandler({ input: [X], output: [Y, C, A, B], callback: () => null }); // must be sorted to CBAY due to the order of listeners and this order is crucial for kahn sorting const X3 = conductor.createEventHandler({ input: [X], output: [B, A, C], callback: () => null }); const L1 = conductor.createEventHandler({ input: [C, B], output: [], callback: () => null }); const L2 = conductor.createEventHandler({ input: [C, A], output: [Y], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A, B], output: [], callback: () => null }); const L4 = conductor.createEventHandler({ input: [A, C], output: [], callback: () => null }); const YL = conductor.createEventHandler({ input: [Y], output: [], callback: () => null }); const eventHandlers = [X1, X2, X3, L1, L2, L3, L4, YL]; conductor.addManySignalProcessors(eventHandlers); const sorted = conductor.getEventHandlers(); expect(X2.getInput()).toEqual([C, B, A, Y]); expect(sorted).toEqual([X1, X2, X3, L1, L2, L3, L4, YL]); // ok }); test('two loops with one without emit (cyclic)', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const A4 = conductor.createEvent('A4'); const A5 = conductor.createEvent('A5'); const B1 = conductor.createEvent('B1'); const B2 = conductor.createEvent('B2'); const B3 = conductor.createEvent('B3'); const B4 = conductor.createEvent('B4'); const B5 = conductor.createEvent('B5'); const LA2 = conductor.createEventHandler({ input: [A2], output: [A3], callback: () => null }); const LA3 = conductor.createEventHandler({ input: [A3], output: [A4], callback: () => null }); const LA5 = conductor.createEventHandler({ input: [A5], output: [], callback: () => null }); // dfs comment 5,1,4,3,2 | 1,5,4,3,2 const LA4 = conductor.createEventHandler({ input: [A4], output: [A5, A1], callback: () => null }); const LA1 = conductor.createEventHandler({ input: [A1], output: [A2], callback: () => null }); const LB2 = conductor.createEventHandler({ input: [B2], output: [B3], callback: () => null }); const LB3 = conductor.createEventHandler({ input: [B3], output: [B4], callback: () => null }); const LB5 = conductor.createEventHandler({ input: [B5], output: [B1], callback: () => null }); const LB4 = conductor.createEventHandler({ input: [B4], output: [B5], callback: () => null }); const LB1 = conductor.createEventHandler({ input: [B1], output: [B2], callback: () => null }); const eventHandlers = [LA2, LA3, LA5, LA4, LA1, LB2, LB3, LB5, LB4, LB1]; expect(() => conductor.addManySignalProcessors(eventHandlers)).toThrow(); // const sorted = conductor.getEventHandlers(); // // expect(sorted).toEqual([LB2, LB3, LB4, LB5, LB1, LA2, LA3, LA4, LA1, LA5]); old dfs // expect(sorted).toEqual([LA2, LB2, LA3, LB3, LA4, LB4, LA5, LA1, LB5, LB1]); }); test('two branches (one looped) with one without emit (cyclic)', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const A4 = conductor.createEvent('A4'); const A5 = conductor.createEvent('A5'); const B1 = conductor.createEvent('B1'); const B2 = conductor.createEvent('B2'); const B3 = conductor.createEvent('B3'); const B4 = conductor.createEvent('B4'); const B5 = conductor.createEvent('B5'); const LA2 = conductor.createEventHandler({ input: [A2], output: [A3], callback: () => null }); const LA3 = conductor.createEventHandler({ input: [A3], output: [A4], callback: () => null }); const LA4 = conductor.createEventHandler({ input: [A4], output: [A5, A1], callback: () => null }); const LA5 = conductor.createEventHandler({ input: [A5], output: [], callback: () => null }); const LA1 = conductor.createEventHandler({ input: [A1], output: [A2], callback: () => null }); const LB1 = conductor.createEventHandler({ input: [B1], output: [B2], callback: () => null }); const LB2 = conductor.createEventHandler({ input: [B2], output: [B3], callback: () => null }); const LB3 = conductor.createEventHandler({ input: [B3], output: [B4], callback: () => null }); const LB4 = conductor.createEventHandler({ input: [B4], output: [B5], callback: () => null }); const LB5 = conductor.createEventHandler({ input: [B5], output: [], callback: () => null }); const eventHandlers = [LA2, LA3, LA5, LA4, LA1, LB2, LB3, LB5, LB4, LB1]; expect(() => conductor.addManySignalProcessors(eventHandlers)).toThrow(); // const sorted = conductor.getEventHandlers(); // //expect(sorted).toEqual([LB1, LB2, LB3, LB4, LB5, LA2, LA3, LA4, LA1, LA5]); // ok // expect(sorted).toEqual([LA2, LB1, LA3, LB2, LA4, LB3, LA5, LA1, LB4, LB5]); // ok }); test('cycled eventHandler calls a eventHandler from another branch', () => { const conductor = new EventConductor({ preserveOrder: true }); const A1 = conductor.createEvent('A1'); const A2 = conductor.createEvent('A2'); const A3 = conductor.createEvent('A3'); const B1 = conductor.createEvent('B1'); const B2 = conductor.createEvent('B2'); const B3 = conductor.createEvent('B3'); const L2 = conductor.createEventHandler({ input: [A2], output: [A3], callback: () => null }); const L3 = conductor.createEventHandler({ input: [A3], output: [], callback: () => null }); const L4 = conductor.createEventHandler({ input: [B1], output: [B2], callback: () => null }); const L1 = conductor.createEventHandler({ input: [A1], output: [A2], callback: () => null }); // 3,2,6,5,4,1 const L5 = conductor.createEventHandler({ input: [B2], output: [B3, A2], callback: () => null }); // A2 B3 sorted const L6 = conductor.createEventHandler({ input: [B3], output: [B1], callback: () => null }); const eventHandlers = [L2, L3, L4, L1, L5, L6]; expect(() => conductor.addManySignalProcessors(eventHandlers)).toThrow(); // const sorted = conductor.getEventHandlers(); // expect(sorted).toEqual([L4, L1, L5, L2, L6, L3]); // ok }); });