All files index.spec.js

31.53% Statements 35/111
50% Branches 1/2
0% Functions 0/2
31.53% Lines 35/111

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 1121x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x                           1x 1x   1x 1x 1x 1x 1x 1x 1x 1x 1x       1x 1x 1x 1x                                               1x 1x 1x                                                                          
/**
 * @license
 * Copyright 2022 Open Ag Data Alliance
 *
 * Use of this source code is governed by an MIT-style
 * license that can be found in the LICENSE file or at
 * https://opensource.org/licenses/MIT.
 */
import test from 'ava';
import { dirname, isAbsolute, join, relative } from 'node:path';
import $RefParser from '@apidevtools/json-schema-ref-parser';
import Ajv from 'ajv';
import schemas, { requireSchema } from './';
/**
 * @todo where should this live?
 */
export function loadSchema(uri) {
    const r = /^https:\/\/formats\.openag\.io/i;
    if (r.test(uri)) {
        // Use local version of openag schemas
        const file = uri.replace(r, '.').replace(/\.json$/, '');
        return requireSchema(file);
    }
    throw new Error(`Unknown schema URI: ${uri}`);
    /*
      // Try to fetch schema online
      const { data: schema } = await axios.get<Schema>(uri);
      return schema;
       */
}
const ajv = new Ajv({
    async loadSchema(uri) {
        return loadSchema(uri);
    },
    /* ProcessCode, */
    inlineRefs: false,
    allErrors: true,
    strict: false,
    // AJV complains about standard formats if this is on
    validateFormats: false,
});
test.before('Initialize JSON Schema validator', async () => {
    const meta = await $RefParser.dereference('https://json-schema.org/draft/2019-09/schema');
    // ???: Why does compileAsync not work for meta schema?
    ajv.addMetaSchema(meta);
});
// FIXME: Figure out less hacky way to make it find the files correctly
let checkReferences;
test.before('Initialize $ref checker', () => {
    checkReferences = async (key, schema) => {
        const $refparser = new $RefParser();
        return $refparser.dereference(schema, {
            resolve: {
                file: {
                    order: 0,
                    canRead: true,
                    // TODO: Support external $ref
                    async read({ url }) {
                        const r = /^https:\/\/formats\.openag\.io/;
                        const directory = '.';
                        const path = url.startsWith('https://formats.openag.io')
                            ? url.replace(r, '')
                            : relative('', url);
                        const file = (isAbsolute(path)
                            ? join(directory, path)
                            : join(directory, dirname(key), path)).replace(/\.json$/, '');
                        return requireSchema(file);
                    },
                },
            },
        });
    };
});
// TODO: Can you make these parallel in ava?
for (const { schema, key } of schemas()) {
    test.before(`Compile schema ${key}`, async () => {
        try {
            await ajv.compileAsync(schema);
        }
        catch {
            // Already compiled?
        }
    });
    test(`${key} should be valid JSON Schema`, async (t) => {
        t.assert(ajv.validateSchema(schema));
    });
    // $id needs to be consistent with file structure or most tools get upset
    test(`${key} should have consistent $id`, async (t) => {
        const { $id } = schema;
        t.is($id, `https://${join('formats.openag.io/', key)}`);
    });
    test.todo(`${key} should have valid self $ref's`);
    test(`${key} should have valid external $ref's`, async (t) => {
        await t.notThrowsAsync(checkReferences(key, schema));
    });
    test(`${key} should have valid default`, async (t) => {
        // eslint-disable-next-line unicorn/prevent-abbreviations
        const { default: def } = schema;
        t.plan(def ? 1 : 0);
        if (def) {
            t.assert(ajv.validate(schema, def), ajv.errorsText());
        }
    });
    test(`${key} should validate examples`, async (t) => {
        const { examples = [] } = schema;
        t.plan(examples?.length ?? 0);
        for (const example of examples) {
            t.assert(ajv.validate(schema, example), ajv.errorsText());
        }
    });
}