Files
privacy.sexy/tests/unit/application/Parser/NodeValidation/NodeValidator.spec.ts
undergroundwires b210aaddf2 Improve script/category name validation
- Use better error messages with more context.
- Unify their validation logic and share tests.
- Validate also type of the name.
- Refactor node (Script/Category) parser tests for easier future
  changes and cleaner test code (using `TestBuilder` to do dirty work in
  unified way).
- Add more tests. Custom `Error` properties are compared manually due to
  `chai` not supporting deep equality checks (chaijs/chai#1065,
  chaijs/chai#1405).
2022-03-11 09:56:50 +01:00

101 lines
3.4 KiB
TypeScript

import 'mocha';
import { expect } from 'chai';
import { NodeDataError } from '@/application/Parser/NodeValidation/NodeDataError';
import { NodeValidator } from '@/application/Parser/NodeValidation/NodeValidator';
import { expectThrowsError } from '@tests/unit/shared/Assertions/ExpectThrowsError';
import { CategoryDataStub } from '@tests/unit/shared/Stubs/CategoryDataStub';
import { NodeDataErrorContextStub } from '@tests/unit/shared/Stubs/NodeDataErrorContextStub';
import { NodeData } from '@/application/Parser/NodeValidation/NodeData';
import { NodeValidationTestRunner } from './NodeValidatorTestRunner';
describe('NodeValidator', () => {
describe('assertValidName', () => {
describe('throws if invalid', () => {
// arrange
const context = new NodeDataErrorContextStub();
const sut = new NodeValidator(context);
// act
const act = (invalidName: string) => sut.assertValidName(invalidName);
// assert
new NodeValidationTestRunner()
.testInvalidNodeName((invalidName) => ({
act: () => act(invalidName),
expectedContext: context,
}));
});
it('does not throw if valid', () => {
// arrange
const validName = 'validName';
const sut = new NodeValidator(new NodeDataErrorContextStub());
// act
const act = () => sut.assertValidName(validName);
// assert
expect(act).to.not.throw();
});
});
describe('assertDefined', () => {
describe('throws if missing', () => {
// arrange
const context = new NodeDataErrorContextStub();
const sut = new NodeValidator(context);
// act
const act = (undefinedNode: NodeData) => sut.assertDefined(undefinedNode);
// assert
new NodeValidationTestRunner()
.testMissingNodeData((invalidName) => ({
act: () => act(invalidName),
expectedContext: context,
}));
});
it('does not throw if defined', () => {
// arrange
const definedNode = mockNode();
const sut = new NodeValidator(new NodeDataErrorContextStub());
// act
const act = () => sut.assertDefined(definedNode);
// assert
expect(act).to.not.throw();
});
});
describe('assert', () => {
it('throws expected error if condition is false', () => {
// arrange
const message = 'error';
const falsePredicate = () => false;
const context = new NodeDataErrorContextStub();
const expected = new NodeDataError(message, context);
const sut = new NodeValidator(context);
// act
const act = () => sut.assert(falsePredicate, message);
// assert
expectThrowsError(act, expected);
});
it('does not throw if condition is true', () => {
// arrange
const truePredicate = () => true;
const sut = new NodeValidator(new NodeDataErrorContextStub());
// act
const act = () => sut.assert(truePredicate, 'ignored error');
// assert
expect(act).to.not.throw();
});
});
describe('throw', () => {
it('throws expected error', () => {
// arrange
const message = 'error';
const context = new NodeDataErrorContextStub();
const expected = new NodeDataError(message, context);
const sut = new NodeValidator(context);
// act
const act = () => sut.throw(message);
// assert
expectThrowsError(act, expected);
});
});
});
function mockNode() {
return new CategoryDataStub();
}