diff --git a/src/application/ElementService.js b/src/application/ElementService.js index 995fb03..456dfa1 100644 --- a/src/application/ElementService.js +++ b/src/application/ElementService.js @@ -88,4 +88,20 @@ export class ElementService { const newY = Math.round(x * sin + y * cos); return [newX, newY]; } + + /** + * Updates properties of an element. + * + * @param {Element} element - The element whose properties are being updated. + * @param {Object} updates - An object containing property updates. + * @throws {Error} If any property value is invalid. + */ + static updateProperties(element, updates) { + Object.entries(updates).forEach(([key, value]) => { + if (!element.properties.isValidValue(value)) { + throw new Error(`Invalid value for property "${key}". Must be a float, "variable", or "undefined".`); + } + element.properties.values[key] = value; + }); + } } diff --git a/src/domain/valueObjects/Properties.js b/src/domain/valueObjects/Properties.js index 5f367f5..830e656 100644 --- a/src/domain/valueObjects/Properties.js +++ b/src/domain/valueObjects/Properties.js @@ -6,13 +6,45 @@ export class Properties { * Creates a properties container. * * @param {Object} values - An object containing the value objects for the properties. + * @throws {Error} If any value is invalid. */ constructor(values = {}) { - if (typeof values !== 'object') { - throw new Error("Properties must be an object."); + if (typeof values !== 'object' || values === null) { + throw new Error("Properties must be a non-null object."); } - this.values = values; // Store value objects (e.g., Resistance, Capacitance) + // Validate each property value + Object.entries(values).forEach(([key, value]) => { + if (!this.isValidValue(value)) { + throw new Error(`Invalid value for property "${key}". Must be a float, "variable", or "undefined".`); + } + }); + + this.values = values; // Store valid values + } + + /** + * Checks if a value is valid. + * + * @param {*} value - The value to check. + * @returns {boolean} True if the value is valid, otherwise false. + */ + isValidValue(value) { + return typeof value === 'number' || value === "variable" || value === "undefined"; + } + + /** + * Updates a property value. + * + * @param {string} key - The property key to update. + * @param {*} value - The new value for the property. + * @throws {Error} If the value is invalid. + */ + updateProperty(key, value) { + if (!this.isValidValue(value)) { + throw new Error(`Invalid value for property "${key}". Must be a float, "variable", or "undefined".`); + } + this.values[key] = value; } /** @@ -22,7 +54,7 @@ export class Properties { */ describe() { return Object.entries(this.values) - .map(([key, value]) => `${key}: ${value.toString()}`) + .map(([key, value]) => `${key}: ${value}`) .join(', '); } } diff --git a/tests/domain/Element.test.js b/tests/domain/Element.test.js index 55b7126..2d822e2 100644 --- a/tests/domain/Element.test.js +++ b/tests/domain/Element.test.js @@ -56,6 +56,26 @@ describe('Element Class Tests', () => { 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." diff --git a/tests/domain/ElementService.test.js b/tests/domain/ElementService.test.js index 2653503..0e5b745 100644 --- a/tests/domain/ElementService.test.js +++ b/tests/domain/ElementService.test.js @@ -23,6 +23,10 @@ describe('Element Service Tests', () => { "Terminals must be an array of Position instances." ); }); + + it('TO BE CHECKED: All elements should have a label except for wires and junctions', () => { + expect(false).to.be.true; // Implement a test for this requirement + }); }); describe('Element Deletion', () => { @@ -107,4 +111,39 @@ describe('Element Service Tests', () => { ); }); }); + + describe('Element Service Property Updates', () => { + it('should update properties through ElementService', () => { + const terminals = [new Position(10, 20)]; + const properties = new Properties({ resistance: 100 }); + const element = new MockElement('E2', terminals, null, properties); + + // Update the property to a new float value + ElementService.updateProperties(element, { resistance: 200 }); + + expect(element.properties.values.resistance).to.equal(200); + }); + + it('should allow to define a property as undefined', () => { + const terminals = [new Position(10, 20)]; + const properties = new Properties({ resistance: 100 }); + const element = new MockElement('E1', terminals, null, properties); + + // Update the property to undefined + ElementService.updateProperties(element, { resistance: "undefined" }); + + expect(element.properties.values.resistance).to.equal("undefined"); + }); + + it('should allow defining properties as a variable parameter for the simulation engine', () => { + const terminals = [new Position(10, 20)]; + const properties = new Properties({ resistance: 100 }); + const element = new MockElement('E3', terminals, null, properties); + + // Define the property as "variable" + ElementService.updateProperties(element, { resistance: "variable" }); + + expect(element.properties.values.resistance).to.equal("variable"); + }); + }); }); \ No newline at end of file