You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
347 lines
6.6 KiB
347 lines
6.6 KiB
'use strict'
|
|
|
|
const t = require('tap')
|
|
const Ajv = require('ajv')
|
|
const makeTest = require('./make-test')
|
|
const { join } = require('path')
|
|
|
|
process.env.VALUE_FROM_ENV = 'pippo'
|
|
|
|
const tests = [
|
|
{
|
|
name: 'empty ok',
|
|
schema: { type: 'object' },
|
|
data: { },
|
|
isOk: true,
|
|
confExpected: {}
|
|
},
|
|
{
|
|
name: 'simple object - ok',
|
|
schema: {
|
|
type: 'object',
|
|
properties: {
|
|
PORT: {
|
|
type: 'string'
|
|
}
|
|
}
|
|
},
|
|
data: {
|
|
PORT: '44'
|
|
},
|
|
isOk: true,
|
|
confExpected: {
|
|
PORT: '44'
|
|
}
|
|
},
|
|
{
|
|
name: 'simple object - ok - coerce value',
|
|
schema: {
|
|
type: 'object',
|
|
properties: {
|
|
PORT: {
|
|
type: 'integer'
|
|
}
|
|
}
|
|
},
|
|
data: {
|
|
PORT: '44'
|
|
},
|
|
isOk: true,
|
|
confExpected: {
|
|
PORT: 44
|
|
}
|
|
},
|
|
{
|
|
name: 'simple object - ok - remove additional properties',
|
|
schema: {
|
|
type: 'object',
|
|
properties: {
|
|
PORT: {
|
|
type: 'integer'
|
|
}
|
|
}
|
|
},
|
|
data: {
|
|
PORT: '44',
|
|
ANOTHER_PORT: '55'
|
|
},
|
|
isOk: true,
|
|
confExpected: {
|
|
PORT: 44
|
|
}
|
|
},
|
|
{
|
|
name: 'simple object - ok - use default',
|
|
schema: {
|
|
type: 'object',
|
|
properties: {
|
|
PORT: {
|
|
type: 'integer',
|
|
default: 5555
|
|
}
|
|
}
|
|
},
|
|
data: { },
|
|
isOk: true,
|
|
confExpected: {
|
|
PORT: 5555
|
|
}
|
|
},
|
|
{
|
|
name: 'simple object - ok - required + default',
|
|
schema: {
|
|
type: 'object',
|
|
required: ['PORT'],
|
|
properties: {
|
|
PORT: {
|
|
type: 'integer',
|
|
default: 6666
|
|
}
|
|
}
|
|
},
|
|
data: { },
|
|
isOk: true,
|
|
confExpected: {
|
|
PORT: 6666
|
|
}
|
|
},
|
|
{
|
|
name: 'simple object - ok - allow array',
|
|
schema: {
|
|
type: 'object',
|
|
required: ['PORT'],
|
|
properties: {
|
|
PORT: {
|
|
type: 'integer',
|
|
default: 6666
|
|
}
|
|
}
|
|
},
|
|
data: [{ }],
|
|
isOk: true,
|
|
confExpected: {
|
|
PORT: 6666
|
|
}
|
|
},
|
|
{
|
|
name: 'simple object - ok - merge multiple object + env',
|
|
schema: {
|
|
type: 'object',
|
|
required: ['PORT', 'MONGODB_URL'],
|
|
properties: {
|
|
PORT: {
|
|
type: 'integer',
|
|
default: 6666
|
|
},
|
|
MONGODB_URL: {
|
|
type: 'string'
|
|
},
|
|
VALUE_FROM_ENV: {
|
|
type: 'string'
|
|
}
|
|
}
|
|
},
|
|
data: [{ PORT: 3333 }, { MONGODB_URL: 'mongodb://localhost/pippo' }],
|
|
isOk: true,
|
|
confExpected: {
|
|
PORT: 3333,
|
|
MONGODB_URL: 'mongodb://localhost/pippo',
|
|
VALUE_FROM_ENV: 'pippo'
|
|
}
|
|
},
|
|
{
|
|
name: 'simple object - ok - load only from env',
|
|
schema: {
|
|
type: 'object',
|
|
required: ['VALUE_FROM_ENV'],
|
|
properties: {
|
|
VALUE_FROM_ENV: {
|
|
type: 'string'
|
|
}
|
|
}
|
|
},
|
|
data: undefined,
|
|
isOk: true,
|
|
confExpected: {
|
|
VALUE_FROM_ENV: 'pippo'
|
|
}
|
|
},
|
|
{
|
|
name: 'simple object - ok - opts override environment',
|
|
schema: {
|
|
type: 'object',
|
|
required: ['VALUE_FROM_ENV'],
|
|
properties: {
|
|
VALUE_FROM_ENV: {
|
|
type: 'string'
|
|
}
|
|
}
|
|
},
|
|
data: { VALUE_FROM_ENV: 'pluto' },
|
|
isOk: true,
|
|
confExpected: {
|
|
VALUE_FROM_ENV: 'pluto'
|
|
}
|
|
},
|
|
{
|
|
name: 'simple object - ok - load only from .env',
|
|
schema: {
|
|
type: 'object',
|
|
required: ['VALUE_FROM_DOTENV'],
|
|
properties: {
|
|
VALUE_FROM_DOTENV: {
|
|
type: 'string'
|
|
}
|
|
}
|
|
},
|
|
data: undefined,
|
|
isOk: true,
|
|
dotenv: { path: join(__dirname, '.env') },
|
|
confExpected: {
|
|
VALUE_FROM_DOTENV: 'look ma'
|
|
}
|
|
},
|
|
{
|
|
name: 'simple object - KO',
|
|
schema: {
|
|
type: 'object',
|
|
required: ['PORT'],
|
|
properties: {
|
|
PORT: {
|
|
type: 'integer'
|
|
}
|
|
}
|
|
},
|
|
data: { },
|
|
isOk: false,
|
|
errorMessage: 'env must have required property \'PORT\''
|
|
},
|
|
{
|
|
name: 'simple object - invalid data',
|
|
schema: {
|
|
type: 'object',
|
|
required: ['PORT'],
|
|
properties: {
|
|
PORT: {
|
|
type: 'integer'
|
|
}
|
|
}
|
|
},
|
|
data: [],
|
|
isOk: false,
|
|
errorMessage: 'opts/data must NOT have fewer than 1 items, opts/data must be object, opts/data must match exactly one schema in oneOf'
|
|
}
|
|
]
|
|
|
|
const ajv = new Ajv({
|
|
allErrors: true,
|
|
removeAdditional: true,
|
|
useDefaults: true,
|
|
coerceTypes: true,
|
|
allowUnionTypes: true
|
|
})
|
|
|
|
tests.forEach(function (testConf) {
|
|
t.test(testConf.name, t => {
|
|
const options = {
|
|
schema: testConf.schema,
|
|
data: testConf.data,
|
|
dotenv: testConf.dotenv,
|
|
dotenvConfig: testConf.dotenvConfig,
|
|
ajv
|
|
}
|
|
|
|
makeTest(t, options, testConf.isOk, testConf.confExpected, testConf.errorMessage)
|
|
})
|
|
})
|
|
|
|
const noCoercionTest = {
|
|
name: 'simple object - not ok - should NOT coerce value',
|
|
schema: {
|
|
type: 'object',
|
|
properties: {
|
|
PORT: {
|
|
type: 'integer'
|
|
}
|
|
}
|
|
},
|
|
data: {
|
|
PORT: '44'
|
|
},
|
|
isOk: false,
|
|
errorMessage: 'env/PORT must be integer',
|
|
confExpected: {
|
|
PORT: 44
|
|
}
|
|
}
|
|
|
|
const strictValidator = new Ajv({
|
|
allErrors: true,
|
|
removeAdditional: true,
|
|
useDefaults: true,
|
|
coerceTypes: false,
|
|
allowUnionTypes: true
|
|
});
|
|
|
|
[noCoercionTest].forEach(function (testConf) {
|
|
t.test(testConf.name, t => {
|
|
const options = {
|
|
schema: testConf.schema,
|
|
data: testConf.data,
|
|
dotenv: testConf.dotenv,
|
|
dotenvConfig: testConf.dotenvConfig,
|
|
ajv: strictValidator
|
|
}
|
|
|
|
makeTest(t, options, testConf.isOk, testConf.confExpected, testConf.errorMessage)
|
|
})
|
|
})
|
|
|
|
t.test('ajv enhancement', t => {
|
|
t.plan(2)
|
|
const testCase = {
|
|
schema: {
|
|
type: 'object',
|
|
required: ['MONGODB_URL'],
|
|
properties: {
|
|
MONGODB_URL: {
|
|
type: 'string',
|
|
format: 'uri'
|
|
}
|
|
}
|
|
},
|
|
data: [{ PORT: 3333 }, { MONGODB_URL: 'mongodb://localhost/pippo' }],
|
|
isOk: true,
|
|
confExpected: {
|
|
MONGODB_URL: 'mongodb://localhost/pippo'
|
|
}
|
|
}
|
|
|
|
t.test('return', t => {
|
|
const options = {
|
|
schema: testCase.schema,
|
|
data: testCase.data,
|
|
ajv: {
|
|
customOptions (ajvInstance) {
|
|
require('ajv-formats')(ajvInstance)
|
|
return ajvInstance
|
|
}
|
|
}
|
|
}
|
|
makeTest(t, options, testCase.isOk, testCase.confExpected)
|
|
})
|
|
|
|
t.test('no return', t => {
|
|
const options = {
|
|
schema: testCase.schema,
|
|
data: testCase.data,
|
|
ajv: {
|
|
customOptions (ajvInstance) {
|
|
// do nothing
|
|
}
|
|
}
|
|
}
|
|
makeTest(t, options, false, undefined, 'customOptions function must return an instance of Ajv')
|
|
})
|
|
})
|