async with nodent transpiler

master
Evgeny Poberezkin 2016-01-29 09:26:11 +00:00
parent 7365dd6e41
commit 6e583554a1
8 changed files with 70 additions and 44 deletions

4
.gitignore vendored
View File

@ -41,3 +41,7 @@ ajv.min.*
# regenerator bundle
regenerator.bundle.*
regenerator.min.*
# nodent bundle
nodent.bundle.*
nodent.min.*

View File

@ -18,6 +18,7 @@ module.exports = function(config) {
'ajv.min.js',
'node_modules/chai/chai.js',
'regenerator.min.js',
'nodent.min.js',
'.browser/*.spec.js'
],

View File

@ -59,16 +59,11 @@ function Ajv(opts) {
addInitialSchemas();
if (opts.formats) addInitialFormats();
if (opts.errorDataPath == 'property')
opts._errorDataPathProperty = true;
if (opts.errorDataPath == 'property') opts._errorDataPathProperty = true;
if (opts.v5) v5.enable(this);
opts.loopRequired = opts.loopRequired || Infinity;
if (opts.async && !opts.transpile)
async.setTranspile(opts);
if (opts.beautify) opts.beautify = opts.beautify === true ? { indent_size: 2 } : opts.beautify;
if (opts.async && !opts.transpile) async.setTranspile(opts);
/**

View File

@ -13,11 +13,11 @@ module.exports = {
var ASYNC = {
generators: generatorsSupported,
es7: getNodent,
regenerator: getRegenerator
'generators': generatorsSupported,
'es7.nodent': getNodent,
'regenerator': getRegenerator
};
var MODES = ['generators', 'es7', 'regenerator'];
var MODES = ['generators', 'es7.nodent', 'regenerator'];
var MODES_STR = MODES.join('/');
var regenerator, nodent;
@ -72,9 +72,7 @@ function regeneratorTranspile(code) {
function getNodent() {
try {
if (!nodent) {
nodent = require('' + 'nodent')({ log: noop });
}
if (!nodent) nodent = require('' + 'nodent')({ log: noop });
return nodentTranspile;
} catch(e) {}
}

View File

@ -16,6 +16,7 @@ module.exports = compile;
function compile(schema, root, localRefs, baseId) {
/* jshint validthis: true, evil: true */
var self = this
, opts = this._opts
, refVal = [ undefined ]
, refs = {}
, patterns = []
@ -38,6 +39,9 @@ function compile(schema, root, localRefs, baseId) {
if (_root.schema != root.schema)
return compile.call(self, _schema, _root, localRefs, baseId);
var $async = _schema.$async === true;
if ($async && !opts.transpile) async.setTranspile(opts);
var validateCode = validateGenerator({
isTop: true,
schema: _schema,
@ -55,7 +59,7 @@ function compile(schema, root, localRefs, baseId) {
usePattern: usePattern,
useDefault: useDefault,
useCustomRule: useCustomRule,
opts: self._opts,
opts: opts,
formats: formats,
self: self
});
@ -64,21 +68,16 @@ function compile(schema, root, localRefs, baseId) {
+ vars(defaults, defaultCode) + vars(customRules, customRuleCode)
+ validateCode;
if (self._opts.beautify) {
var opts = self._opts.beautify === true ? { indent_size: 2 } : self._opts.beautify;
if (opts.beautify) {
/* istanbul ignore else */
if (beautify) validateCode = beautify(validateCode, opts);
if (beautify) validateCode = beautify(validateCode, opts.beautify);
else console.error('"npm install js-beautify" to use beautify option');
}
// console.log('\n\n\n *** \n', validateCode);
var validate;
var $async = _schema.$async === true;
try {
if ($async) {
var transpile = self._opts.transpile || async.setTranspile(self._opts);
if (typeof transpile == 'function')
validateCode = transpile(validateCode);
}
if ($async && typeof opts.transpile == 'function')
validateCode = opts.transpile(validateCode);
eval(validateCode);
refVal[0] = validate;
} catch(e) {
@ -119,7 +118,7 @@ function compile(schema, root, localRefs, baseId) {
if (!v) {
var localSchema = localRefs && localRefs[ref];
if (localSchema) {
v = resolve.inlineRef(localSchema, self._opts.inlineRefs)
v = resolve.inlineRef(localSchema, opts.inlineRefs)
? localSchema
: compile.call(self, localSchema, root, localRefs, baseId);
}
@ -187,7 +186,7 @@ function compile(schema, root, localRefs, baseId) {
validate = compile.call(self, schema, parentSchema);
else if (macro) {
validate = macro.call(self, schema, parentSchema);
if (self._opts.validateSchema !== false) self.validateSchema(validate, true);
if (opts.validateSchema !== false) self.validateSchema(validate, true);
} else if (inline)
validate = inline.call(self, it, rule.keyword, schema, parentSchema);
else

View File

@ -26,7 +26,7 @@
it.baseId = it.baseId || it.rootId;
if ($async) {
it.async = true;
var $es7 = it.opts.async == 'es7';
var $es7 = it.opts.async.slice(0, 3) == 'es7';
it.yieldAwait = $es7 ? 'await' : 'yield';
}
delete it.isTop;

View File

@ -17,10 +17,12 @@
"test-cov": "istanbul cover -x '**/spec/**' node_modules/mocha/bin/_mocha -- spec/*.spec.js -R spec",
"bundle": "browserify -r ./lib/ajv.js:ajv -o ajv.bundle.js -s Ajv && uglifyjs ajv.bundle.js -o ajv.min.js -c pure_getters -m --source-map ajv.min.js.map -r Ajv --preamble '/* Ajv JSON-schema validator */'",
"bundle-regenerator": "browserify -r ./node_modules/regenerator/main.js:regenerator -o regenerator.bundle.js && uglifyjs regenerator.bundle.js -o regenerator.min.js -c -m --source-map regenerator.min.js.map",
"bundle-nodent": "browserify -r ./node_modules/nodent/nodent.js:nodent -o nodent.bundle.js && uglifyjs nodent.bundle.js -o nodent.min.js -c -m --source-map nodent.min.js.map",
"bundle-all": "npm run bundle && npm run bundle-regenerator && npm run bundle-nodent",
"build": "node scripts/compile-dots.js",
"test-browser": "npm run bundle && npm run bundle-regenerator && scripts/prepare-tests && karma start --single-run --browsers PhantomJS",
"test-browser": "npm run bundle-all && scripts/prepare-tests && karma start --single-run --browsers PhantomJS",
"test": "npm run jshint && npm run build && npm run test-cov && npm run test-browser",
"prepublish": "npm run build && npm run bundle && npm run bundle-regenerator && mkdir -p dist && mv ajv.* dist && mv regenerator.* dist",
"prepublish": "npm run build && npm run bundle-all && mkdir -p dist && mv ajv.* dist && mv regenerator.* dist && mv nodent.* dist",
"watch": "watch 'npm run build' ./lib/dot"
},
"repository": {

View File

@ -26,20 +26,24 @@ describe('async schemas, formats and keywords', function() {
opts = opts || {};
var firstTime = instances === undefined;
instances = [];
[
var options = [
{},
{ allErrors: true },
{ async: 'generators' },
{ async: 'generators', allErrors: true },
// { async: 'es7' }
// , { async: 'es7', allErrors: true },
{ async: 'es7.nodent' },
{ async: 'es7.nodent', allErrors: true },
{ async: 'regenerator' },
{ async: 'regenerator', allErrors: true }
].forEach(function (_opts) {
];
options.forEach(function (_opts) {
util.copy(opts, _opts);
var ajv = getAjv(_opts);
if (ajv) instances.push(ajv);
});
if (firstTime) console.log('Testing', instances.length, 'ajv instances');
}
@ -116,26 +120,27 @@ describe('async schemas, formats and keywords', function() {
it('should fail compilation if async format is inside sync schema', function() {
instances.forEach(test);
function test(ajv) {
var schema1 = {
instances.forEach(function (ajv) {
var schema = {
type: 'string',
format: 'english_word',
minimum: 5
format: 'english_word'
};
shouldThrowFunc('async format in sync schema', function() {
ajv.compile(schema1);
ajv.compile(schema);
})
schema1.$async = true;
ajv.compile(schema1);
}
schema.$async = true;
ajv.compile(schema);
});
});
it('should support async formats when $data ref resolves to async format name', function() {
getInstances({ v5: true });
console.warn('Skipping this test for opts.async = "es7.nodent"');
instances = instances.filter(function (ajv) {
return ajv._opts.async != 'es7.nodent';
});
addFormatEnglishWord();
var schema = {
@ -241,6 +246,28 @@ describe('async schemas, formats and keywords', function() {
});
it('should fail compilation if async keyword is inside sync schema', function() {
instances.forEach(function (ajv) {
var schema = {
type: 'object',
properties: {
userId: {
type: 'integer',
idExists: { table: 'users' }
}
}
};
shouldThrowFunc('async keyword in sync schema', function() {
ajv.compile(schema);
})
schema.$async = true;
ajv.compile(schema);
});
});
function checkIdExists(schema, data) {
switch (schema.table) {
case 'users': return check([1, 5, 8]);