Files
OpenNoodl/packages/noodl-editor/tests/components/componentconnections.js
Michael Cartner b9c60b07dc 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>
2024-01-26 11:52:55 +01:00

373 lines
9.7 KiB
JavaScript

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');
});
});