UNPKG

@eclipse-emfcloud/model-validation

Version:

Generic model validation framework.

286 lines 12.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); // ***************************************************************************** // Copyright (C) 2023-2024 STMicroelectronics. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at // http://www.eclipse.org/legal/epl-2.0. // // This Source Code may also be made available under the following Secondary // Licenses when the conditions for such availability set forth in the Eclipse // Public License v. 2.0 are satisfied: MIT License which is // available at https://opensource.org/licenses/MIT. // // SPDX-License-Identifier: EPL-2.0 OR MIT // ***************************************************************************** const chai_1 = require("chai"); const diagnostic_1 = require("../diagnostic"); describe('Diagnostic functions', () => { describe('ok', () => { it('yields an OK diagnostic', () => { const actual = (0, diagnostic_1.ok)(); (0, chai_1.expect)(actual.severity, 'not ok').to.be.equal('ok'); (0, chai_1.expect)(actual.source).to.be.equal('@eclipse-emfcloud/model-validation'); }); it('always yields a new instance', () => { const first = (0, diagnostic_1.ok)(); const second = (0, diagnostic_1.ok)(); (0, chai_1.expect)(second, 'not distinct').not.to.be.equal(first); }); it('supports a custom source', () => { const custom = (0, diagnostic_1.ok)('@example/test'); (0, chai_1.expect)(custom.source, 'stock source').to.be.equal('@example/test'); }); }); describe('merge', () => { const defaultOKInstance = (0, diagnostic_1.ok)(); const customOKInstance = { severity: 'ok', source: '@example/test', code: '0', path: '', message: 'Hello.', }; const infoInstance = { severity: 'info', source: '@example/test', code: '1', path: 'foo/infoProp', message: 'I have information for you.', }; const warningInstance = { severity: 'warn', source: '@example/test', code: '2', path: 'foo/warningProp', message: 'This is a warning.', }; const errorInstance = { severity: 'error', source: '@example/test', code: '4', path: 'foo/errorProp', message: 'Error, error!', children: [], // Empty children array is equivalent to absent children array }; const multiWarningInstance = { severity: 'warn', source: '@example/test', path: 'foo/warningObject', message: '', children: [warningInstance, infoInstance], }; const multiErrorInstance = { severity: 'error', source: '@example/test', path: 'foo/errorObject', message: '', children: [customOKInstance, errorInstance], }; // This one contains itself and is, therefore, invalid const cyclicInstance = { severity: 'error', source: '@example/test', path: 'bar/cyclic', message: '', children: [multiWarningInstance], }; cyclicInstance.children?.push(cyclicInstance); it('merges no diagnostics', () => { const actual = (0, diagnostic_1.merge)(); (0, chai_1.expect)(actual.severity, 'not ok').to.be.equal('ok'); verifySerializable(actual); }); it('merges one diagnostic', () => { const actual = (0, diagnostic_1.merge)(infoInstance); (0, chai_1.expect)(actual, 'input not returned').to.be.equal(infoInstance); verifySerializable(actual); }); it('merges only OK diagnostics', () => { const actual = (0, diagnostic_1.merge)(defaultOKInstance, customOKInstance); (0, chai_1.expect)(actual.severity, 'not ok').to.be.equal('ok'); (0, chai_1.expect)(actual, 'returned one of the inputs') .not.to.equal(defaultOKInstance) .and.not.to.equal(customOKInstance); verifySerializable(actual); }); it('merges an OK and a problem', () => { const actual = (0, diagnostic_1.merge)(customOKInstance, warningInstance); (0, chai_1.expect)(actual).to.equal(warningInstance); verifySerializable(actual); }); it('merges a leaf and another leaf', () => { const actual = (0, diagnostic_1.merge)(infoInstance, warningInstance); (0, chai_1.expect)(actual).to.deep.equal({ severity: 'warn', source: '@example/test', path: 'foo', message: '2 problems found.', children: [infoInstance, warningInstance], }); verifySerializable(actual); }); it('merges a leaf and a non-leaf', () => { const actual = (0, diagnostic_1.merge)(errorInstance, multiWarningInstance); (0, chai_1.expect)(actual).to.deep.equal({ severity: 'error', source: '@example/test', path: 'foo', message: '3 problems found.', children: [errorInstance, warningInstance, infoInstance], }); verifySerializable(actual); }); it('merges a leaf and a non-leaf in which some child is OK', () => { const actual = (0, diagnostic_1.merge)(warningInstance, multiErrorInstance); (0, chai_1.expect)(actual).to.deep.equal({ severity: 'error', source: '@example/test', path: 'foo', message: '2 problems found.', children: [warningInstance, errorInstance], // `customOKInstance` was elided }); verifySerializable(actual); }); it('merges a non-leaf and a leaf', () => { const actual = (0, diagnostic_1.merge)(multiWarningInstance, errorInstance); (0, chai_1.expect)(actual).to.deep.equal({ severity: 'error', source: '@example/test', path: 'foo', message: '3 problems found.', children: [warningInstance, infoInstance, errorInstance], }); verifySerializable(actual); }); it('merges a non-leaf in which some child is OK and a leaf', () => { const actual = (0, diagnostic_1.merge)(multiErrorInstance, warningInstance); (0, chai_1.expect)(actual).to.deep.equal({ severity: 'error', source: '@example/test', path: 'foo', message: '2 problems found.', children: [errorInstance, warningInstance], // `customOKInstance` was elided }); verifySerializable(actual); }); it('merges a non-leaf and another non-leaf', () => { const actual = (0, diagnostic_1.merge)(multiWarningInstance, multiErrorInstance); (0, chai_1.expect)(actual).to.deep.equal({ severity: 'error', source: '@example/test', path: 'foo', message: '3 problems found.', children: [warningInstance, infoInstance, errorInstance], // `customOKInstance` was elided }); verifySerializable(actual); }); it('tolerates a cyclic diagnostic', () => { const actual = (0, diagnostic_1.merge)(multiErrorInstance, cyclicInstance); (0, chai_1.expect)(actual).to.include({ severity: 'error', source: '@example/test', path: '', message: '3 problems found.', }); (0, chai_1.expect)(actual.children) .to.be.an('array') .of.length(3) .that.includes(errorInstance) .and.that.includes(multiWarningInstance) .and.that.includes(cyclicInstance); // Don't try to serialize this cyclic structure }); it('merges more than two diagnostics', () => { const newInstance = { severity: 'info', source: '@example/test', path: 'foo', message: "You've got mail!", }; const actual = (0, diagnostic_1.merge)(infoInstance, warningInstance, multiErrorInstance, newInstance); (0, chai_1.expect)(actual).to.deep.equal({ severity: 'error', source: '@example/test', path: 'foo', message: '4 problems found.', children: [infoInstance, warningInstance, errorInstance, newInstance], // `customOKInstance` was elided }); verifySerializable(actual); }); it('merges non-leaf diagnostics that only have OK children', () => { const silly1 = { severity: 'info', // This doesn't make sense source: '@example/test', path: 'foo/silly/1', message: 'This is a silly diagnostic.', children: [defaultOKInstance, customOKInstance], }; const silly2 = { severity: 'warn', // This doesn't make sense source: '@example/test', path: 'foo/silly/2', message: 'This is another silly diagnostic.', children: [(0, diagnostic_1.ok)(), defaultOKInstance], }; const actual = (0, diagnostic_1.merge)(silly1, silly2); (0, chai_1.expect)(actual, 'merge is not reduced').to.be.deep.equal((0, diagnostic_1.ok)()); }); it('treats empty children array the same as no children array', () => { const emptyChildren = { severity: 'warn', source: '@example/test', path: 'foo/emptyChildren', message: 'This diagnostic has an empty children array.', children: [], }; const actual = (0, diagnostic_1.merge)(emptyChildren); (0, chai_1.expect)(actual, 'leaf should have stood for itself').to.be.equal(emptyChildren); }); it('merge of a single multi-diagnostic filters its children', () => { const actual = (0, diagnostic_1.merge)(multiErrorInstance); (0, chai_1.expect)(actual, 'merge is not reduced').to.be.equal(errorInstance); }); it('tolerates missing paths', () => { const missingPath = { severity: 'warn', source: '@example/test', message: 'None.', }; const hasPath = { severity: 'info', source: '@example/test', path: 'foo/whatever', message: 'None.', }; const missingFirst = (0, diagnostic_1.merge)(missingPath, hasPath); delete missingFirst.children; const missingSecond = (0, diagnostic_1.merge)(hasPath, missingPath); delete missingSecond.children; (0, chai_1.expect)(missingSecond).to.be.deep.equal(missingFirst); (0, chai_1.expect)(missingFirst).to.be.deep.equal({ severity: 'warn', source: '@example/test', path: '', message: '2 problems found.', }); }); it('reduces mixed sources to nil', () => { const source1 = { source: '@example/1' }; const source2a = { source: '@example/2' }; const source2b = { source: '@example/2' }; const actual = (0, diagnostic_1.merge)(source1, source2a, source2b); (0, chai_1.expect)(actual.source).not.to.be.ok; // Chai's version of '.to.be.falsy' }); it('source of empty merge is defaulted', () => { const actual = (0, diagnostic_1.merge)(); (0, chai_1.expect)(actual.source).to.be.equal('@eclipse-emfcloud/model-validation'); }); }); }); const verifySerializable = (d) => { const transmitted = JSON.parse(JSON.stringify(d)); (0, chai_1.expect)(transmitted).to.deep.equal(d); }; //# sourceMappingURL=diagnostic.spec.js.map