refactor async tests
parent
b4f756d403
commit
38827f50d4
|
@ -58,7 +58,7 @@
|
|||
"istanbul": "^0.4.2",
|
||||
"js-beautify": "^1.5.6",
|
||||
"jshint": "^2.8.0",
|
||||
"json-schema-test": "^1.0.0",
|
||||
"json-schema-test": "^1.1.0",
|
||||
"karma": "^0.13.3",
|
||||
"karma-chrome-launcher": "^0.2.0",
|
||||
"karma-mocha": "^0.2.0",
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
[
|
||||
{
|
||||
"description": "async custom formats",
|
||||
"schema": {
|
||||
"$async": true,
|
||||
"type": "string",
|
||||
"format": "english_word"
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "'tomorrow' is a valid english word",
|
||||
"data": "tomorrow",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "'manana' is an invalid english word",
|
||||
"data": "manana",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "number is invalid",
|
||||
"data": 1,
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "'today' throws an exception, not in the dictionary",
|
||||
"data": "today",
|
||||
"error": "unknown word"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "async formats when $data ref resolves to async format name",
|
||||
"schema": {
|
||||
"$async": true,
|
||||
"additionalProperties": {
|
||||
"type": "string",
|
||||
"format": { "$data": "0#" }
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "'tomorrow' is a valid english word",
|
||||
"data": { "english_word": "tomorrow" },
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "'manana' is an invalid english word",
|
||||
"data": { "english_word": "manana" },
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "number is invalid",
|
||||
"data": { "english_word": 1 },
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "'today' throws an exception, not in the dictionary",
|
||||
"data": { "english_word": "today" },
|
||||
"error": "unknown word"
|
||||
},
|
||||
{
|
||||
"description": "valid date",
|
||||
"data": { "date": "2016-01-25" },
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid date",
|
||||
"data": { "date": "01/25/2016" },
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "number is invalid",
|
||||
"data": { "date": 1 },
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -0,0 +1,88 @@
|
|||
[
|
||||
{
|
||||
"description": "async custom keywords (validated)",
|
||||
"schema": {
|
||||
"$async": true,
|
||||
"properties": {
|
||||
"userId": {
|
||||
"type": "integer",
|
||||
"idExists": { "table": "users" }
|
||||
},
|
||||
"postId": {
|
||||
"type": "integer",
|
||||
"idExists": { "table": "posts" }
|
||||
},
|
||||
"categoryId": {
|
||||
"description": "will throw if present, no such table",
|
||||
"type": "integer",
|
||||
"idExists": { "table": "categories" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid object",
|
||||
"data": { "userId": 1, "postId": 21 },
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "another valid object",
|
||||
"data": { "userId": 5, "postId": 25 },
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid - no such post",
|
||||
"data": { "userId": 5, "postId": 10 },
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid - no such user",
|
||||
"data": { "userId": 9, "postId": 25 },
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "should throw exception during validation - no such table",
|
||||
"data": { "postId": 25, "categoryId": 1 },
|
||||
"error": "no such table"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "async custom keywords (compiled)",
|
||||
"schema": {
|
||||
"$async": true,
|
||||
"properties": {
|
||||
"userId": {
|
||||
"type": "integer",
|
||||
"idExistsCompiled": { "table": "users" }
|
||||
},
|
||||
"postId": {
|
||||
"type": "integer",
|
||||
"idExistsCompiled": { "table": "posts" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "valid object",
|
||||
"data": { "userId": 1, "postId": 21 },
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "another valid object",
|
||||
"data": { "userId": 5, "postId": 25 },
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "invalid - no such post",
|
||||
"data": { "userId": 5, "postId": 10 },
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "invalid - no such user",
|
||||
"data": { "userId": 9, "postId": 25 },
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -0,0 +1,27 @@
|
|||
[
|
||||
{
|
||||
"description": "async schema without async elements",
|
||||
"schema": {
|
||||
"$async": true,
|
||||
"type": "string",
|
||||
"maxLength": 3
|
||||
},
|
||||
"tests": [
|
||||
{
|
||||
"description": "string <= 3 chars is valid",
|
||||
"data": "abc",
|
||||
"valid": true
|
||||
},
|
||||
{
|
||||
"description": "string > 3 chars is invalid",
|
||||
"data": "abcd",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "number is invalid",
|
||||
"data": 1,
|
||||
"valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
|
@ -0,0 +1,103 @@
|
|||
'use strict';
|
||||
|
||||
var jsonSchemaTest = require('json-schema-test')
|
||||
, Promise = require('./promise')
|
||||
, getAjvInstances = require('./ajv_async_instances')
|
||||
, assert = require('./chai').assert;
|
||||
|
||||
|
||||
var instances = getAjvInstances({ v5: true });
|
||||
|
||||
instances.forEach(addAsyncFormatsAndKeywords);
|
||||
|
||||
|
||||
jsonSchemaTest(instances, {
|
||||
description: 'asynchronous schemas tests of ' + instances.length + ' ajv instances with different options',
|
||||
suites: testSuites(),
|
||||
async: true,
|
||||
assert: require('./chai').assert,
|
||||
Promise: Promise,
|
||||
afterError: function (res) {
|
||||
console.log('ajv options:', res.validator._opts);
|
||||
},
|
||||
// afterEach: function (res) {
|
||||
// console.log(res.errors);
|
||||
// },
|
||||
cwd: __dirname,
|
||||
hideFolder: 'async/',
|
||||
timeout: 90000
|
||||
});
|
||||
|
||||
|
||||
function testSuites() {
|
||||
if (typeof window == 'object') {
|
||||
var suites = {
|
||||
'async schemas': require('./async/{**/,}*.json', {mode: 'list'})
|
||||
};
|
||||
for (var suiteName in suites) {
|
||||
suites[suiteName].forEach(function (suite) {
|
||||
suite.test = suite.module;
|
||||
});
|
||||
}
|
||||
} else {
|
||||
var suites = {
|
||||
'async schemas': './async/{**/,}*.json'
|
||||
}
|
||||
}
|
||||
return suites;
|
||||
}
|
||||
|
||||
|
||||
function addAsyncFormatsAndKeywords (ajv) {
|
||||
ajv.addFormat('english_word', {
|
||||
async: true,
|
||||
validate: checkWordOnServer
|
||||
});
|
||||
|
||||
ajv.addKeyword('idExists', {
|
||||
async: true,
|
||||
type: 'number',
|
||||
validate: checkIdExists
|
||||
});
|
||||
|
||||
ajv.addKeyword('idExistsCompiled', {
|
||||
async: true,
|
||||
type: 'number',
|
||||
compile: compileCheckIdExists
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function checkWordOnServer(str) {
|
||||
return str == 'tomorrow' ? Promise.resolve(true)
|
||||
: str == 'manana' ? Promise.resolve(false)
|
||||
: Promise.reject(new Error('unknown word'));
|
||||
}
|
||||
|
||||
|
||||
function checkIdExists(schema, data) {
|
||||
switch (schema.table) {
|
||||
case 'users': return check([1, 5, 8]);
|
||||
case 'posts': return check([21, 25, 28]);
|
||||
default: throw new Error('no such table');
|
||||
}
|
||||
|
||||
function check(IDs) {
|
||||
return Promise.resolve(IDs.indexOf(data) >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function compileCheckIdExists(schema) {
|
||||
switch (schema.table) {
|
||||
case 'users': return compileCheck([1, 5, 8]);
|
||||
case 'posts': return compileCheck([21, 25, 28]);
|
||||
default: throw new Error('no such table');
|
||||
}
|
||||
|
||||
function compileCheck(IDs) {
|
||||
return function (data) {
|
||||
return Promise.resolve(IDs.indexOf(data) >= 0);
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,17 +1,10 @@
|
|||
'use strict';
|
||||
|
||||
var Ajv = require('./ajv')
|
||||
, Promise = require('./promise')
|
||||
, getAjvInstances = require('./ajv_async_instances')
|
||||
, should = require('./chai').should()
|
||||
, co = require('co')
|
||||
, Promise = require('bluebird');
|
||||
|
||||
Promise.config({ warnings: false });
|
||||
|
||||
var g = typeof global == 'object' ? global :
|
||||
typeof window == 'object' ? window : this;
|
||||
|
||||
g.Promise = g.Promise || Promise;
|
||||
, co = require('co');
|
||||
|
||||
|
||||
describe('async schemas, formats and keywords', function() {
|
||||
|
@ -48,9 +41,6 @@ describe('async schemas, formats and keywords', function() {
|
|||
shouldBeValid( _co(validate('abc')) ),
|
||||
shouldBeInvalid( _co(validate('abcd')) ),
|
||||
shouldBeInvalid( _co(validate(1)) ),
|
||||
shouldBeValid( ajv.validate(schema, 'abc') ),
|
||||
shouldBeInvalid( ajv.validate(schema, 'abcd') ),
|
||||
shouldBeInvalid( ajv.validate(schema, 1) )
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
@ -80,28 +70,6 @@ describe('async schemas, formats and keywords', function() {
|
|||
describe('async formats', function() {
|
||||
beforeEach(addFormatEnglishWord);
|
||||
|
||||
it('should return promise that resolves as true or rejects with array of errors', function() {
|
||||
var schema = {
|
||||
$async: true,
|
||||
type: 'string',
|
||||
format: 'english_word'
|
||||
};
|
||||
|
||||
return repeat(function() { return Promise.map(instances, test); });
|
||||
|
||||
function test(ajv) {
|
||||
var validate = ajv.compile(schema);
|
||||
var _co = useCo(ajv);
|
||||
|
||||
return Promise.all([
|
||||
shouldBeValid( _co(validate('tomorrow')) ),
|
||||
shouldBeInvalid( _co(validate('manana')) ),
|
||||
shouldBeInvalid( _co(validate(1)) ),
|
||||
shouldThrow( _co(validate('today')), 'unknown word' )
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
it('should fail compilation if async format is inside sync schema', function() {
|
||||
instances.forEach(function (ajv) {
|
||||
|
@ -117,38 +85,6 @@ describe('async schemas, formats and keywords', function() {
|
|||
ajv.compile(schema);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should support async formats when $data ref resolves to async format name', function() {
|
||||
instances = getAjvInstances({ v5: true });
|
||||
addFormatEnglishWord();
|
||||
|
||||
var schema = {
|
||||
$async: true,
|
||||
additionalProperties: {
|
||||
type: 'string',
|
||||
format: { $data: '0#' }
|
||||
}
|
||||
};
|
||||
|
||||
return repeat(function() { return Promise.map(instances, test); });
|
||||
|
||||
function test(ajv, index) {
|
||||
var validate = ajv.compile(schema);
|
||||
var _co = useCo(ajv);
|
||||
|
||||
return Promise.all([
|
||||
shouldBeValid( _co(validate({ english_word: 'tomorrow' })) ),
|
||||
shouldBeInvalid( _co(validate({ english_word: 'manana' })) ),
|
||||
shouldBeInvalid( _co(validate({ english_word: 1 })) ),
|
||||
shouldThrow( _co(validate({ english_word: 'today' })), 'unknown word' ),
|
||||
|
||||
shouldBeValid( _co(validate({ date: '2016-01-25' })) ),
|
||||
shouldBeInvalid( _co(validate({ date: '01/25/2016' })) ),
|
||||
shouldBeInvalid( _co(validate({ date: 1 })) ),
|
||||
]);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
@ -160,74 +96,10 @@ describe('async schemas, formats and keywords', function() {
|
|||
type: 'number',
|
||||
validate: checkIdExists
|
||||
});
|
||||
|
||||
ajv.addKeyword('idExistsCompiled', {
|
||||
async: true,
|
||||
type: 'number',
|
||||
compile: compileCheckIdExists
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should validate custom keyword that returns promise', function() {
|
||||
var schema1 = {
|
||||
$async: true,
|
||||
properties: {
|
||||
userId: {
|
||||
type: 'integer',
|
||||
idExists: { table: 'users' }
|
||||
},
|
||||
postId: {
|
||||
type: 'integer',
|
||||
idExists: { table: 'posts' }
|
||||
},
|
||||
categoryId: {
|
||||
description: 'will throw if present, no such table',
|
||||
type: 'integer',
|
||||
idExists: { table: 'categories' }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var schema2 = {
|
||||
$async: true,
|
||||
properties: {
|
||||
userId: {
|
||||
type: 'integer',
|
||||
idExistsCompiled: { table: 'users' }
|
||||
},
|
||||
postId: {
|
||||
type: 'integer',
|
||||
idExistsCompiled: { table: 'posts' }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return repeat(function() { return Promise.all([
|
||||
test(instances, schema1, true),
|
||||
test(instances, schema2)
|
||||
]); });
|
||||
|
||||
function test(instances, schema, checkThrow) {
|
||||
return Promise.map(instances, function (ajv) {
|
||||
var validate = ajv.compile(schema);
|
||||
var _co = useCo(ajv);
|
||||
|
||||
return Promise.all([
|
||||
shouldBeValid( _co(validate({ userId: 1, postId: 21 })) ),
|
||||
shouldBeValid( _co(validate({ userId: 5, postId: 25 })) ),
|
||||
shouldBeInvalid( _co(validate({ userId: 5, postId: 10 })) ), // no post
|
||||
shouldBeInvalid( _co(validate({ userId: 9, postId: 25 })) ), // no user
|
||||
checkThrow
|
||||
? shouldThrow( _co(validate({ postId: 25, categoryId: 1 })), 'no such table' )
|
||||
: undefined
|
||||
]);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
it('should fail compilation if async keyword is inside sync schema', function() {
|
||||
instances.forEach(function (ajv) {
|
||||
var schema = {
|
||||
|
@ -261,21 +133,6 @@ describe('async schemas, formats and keywords', function() {
|
|||
return Promise.resolve(IDs.indexOf(data) >= 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function compileCheckIdExists(schema) {
|
||||
switch (schema.table) {
|
||||
case 'users': return compileCheck([1, 5, 8]);
|
||||
case 'posts': return compileCheck([21, 25, 28]);
|
||||
default: throw new Error('no such table');
|
||||
}
|
||||
|
||||
function compileCheck(IDs) {
|
||||
return function (data) {
|
||||
return Promise.resolve(IDs.indexOf(data) >= 0);
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
'use strict'
|
||||
|
||||
var Promise = require('bluebird');
|
||||
|
||||
Promise.config({ warnings: false });
|
||||
|
||||
var g = typeof global == 'object' ? global :
|
||||
typeof window == 'object' ? window : this;
|
||||
|
||||
g.Promise = g.Promise || Promise;
|
||||
|
||||
module.exports = Promise;
|
Loading…
Reference in New Issue