Skip to content

Commit

Permalink
Fix: Eval as boolean (#619)
Browse files Browse the repository at this point in the history
* fix: eval as boolean

* undefined check

* add a test

* remove foreign file

* restore

* better

* use typeof

* add test with helper

* save stuff

* save data

* fix
  • Loading branch information
XVincentX committed Dec 1, 2020
1 parent 2e5c9f3 commit 50eb15f
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 88 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "JSON-Schema + fake data generators",
"homepage": "http://json-schema-faker.js.org",
"bin": {
"jsf": "./bin/gen.js"
"jsf": "bin/gen.js"
},
"main": "dist/main.cjs.js",
"module": "dist/main.esm.js",
Expand Down
25 changes: 14 additions & 11 deletions src/lib/types/array.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,25 +61,28 @@ function arrayType(value, path, resolve, traverseCallback) {
let minItems = value.minItems;
let maxItems = value.maxItems;

if (optionAPI('minItems')) {
const defaultMinItems = optionAPI('minItems');
const defaultMaxItems = optionAPI('maxItems');

if (defaultMinItems) {
// fix boundaries
minItems = !maxItems
? optionAPI('minItems')
: Math.min(optionAPI('minItems'), maxItems);
minItems = typeof maxItems === 'undefined'
? defaultMinItems
: Math.min(defaultMinItems, maxItems);
}

if (optionAPI('maxItems')) {
maxItems = !minItems
? optionAPI('maxItems')
: Math.min(optionAPI('maxItems'), minItems);
if (defaultMaxItems) {
maxItems = typeof minItems === 'undefined'
? defaultMaxItems
: Math.min(defaultMaxItems, minItems);

// Don't allow user to set max items above our maximum
if (maxItems && maxItems > optionAPI('maxItems')) {
maxItems = optionAPI('maxItems');
if (maxItems && maxItems > defaultMaxItems) {
maxItems = defaultMaxItems;
}

// Don't allow user to set min items above our maximum
if (minItems && minItems > optionAPI('maxItems')) {
if (minItems && minItems > defaultMaxItems) {
minItems = maxItems;
}
}
Expand Down
19 changes: 19 additions & 0 deletions tests/schema/core/types/array.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,25 @@
},
"equal": [1, 1, 1, 1, 1, 1, 1]
},
{
"description": "should handle minItems and maxItems passed as arguments to JSF, and minItems is 0",
"schema": {
"type": "array",
"items": {
"type": "integer",
"default": 1
},
"minItems": 0,
"maxItems": 5
},
"valid": true,
"set": {
"minItems": 7,
"maxItems": 7,
"useDefaultValue": true
},
"lessThan": 7
},
{
"description": "should handle uniqueItems",
"schema": {
Expand Down
156 changes: 80 additions & 76 deletions tests/schema/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,101 +61,105 @@ export function getTests(srcDir) {

export function tryTest(nth, max, test, refs, schema) {
return Promise.resolve()
.then(() => _jsf[test.sync ? 'generate' : 'resolve'](schema, refs))
.then(sample => {
if (test.dump) {
console.log(JSON.stringify(sample, null, 2));
.then(() => _jsf[test.sync ? 'generate' : 'resolve'](schema, refs))
.then(sample => {
if (test.dump) {
console.log(JSON.stringify(sample, null, 2));

if (test.dump === 'bail') {
return;
if (test.dump === 'bail') {
return;
}
}
}

try {
if (test.type) {
checkType(sample, test.type);
}
try {
if (test.type) {
checkType(sample, test.type);
}

if (test.valid) {
checkSchema(sample, schema, refs);
}
} catch (e) {
const _e = new Error(`${e.message.split('\n')[0]} (${nth} of ${max})`);
if (test.valid) {
checkSchema(sample, schema, refs);
}
} catch (e) {
const _e = new Error(`${e.message.split('\n')[0]} (${nth} of ${max})`);

_e.stack = e.stack.split('\n').slice(1).join('\n');
_e.stack = e.stack.split('\n').slice(1).join('\n');

throw _e;
}
throw _e;
}

if (test.check) {
checkSchema(sample, test.check, refs);
}
if (test.check) {
checkSchema(sample, test.check, refs);
}

if (test.length) {
expect(sample.length).to.eql(test.length);
}
if (test.length) {
expect(sample.length).to.eql(test.length);
}

if (test.notEmpty) {
test.notEmpty.forEach(objectPath => {
const value = pick(sample, objectPath);
if (test.notEmpty) {
test.notEmpty.forEach(objectPath => {
const value = pick(sample, objectPath);

if (value === undefined || (Array.isArray(value) && !value.length)) {
throw new Error(`${objectPath} should not be empty`);
}
});
}
if (value === undefined || (Array.isArray(value) && !value.length)) {
throw new Error(`${objectPath} should not be empty`);
}
});
}

if (test.hasProps) {
test.hasProps.forEach(prop => {
if (Array.isArray(sample)) {
sample.forEach(s => {
if (typeof pick(s, prop) === 'undefined') {
throw new Error(`Property '${prop}' is not present`);
}
});
} else if (typeof pick(sample, prop) === 'undefined') {
throw new Error(`Property '${prop}' is not present`);
}
});
}
if (test.hasProps) {
test.hasProps.forEach(prop => {
if (Array.isArray(sample)) {
sample.forEach(s => {
if (typeof pick(s, prop) === 'undefined') {
throw new Error(`Property '${prop}' is not present`);
}
});
} else if (typeof pick(sample, prop) === 'undefined') {
throw new Error(`Property '${prop}' is not present`);
}
});
}

if (test.onlyProps) {
expect(Object.keys(sample).sort()).to.eql(test.onlyProps.sort());
}
if (test.onlyProps) {
expect(Object.keys(sample).sort()).to.eql(test.onlyProps.sort());
}

if (test.count) {
expect((Array.isArray(sample) ? sample : Object.keys(sample)).length).to.eql(test.count);
}
if (test.count) {
expect((Array.isArray(sample) ? sample : Object.keys(sample)).length).to.eql(test.count);
}

if (test.hasNot) {
expect(JSON.stringify(sample)).not.to.contain(test.hasNot);
}
if (test.lessThan) {
expect(sample.length).to.be.below(test.lessThan);
}

if ('equal' in test) {
expect(sample).to.eql(test.equal);
}
if (test.hasNot) {
expect(JSON.stringify(sample)).not.to.contain(test.hasNot);
}

if (test.throws) {
delete test.throws;
if ('equal' in test) {
expect(sample).to.eql(test.equal);
}

const message = typeof test.throws === 'string' ? `: "${test.throws}"` : '';
if (test.throws) {
delete test.throws;

throw new Error(`Expected test to throw${message}`);
}
}).catch(error => {
const throwsValue = test.throws || test.throwsSometimes;
const message = typeof test.throws === 'string' ? `: "${test.throws}"` : '';

if (typeof throwsValue === 'string') {
expect(error).to.match(new RegExp(throwsValue, 'im'));
test.throwCount++;
return;
}
throw new Error(`Expected test to throw${message}`);
}
}).catch(error => {
const throwsValue = test.throws || test.throwsSometimes;

if (throwsValue === true) {
test.throwCount++;
return;
}
if (typeof throwsValue === 'string') {
expect(error).to.match(new RegExp(throwsValue, 'im'));
test.throwCount++;
return;
}

throw error;
});
if (throwsValue === true) {
test.throwCount++;
return;
}

throw error;
});
}

0 comments on commit 50eb15f

Please sign in to comment.