Skip to content

Commit 4e49d6b

Browse files
committed
With this commit we can test all instances of Element in a parametrized way, in this way we can run the same test for Resistor, Capacitor, Junction, Wire, etc. Not having to rewrite the same.
1 parent 523d243 commit 4e49d6b

File tree

1 file changed

+60
-79
lines changed

1 file changed

+60
-79
lines changed

tests/domain/Element.test.js

+60-79
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { expect } from 'chai';
22
import { Element } from '../../src/domain/entities/Element.js';
3+
import { MockElement } from './MockElement.js'; // A mock element class for testing
34
import { Position } from '../../src/domain/valueObjects/Position.js';
45
import { Label } from '../../src/domain/valueObjects/Label.js';
56
import { Properties } from '../../src/domain/valueObjects/Properties.js';
@@ -10,93 +11,73 @@ describe('Basic Import Test', () => {
1011
expect(Element).to.be.a('function');
1112
});
1213
});
13-
/**
14-
* MockElement class extends the Element class for testing purposes.
15-
*/
16-
class MockElement extends Element {
17-
constructor(id, terminals = [], label = null, properties = new Properties()) {
18-
super(id, terminals, label, properties);
19-
this.type = 'mock';
20-
}
21-
}
2214

2315
describe('Element Class Tests', () => {
24-
it('An element should have a unique identifier', () => {
25-
const element = new MockElement('E1', [new Position(10, 20)], null, new Properties());
26-
expect(element.id).to.equal('E1');
27-
});
16+
/**
17+
* Parameterized test function to validate Element subclasses.
18+
*
19+
* @param {string} type - The type of the Element subclass (e.g., 'Resistor', 'Wire', 'MockElement').
20+
* @param {Function} ElementClass - The Element subclass to test.
21+
* @param {Object} defaultProperties - Default properties for the Element subclass.
22+
*/
23+
const testElementSubclass = (type, ElementClass, defaultProperties) => {
24+
describe(`${type} Tests`, () => {
25+
it(`A ${type.toLowerCase()} should have a unique identifier`, () => {
26+
const element = new ElementClass('E1', [new Position(10, 20), new Position(30, 40)], null, new Properties(defaultProperties));
27+
expect(element.id).to.equal('E1');
28+
});
2829

29-
it('An element should validate terminals as an array of Position instances', () => {
30-
const terminals = [new Position(10, 20), new Position(30, 40)];
31-
const element = new MockElement('E2', terminals, null, new Properties());
32-
expect(element.terminals).to.deep.equal(terminals);
33-
});
30+
it(`A ${type.toLowerCase()} should validate terminals as an array of Position instances`, () => {
31+
const terminals = [new Position(10, 20), new Position(30, 40)];
32+
const element = new ElementClass('E2', terminals, null, new Properties(defaultProperties));
33+
expect(element.terminals).to.deep.equal(terminals);
34+
});
3435

35-
it('An element should throw an error if terminals are invalid', () => {
36-
expect(() => new MockElement('E3', [10, 20], null, new Properties())).to.throw(
37-
"Terminals must be an array of Position instances."
38-
);
39-
});
36+
it(`A ${type.toLowerCase()} should throw an error if terminals are invalid`, () => {
37+
expect(() => new ElementClass('E3', [10, 20], null, new Properties(defaultProperties))).to.throw(
38+
"Terminals must be an array of Position instances."
39+
);
40+
});
4041

41-
it('An element should accept a label of type Label or null', () => {
42-
const label = new Label('Test Label');
43-
const element = new MockElement('E4', [new Position(10, 20)], label, new Properties());
44-
expect(element.label).to.equal(label);
45-
});
42+
it(`A ${type.toLowerCase()} should accept a label of type Label or null`, () => {
43+
const label = new Label(`${type} Label`);
44+
const element = new ElementClass('E4', [new Position(10, 20), new Position(30, 40)], label, new Properties(defaultProperties));
45+
expect(element.label).to.equal(label);
46+
});
4647

47-
it('An element should throw an error if label is invalid', () => {
48-
expect(() => new MockElement('E5', [new Position(10, 20)], 'Invalid Label', new Properties())).to.throw(
49-
"Label must be an instance of Label or null."
50-
);
51-
});
48+
it(`A ${type.toLowerCase()} should throw an error if label is invalid`, () => {
49+
expect(() => new ElementClass('E5', [new Position(10, 20), new Position(30, 40)], 'Invalid Label', new Properties(defaultProperties))).to.throw(
50+
"Label must be an instance of Label or null."
51+
);
52+
});
5253

53-
it('An element should accept properties of type Properties', () => {
54-
const properties = new Properties({ resistance: 100 });
55-
const element = new MockElement('E6', [new Position(10, 20)], null, properties);
56-
expect(element.properties).to.equal(properties);
57-
});
54+
it(`A ${type.toLowerCase()} should accept properties of type Properties`, () => {
55+
const properties = new Properties(defaultProperties);
56+
const element = new ElementClass('E6', [new Position(10, 20), new Position(30, 40)], null, properties);
57+
expect(element.properties).to.equal(properties);
58+
});
5859

59-
it('Properties should accept a float, a "variable" string, or "undefined"', () => {
60-
// Valid cases
61-
const validProperties1 = new Properties({ resistance: 100, capacitance: "variable", inductance: "undefined" });
62-
expect(validProperties1.values.resistance).to.equal(100);
63-
expect(validProperties1.values.capacitance).to.equal("variable");
64-
expect(validProperties1.values.inductance).to.equal("undefined");
65-
66-
// Invalid cases
67-
expect(() => new Properties({ resistance: true })).to.throw(
68-
'Invalid value for property "resistance". Must be a float, "variable", or "undefined".'
69-
);
70-
expect(() => new Properties({ capacitance: null })).to.throw(
71-
'Invalid value for property "capacitance". Must be a float, "variable", or "undefined".'
72-
);
73-
expect(() => new Properties({ inductance: {} })).to.throw(
74-
'Invalid value for property "inductance". Must be a float, "variable", or "undefined".'
75-
);
76-
});
77-
78-
79-
it('An element should throw an error if properties are invalid', () => {
80-
expect(() => new MockElement('E7', [new Position(10, 20)], null, { invalid: 'properties' })).to.throw(
81-
"Properties must be an instance of Properties."
82-
);
83-
});
60+
it(`A ${type.toLowerCase()} should throw an error if properties are invalid`, () => {
61+
expect(() => new ElementClass('E7', [new Position(10, 20), new Position(30, 40)], null, { invalid: 'properties' })).to.throw(
62+
"Properties must be an instance of Properties."
63+
);
64+
});
8465

85-
it('An element should be abstract and not directly instantiable', () => {
86-
expect(() => new Element('E8', [new Position(10, 20)], null, new Properties())).to.throw(
87-
"Cannot instantiate abstract class Element directly."
88-
);
89-
});
66+
it(`A ${type.toLowerCase()} should support the describe method`, () => {
67+
const terminals = [new Position(10, 20), new Position(30, 40)];
68+
const label = new Label(`${type} Label`);
69+
const properties = new Properties(defaultProperties);
9070

91-
it('An element should support the describe method', () => {
92-
const terminals = [new Position(10, 20), new Position(30, 40)];
93-
const label = new Label('Test Label');
94-
const properties = new Properties({ resistance: 100 });
95-
const element = new MockElement('E9', terminals, label, properties);
71+
const element = new ElementClass('E8', terminals, label, properties);
9672

97-
const description = element.describe();
98-
expect(description).to.equal(
99-
'mock (E9): terminals: [(10, 20), (30, 40)], label: "Test Label", properties: resistance: 100'
100-
);
101-
});
102-
});
73+
const description = element.describe();
74+
expect(description).to.include(`${type.toLowerCase()} (E8): terminals:`);
75+
expect(description).to.include(`label: "${type} Label"`);
76+
expect(description).to.include(`properties:`);
77+
});
78+
});
79+
};
80+
81+
// Tests for MockElement
82+
testElementSubclass('MockElement', MockElement, { mockProperty: 42 });
83+
});

0 commit comments

Comments
 (0)