mirror of
https://github.com/The-Low-Code-Foundation/OpenNoodl.git
synced 2026-01-11 23:02:56 +01:00
Initial commit
Co-Authored-By: Eric Tuvesson <eric.tuvesson@gmail.com> Co-Authored-By: mikaeltellhed <2311083+mikaeltellhed@users.noreply.github.com> Co-Authored-By: kotte <14197736+mrtamagotchi@users.noreply.github.com> Co-Authored-By: Anders Larsson <64838990+anders-topp@users.noreply.github.com> Co-Authored-By: Johan <4934465+joolsus@users.noreply.github.com> Co-Authored-By: Tore Knudsen <18231882+torekndsn@users.noreply.github.com> Co-Authored-By: victoratndl <99176179+victoratndl@users.noreply.github.com>
This commit is contained in:
372
packages/noodl-editor/tests/components/componentconnections.js
Normal file
372
packages/noodl-editor/tests/components/componentconnections.js
Normal file
@@ -0,0 +1,372 @@
|
||||
const NodeGraphModel = require('@noodl-models/nodegraphmodel').NodeGraphModel;
|
||||
const NodeGraphNode = require('@noodl-models/nodegraphmodel').NodeGraphNode;
|
||||
const { ComponentModel } = require('@noodl-models/componentmodel');
|
||||
const NodeLibrary = require('@noodl-models/nodelibrary').NodeLibrary;
|
||||
const { ProjectModel } = require('@noodl-models/projectmodel');
|
||||
|
||||
describe('Connecting component inputs and outputs', function () {
|
||||
var g1, c1;
|
||||
var ci, co, n1, n2, co2;
|
||||
var p;
|
||||
var con1, con2;
|
||||
|
||||
beforeEach(() => {
|
||||
window.NodeLibraryData = require('../nodegraph/nodelibrary');
|
||||
NodeLibrary.instance.loadLibrary();
|
||||
|
||||
g1 = new NodeGraphModel();
|
||||
|
||||
c1 = new ComponentModel({
|
||||
name: 'c1',
|
||||
graph: g1
|
||||
});
|
||||
|
||||
ci = NodeGraphNode.fromJSON({
|
||||
type: 'Component Inputs',
|
||||
id: 'A'
|
||||
});
|
||||
g1.addRoot(ci);
|
||||
|
||||
co = NodeGraphNode.fromJSON({
|
||||
type: 'Component Outputs',
|
||||
id: 'B'
|
||||
});
|
||||
g1.addRoot(co);
|
||||
|
||||
co2 = NodeGraphNode.fromJSON({
|
||||
type: 'Component Outputs',
|
||||
id: 'B2'
|
||||
});
|
||||
g1.addRoot(co2);
|
||||
|
||||
n1 = NodeGraphNode.fromJSON({
|
||||
type: 'group',
|
||||
id: 'C'
|
||||
});
|
||||
g1.addRoot(n1);
|
||||
|
||||
n2 = NodeGraphNode.fromJSON({
|
||||
type: 'group',
|
||||
id: 'D'
|
||||
});
|
||||
g1.addRoot(n2);
|
||||
|
||||
p = new ProjectModel({
|
||||
name: 'test'
|
||||
});
|
||||
p.addComponent(c1);
|
||||
|
||||
NodeLibrary.instance.registerModule(p);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
NodeLibrary.instance.unregisterModule(p);
|
||||
});
|
||||
|
||||
function addPorts() {
|
||||
c1.graph.findNodeWithId('B').addPort({
|
||||
name: 'p1',
|
||||
plug: 'input',
|
||||
type: '*',
|
||||
index: 0
|
||||
});
|
||||
|
||||
c1.graph.findNodeWithId('B').addPort({
|
||||
name: 'p2',
|
||||
plug: 'input',
|
||||
type: '*',
|
||||
index: 1
|
||||
});
|
||||
|
||||
c1.graph.findNodeWithId('A').addPort({
|
||||
name: 'p3',
|
||||
plug: 'output',
|
||||
type: '*',
|
||||
index: 2
|
||||
});
|
||||
|
||||
c1.graph.findNodeWithId('B2').addPort({
|
||||
name: 'p1',
|
||||
plug: 'input',
|
||||
type: '*',
|
||||
index: 0
|
||||
});
|
||||
}
|
||||
|
||||
function addConnections() {
|
||||
con1 = {
|
||||
fromId: n1.id,
|
||||
fromProperty: 'width',
|
||||
toId: co.id,
|
||||
toProperty: 'p1'
|
||||
};
|
||||
g1.addConnection(con1);
|
||||
|
||||
con2 = {
|
||||
fromId: ci.id,
|
||||
fromProperty: 'p3',
|
||||
toId: n1.id,
|
||||
toProperty: 'x'
|
||||
};
|
||||
g1.addConnection(con2);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------
|
||||
it('can add input ports to the component', function () {
|
||||
addPorts();
|
||||
|
||||
var ports = c1.getPorts();
|
||||
expect(ports.length).toBe(3);
|
||||
expect(ports[0].name).toBe('p1');
|
||||
expect(ports[0].plug).toBe('output');
|
||||
expect(ports[0].type).toBe('*');
|
||||
expect(ports[1].name).toBe('p2');
|
||||
expect(ports[1].plug).toBe('output');
|
||||
expect(ports[1].type).toBe('*');
|
||||
expect(ports[2].name).toBe('p3');
|
||||
expect(ports[2].plug).toBe('input');
|
||||
expect(ports[2].type).toBe('*');
|
||||
});
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------
|
||||
it('can list ports correctly for component input/outputs', function () {
|
||||
addPorts();
|
||||
|
||||
var ports = c1.graph.findNodeWithId('B').getPorts('input');
|
||||
|
||||
expect(ports[0].name).toBe('p1');
|
||||
expect(ports[1].name).toBe('p2');
|
||||
expect(ports[0].plug).toBe('input');
|
||||
expect(ports[1].plug).toBe('input');
|
||||
expect(ports[0].type).toBe('*');
|
||||
expect(ports[1].type).toBe('*');
|
||||
expect(ports.length).toBe(2);
|
||||
|
||||
var ports = c1.graph.findNodeWithId('A').getPorts('output');
|
||||
expect(ports[0].name).toBe('p3');
|
||||
expect(ports[0].plug).toBe('output');
|
||||
expect(ports[0].type).toBe('*');
|
||||
expect(ports.length).toBe(1);
|
||||
});
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------
|
||||
it('reports connection status properly', function () {
|
||||
addPorts();
|
||||
|
||||
// component input
|
||||
var status = g1.getConnectionStatus({
|
||||
sourceNode: ci,
|
||||
sourcePort: 'p1',
|
||||
targetNode: n1,
|
||||
targetPort: 'width'
|
||||
});
|
||||
expect(status.connectable).toBe(true);
|
||||
|
||||
// number to number
|
||||
var status = g1.getConnectionStatus({
|
||||
sourceNode: n1,
|
||||
sourcePort: 'screenX',
|
||||
targetNode: n2,
|
||||
targetPort: 'width'
|
||||
});
|
||||
expect(status.connectable).toBe(true);
|
||||
|
||||
// component outputs
|
||||
var status = g1.getConnectionStatus({
|
||||
sourceNode: n1,
|
||||
sourcePort: 'width',
|
||||
targetNode: co,
|
||||
targetPort: 'p1'
|
||||
});
|
||||
expect(status.connectable).toBe(true);
|
||||
});
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------
|
||||
it('can rename ports', function () {
|
||||
addPorts();
|
||||
addConnections();
|
||||
|
||||
expect(c1.graph.findNodeWithId('B').renamePortWithName('p1', 'p2')).toBe(false);
|
||||
expect(c1.graph.findNodeWithId('B').renamePortWithName('p1', 'p1b')).toBe(true);
|
||||
expect(c1.graph.findNodeWithId('A').renamePortWithName('p3', 'p3b')).toBe(true);
|
||||
|
||||
expect(con2.fromProperty).toBe('p3b');
|
||||
expect(con1.toProperty).toBe('p1b');
|
||||
|
||||
expect(c1.graph.findNodeWithId('B').renamePortWithName('p1b', 'p1')).toBe(true);
|
||||
expect(c1.graph.findNodeWithId('A').renamePortWithName('p3b', 'p3')).toBe(true);
|
||||
});
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------
|
||||
it('cannot remove ports with connections', function () {
|
||||
addPorts();
|
||||
addConnections();
|
||||
|
||||
expect(c1.graph.findNodeWithId('B').removePortWithName('p1')).toBe(false);
|
||||
expect(c1.graph.findNodeWithId('B').removePortWithName('p2')).toBe(true);
|
||||
expect(c1.graph.findNodeWithId('A').removePortWithName('p3')).toBe(false);
|
||||
|
||||
expect(c1.findPortWithName('p2')).toBe(undefined);
|
||||
expect(c1.findPortWithName('p1').name).toBe('p1');
|
||||
});
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------
|
||||
it('can add more connections are report type correctly', function () {
|
||||
addPorts();
|
||||
addConnections();
|
||||
|
||||
g1.removeConnection(con1);
|
||||
g1.removeConnection(con2);
|
||||
|
||||
// Single type, should just be number
|
||||
g1.addConnection({
|
||||
fromId: n1.id,
|
||||
fromProperty: 'screenX',
|
||||
toId: co2.id,
|
||||
toProperty: 'p1'
|
||||
});
|
||||
|
||||
expect(NodeLibrary.nameForPortType(c1.findPortWithName('p1').type)).toBe('number');
|
||||
|
||||
// Connect a number and boolean to the components outputs, but on different
|
||||
// nodes
|
||||
g1.addConnection({
|
||||
fromId: n1.id,
|
||||
fromProperty: 'clipOut',
|
||||
toId: co.id,
|
||||
toProperty: 'p1'
|
||||
});
|
||||
|
||||
// Resulting type should be boolean (the only type that can be converted to from both boolean and number)
|
||||
expect(NodeLibrary.nameForPortType(c1.findPortWithName('p1').type)).toBe('boolean');
|
||||
|
||||
// Adding a connection to a star type should not affect the resulting type
|
||||
g1.addConnection({
|
||||
fromId: ci.id,
|
||||
fromProperty: 'p3',
|
||||
toId: co2.id,
|
||||
toProperty: 'p1'
|
||||
});
|
||||
|
||||
expect(NodeLibrary.nameForPortType(c1.findPortWithName('p1').type)).toBe('boolean');
|
||||
|
||||
// Adding a reference type connection will cause it to break down, no type can be found
|
||||
g1.addConnection({
|
||||
fromId: n1.id,
|
||||
fromProperty: 'this',
|
||||
toId: co2.id,
|
||||
toProperty: 'p1'
|
||||
});
|
||||
|
||||
expect(c1.findPortWithName('p1').type).toBe('*');
|
||||
});
|
||||
|
||||
it('can report plug correctly', function () {
|
||||
addPorts();
|
||||
|
||||
expect(c1.findPortWithName('p1').plug).toBe('output');
|
||||
expect(c1.findPortWithName('p3').plug).toBe('input');
|
||||
|
||||
// Adding an extra port of mixed type for p1 should change the plug
|
||||
c1.graph.findNodeWithId('A').addPort({
|
||||
name: 'p1',
|
||||
plug: 'output',
|
||||
type: '*'
|
||||
});
|
||||
|
||||
expect(c1.getPorts().length).toBe(4);
|
||||
expect(c1.getPorts()).toContain({
|
||||
name: 'p1',
|
||||
type: '*',
|
||||
default: undefined,
|
||||
group: undefined,
|
||||
plug: 'output',
|
||||
index: 0
|
||||
});
|
||||
expect(c1.getPorts()).toContain({
|
||||
name: 'p1',
|
||||
type: '*',
|
||||
default: undefined,
|
||||
group: undefined,
|
||||
plug: 'input',
|
||||
index: 1
|
||||
});
|
||||
});
|
||||
|
||||
it('can ignore * types', function () {
|
||||
addPorts();
|
||||
addConnections();
|
||||
|
||||
// Remove all connections
|
||||
while (g1.connections.length > 0) {
|
||||
g1.removeConnection(g1.connections[0]);
|
||||
}
|
||||
|
||||
// Number type
|
||||
g1.addConnection({
|
||||
fromId: n1.id,
|
||||
fromProperty: 'screenX',
|
||||
toId: co.id,
|
||||
toProperty: 'p1'
|
||||
});
|
||||
|
||||
expect(c1.findPortWithName('p1').type).toBe('number');
|
||||
|
||||
// Add a connection to a * type
|
||||
g1.addConnection({
|
||||
fromId: ci.id,
|
||||
fromProperty: 'p3',
|
||||
toId: co.id,
|
||||
toProperty: 'p1'
|
||||
});
|
||||
|
||||
// Should just ignore * type and still be number
|
||||
expect(c1.findPortWithName('p1').type).toBe('number');
|
||||
});
|
||||
|
||||
it('can support units with default in types', function () {
|
||||
addPorts();
|
||||
addConnections();
|
||||
|
||||
// Remove all connections
|
||||
while (g1.connections.length > 0) {
|
||||
g1.removeConnection(g1.connections[0]);
|
||||
}
|
||||
|
||||
// Add a connection to a type with units
|
||||
g1.addConnection({
|
||||
fromId: ci.id,
|
||||
fromProperty: 'p3',
|
||||
toId: n1.id,
|
||||
toProperty: 'x'
|
||||
});
|
||||
|
||||
// Should just ignore * type and still be number
|
||||
expect(c1.findPortWithName('p3').type.name).toBe('number');
|
||||
expect(c1.findPortWithName('p3').type.units).toEqual(['px', '%']);
|
||||
expect(c1.findPortWithName('p3').default).toEqual({
|
||||
value: 10,
|
||||
unit: '%'
|
||||
});
|
||||
|
||||
expect(c1.findPortWithName('p3').group).toBe('test'); // Should inherit from connected port
|
||||
|
||||
//Change parameter value should propagate to default
|
||||
n1.setParameter('x', {
|
||||
value: 50,
|
||||
unit: 'px'
|
||||
});
|
||||
expect(c1.findPortWithName('p3').default).toEqual({
|
||||
value: 50,
|
||||
unit: 'px'
|
||||
});
|
||||
});
|
||||
|
||||
it('can rearrange ports', function () {
|
||||
addPorts();
|
||||
addConnections();
|
||||
|
||||
ci.arrangePort('p3', undefined, 'G1');
|
||||
expect(c1.findPortWithName('p3').group).toBe('G1');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user