1
0
Fork 0
salty-dog/test/rule/TestSchemaRule.ts

158 lines
3.9 KiB
TypeScript

import { expect } from 'chai';
import { NullLogger } from 'noicejs';
import { stub } from 'sinon';
import { SchemaRule } from '../../src/rule/SchemaRule';
import { VisitorContext } from '../../src/visitor/VisitorContext';
import { describeLeaks, itLeaks } from '../helpers/async';
const TEST_NAME = 'test-rule';
describeLeaks('schema rule', async () => {
itLeaks('should pick items from the scope', async () => {
const ctx = new VisitorContext({
innerOptions: {
coerce: false,
defaults: false,
mutate: false,
},
logger: NullLogger.global,
});
const data = {
foo: 3,
};
const rule = new SchemaRule({
check: {},
desc: '',
level: 'info',
name: 'foo',
select: '$.foo',
tags: [],
});
const results = await rule.pick(ctx, data);
expect(results).to.deep.equal([data.foo]);
});
itLeaks('should filter out items', async () => {
const ctx = new VisitorContext({
innerOptions: {
coerce: false,
defaults: false,
mutate: false,
},
logger: NullLogger.global,
});
const data = {
foo: 3,
};
const rule = new SchemaRule({
check: {},
desc: '',
filter: {
properties: {
foo: {
type: 'number',
},
},
type: 'object',
},
level: 'info',
name: 'foo',
select: '$.foo',
tags: [],
});
const results = await rule.visit(ctx, data);
expect(results.errors.length).to.equal(0);
});
itLeaks('should pick items from the root', async () => {
const ctx = new VisitorContext({
innerOptions: {
coerce: false,
defaults: false,
mutate: false,
},
logger: NullLogger.global,
});
const rule = new SchemaRule({
check: undefined,
desc: TEST_NAME,
level: 'info',
name: TEST_NAME,
select: '$.foo',
tags: [],
});
const results = await rule.pick(ctx, {
foo: [1, 2, 3],
});
expect(Array.isArray(results)).to.equal(true);
});
itLeaks('should visit selected items', async () => {
const ctx = new VisitorContext({
innerOptions: {
coerce: false,
defaults: false,
mutate: false,
},
logger: NullLogger.global,
});
const check = {};
const checkSpy = stub().returns(true);
const filter = {};
const filterSpy = stub().returns(true);
ctx.compile = stub().onFirstCall().returns(checkSpy).onSecondCall().returns(filterSpy);
const rule = new SchemaRule({
check,
desc: TEST_NAME,
filter,
level: 'info',
name: TEST_NAME,
select: '$.foo',
tags: [],
});
const data = {};
await rule.visit(ctx, data);
expect(filterSpy, 'filter spy should have been called with data').to.have.callCount(1).and.been.calledWithExactly(data);
expect(checkSpy, 'check spy should have been called with data').to.have.callCount(1).and.been.calledWithExactly(data);
});
itLeaks('should skip filtered items', async () => {
const ctx = new VisitorContext({
innerOptions: {
coerce: false,
defaults: false,
mutate: false,
},
logger: NullLogger.global,
});
const checkSpy = stub().throws(new Error('check spy error'));
const filterSpy = stub().returns(false);
ctx.compile = stub().onFirstCall().returns(checkSpy).onSecondCall().returns(filterSpy);
const rule = new SchemaRule({
check: undefined,
desc: TEST_NAME,
filter: {},
level: 'info',
name: TEST_NAME,
select: '$.foo',
tags: [],
});
const data = {};
await rule.visit(ctx, data);
expect(filterSpy, 'filter spy should have been called with data').to.have.callCount(1).and.been.calledWithExactly(data);
expect(checkSpy, 'check spy should not have been called').to.have.callCount(0);
});
});