Skip to content

Commit

Permalink
With this commit we can test all instances of Element in a parametriz…
Browse files Browse the repository at this point in the history
…ed way, in this way we can run the same test for Resistor, Capacitor, Junction, Wire, etc. Not having to rewrite the same.
  • Loading branch information
jurra committed Jan 9, 2025
1 parent 523d243 commit 2ad579d
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 80 deletions.
139 changes: 60 additions & 79 deletions tests/domain/Element.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { expect } from 'chai';
import { Element } from '../../src/domain/entities/Element.js';
import { MockElement } from './MockElement.js'; // A mock element class for testing
import { Position } from '../../src/domain/valueObjects/Position.js';
import { Label } from '../../src/domain/valueObjects/Label.js';
import { Properties } from '../../src/domain/valueObjects/Properties.js';
Expand All @@ -10,93 +11,73 @@ describe('Basic Import Test', () => {
expect(Element).to.be.a('function');
});
});
/**
* MockElement class extends the Element class for testing purposes.
*/
class MockElement extends Element {
constructor(id, terminals = [], label = null, properties = new Properties()) {
super(id, terminals, label, properties);
this.type = 'mock';
}
}

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

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

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

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

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

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

it('Properties should accept a float, a "variable" string, or "undefined"', () => {
// Valid cases
const validProperties1 = new Properties({ resistance: 100, capacitance: "variable", inductance: "undefined" });
expect(validProperties1.values.resistance).to.equal(100);
expect(validProperties1.values.capacitance).to.equal("variable");
expect(validProperties1.values.inductance).to.equal("undefined");

// Invalid cases
expect(() => new Properties({ resistance: true })).to.throw(
'Invalid value for property "resistance". Must be a float, "variable", or "undefined".'
);
expect(() => new Properties({ capacitance: null })).to.throw(
'Invalid value for property "capacitance". Must be a float, "variable", or "undefined".'
);
expect(() => new Properties({ inductance: {} })).to.throw(
'Invalid value for property "inductance". Must be a float, "variable", or "undefined".'
);
});


it('An element should throw an error if properties are invalid', () => {
expect(() => new MockElement('E7', [new Position(10, 20)], null, { invalid: 'properties' })).to.throw(
"Properties must be an instance of Properties."
);
});
it(`A ${type.toLowerCase()} should throw an error if properties are invalid`, () => {
expect(() => new ElementClass('E7', [new Position(10, 20), new Position(30, 40)], null, { invalid: 'properties' })).to.throw(
"Properties must be an instance of Properties."
);
});

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

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

const description = element.describe();
expect(description).to.equal(
'mock (E9): terminals: [(10, 20), (30, 40)], label: "Test Label", properties: resistance: 100'
);
});
});
const description = element.describe();
expect(description).to.include(`${type.toLowerCase()} (E8): terminals:`);
expect(description).to.include(`label: "${type} Label"`);
expect(description).to.include(`properties:`);
});
});
};

// Tests for MockElement
testElementSubclass('MockElement', MockElement, { mockProperty: 42 });
});
2 changes: 1 addition & 1 deletion tests/domain/MockElement.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ export class MockElement extends Element {
*/
constructor(id, terminals = [], label = null, properties = new Properties()) {
super(id, terminals, label, properties);
this.type = 'mock';
this.type = 'mockelement';
}
}
16 changes: 16 additions & 0 deletions tests/domain/Properties.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { expect } from 'chai';
import { Properties } from '../../src/domain/valueObjects/Properties.js';

describe('Properties Class Tests', () => {
it('should describe properties correctly', () => {
const properties = new Properties({ resistance: 100, capacitance: "variable" });
const description = properties.describe();
expect(description).to.equal("resistance: 100, capacitance: variable");
});

it('should handle empty properties correctly', () => {
const properties = new Properties({});
const description = properties.describe();
expect(description).to.equal("");
});
});

0 comments on commit 2ad579d

Please sign in to comment.