flow2schema/tests/run.js

113 lines
2.8 KiB
JavaScript
Raw Normal View History

2018-11-21 15:53:15 +03:00
// @flow
2017-11-16 15:17:15 +03:00
import * as assert from 'assert';
import * as fs from 'fs';
import * as path from 'path';
2017-11-30 14:27:05 +03:00
import * as yaml from 'yaml-js';
2017-11-30 17:19:44 +03:00
import wu from 'wu';
import Ajv from 'ajv';
import stringifyJson from 'json-stringify-pretty-compact';
2017-10-29 15:42:46 +03:00
2017-11-16 15:17:15 +03:00
import collect from '../src';
2017-10-29 15:42:46 +03:00
function run(title, generateMissing) {
2017-12-17 02:10:39 +03:00
let actual, expectedTypes, expectedSchema;
2017-11-05 15:39:40 +03:00
// Run the collector only if the suite will be checked.
before(() => {
2017-12-01 20:44:35 +03:00
actual = collect(title + '/source.js');
expectedTypes = readFileAndPrepare(title + '/types.yaml', yaml.load);
expectedSchema = readFileAndPrepare(title + '/schema.json', JSON.parse);
2017-11-05 15:39:40 +03:00
});
2017-11-02 21:52:35 +03:00
2017-11-30 17:19:44 +03:00
it('should not include cycles', () => {
assert.deepEqual(detectCycles(actual.types), new Set);
});
2017-11-28 16:35:28 +03:00
it('should provide expected types', () => {
if (expectedTypes === undefined && generateMissing) {
console.log('Generating types.yaml...');
const content = yaml.dump(actual.types, null, null, {
indent: 4,
width: 100,
}).trimRight();
fs.writeFileSync(title + '/types.yaml', content);
} else {
assert.deepEqual(actual.types, expectedTypes);
}
2017-11-05 12:28:10 +03:00
});
it('should generate valid JSON schema', () => {
const ajv = new Ajv;
ajv.validateSchema(actual.schema);
assert.equal(ajv.errors, null);
});
2017-12-17 02:10:39 +03:00
it('should provide expected JSON schema', () => {
if (expectedSchema === undefined && generateMissing) {
console.log('Generating schema.json...');
const content = stringifyJson(actual.schema, {
indent: 4,
maxLength: 100,
});
fs.writeFileSync(title + '/schema.json', content);
} else {
assert.deepEqual(actual.schema, expectedSchema);
}
2017-12-17 02:10:39 +03:00
});
2017-11-05 00:44:25 +03:00
}
function readFileAndPrepare<R>(path: string, prepare: string => R): R | void {
let data;
try {
data = fs.readFileSync(path, 'utf8');
} catch (ex) {
if (ex.code === 'ENOENT') {
return undefined;
}
throw ex;
}
return prepare(data);
}
2017-11-30 17:19:44 +03:00
function detectCycles(obj: mixed, cycles: Set<mixed> = new Set, objs: Set<mixed> = new Set) {
if (obj == null || typeof obj !== 'object') {
return cycles;
}
if (objs.has(obj)) {
cycles.add(obj);
}
objs.add(obj);
if (obj instanceof Array) {
wu(obj).forEach(item => detectCycles(item, cycles, objs));
} else {
wu.values(obj).forEach(item => detectCycles(item, cycles, objs));
}
return cycles;
}
2017-11-05 00:44:25 +03:00
function main() {
2017-11-16 15:17:15 +03:00
process.chdir(path.join(__dirname, 'samples'));
2017-11-05 00:44:25 +03:00
const generateMissing = process.env.GENERATE_MISSING === '1';
2017-12-01 20:44:35 +03:00
for (const title of fs.readdirSync('.')) {
describe(title, () => run(title, generateMissing));
2017-12-01 20:44:35 +03:00
}
2017-10-29 15:42:46 +03:00
}
2017-11-05 00:44:25 +03:00
main();