Skip to content

Commit 4c55a27

Browse files
l0b0Mitchell Paff
andcommitted
feat: Add unit tests
Co-authored-by: Mitchell Paff <[email protected]> Co-authored-by: Victor Engmark <[email protected]>
1 parent c0f506b commit 4c55a27

File tree

4 files changed

+123
-1
lines changed

4 files changed

+123
-1
lines changed

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@
22
"name": "stac-extensions",
33
"version": "1.0.0",
44
"scripts": {
5-
"test": "npm run check-markdown && npm run check-examples",
5+
"test": "npx ospec && npm run check-markdown && npm run check-examples",
66
"check-markdown": "remark . -f -r .github/remark.yaml",
77
"check-examples": "stac-node-validator . --lint --verbose --schemaMap https://stac-extensions.github.io/template/v1.0.0/schema.json=./json-schema/schema.json",
88
"format-examples": "stac-node-validator . --format --schemaMap https://stac-extensions.github.io/template/v1.0.0/schema.json=./json-schema/schema.json"
99
},
10+
"type": "module",
1011
"dependencies": {
12+
"@types/ospec": "^4.0.2",
13+
"ospec": "^4.1.1",
1114
"remark-cli": "^8.0.0",
1215
"remark-lint": "^7.0.0",
1316
"remark-lint-no-html": "^2.0.0",

tests/template_collection.test.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import o from 'ospec';
2+
import Ajv from 'ajv';
3+
import { join } from 'path';
4+
import { promises as fs } from 'fs';
5+
import { AjvOptions, rootDirectory, schemaPath } from './validation.js';
6+
7+
const examplePath = join(rootDirectory, 'examples/collection.json');
8+
9+
o.spec('Collection', () => {
10+
let validate;
11+
const ajv = new Ajv(AjvOptions);
12+
13+
o.before(async () => {
14+
const data = JSON.parse(await fs.readFile(schemaPath));
15+
validate = await ajv.compileAsync(data);
16+
});
17+
18+
o('Example should pass validation', async () => {
19+
// given
20+
const example = JSON.parse(await fs.readFile(examplePath));
21+
22+
// when
23+
let valid = validate(example);
24+
25+
// then
26+
o(valid).equals(true)(JSON.stringify(validate.errors, null, 2));
27+
});
28+
29+
o("Non-asset example without mandatory 'template:new_field' field should fail validation", async () => {
30+
// given
31+
const example = JSON.parse(await fs.readFile(examplePath));
32+
delete example['assets'];
33+
delete example['item_assets'];
34+
delete example['template:new_field'];
35+
36+
// when
37+
let valid = validate(example);
38+
39+
// then
40+
o(valid).equals(false);
41+
o(
42+
validate.errors.some((error) => error.message === "should have required property '['template:new_field']'"),
43+
).equals(true)(JSON.stringify(validate.errors));
44+
});
45+
});

tests/template_item.test.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import o from 'ospec';
2+
import Ajv from 'ajv';
3+
import { join } from 'path';
4+
import { promises as fs } from 'fs';
5+
import { AjvOptions, rootDirectory, schemaPath } from './validation.js';
6+
7+
const examplePath = join(rootDirectory, 'examples/item.json');
8+
9+
o.spec('Item', () => {
10+
let validate;
11+
const ajv = new Ajv(AjvOptions);
12+
13+
o.before(async () => {
14+
const data = JSON.parse(await fs.readFile(schemaPath));
15+
validate = await ajv.compileAsync(data);
16+
});
17+
18+
o('Example should pass validation', async () => {
19+
// given
20+
const example = JSON.parse(await fs.readFile(examplePath));
21+
22+
// when
23+
let valid = validate(example);
24+
25+
// then
26+
o(valid).equals(true)(JSON.stringify(validate.errors, null, 2));
27+
});
28+
29+
o("Example without mandatory 'template:new_field' property should fail validation", async () => {
30+
// given
31+
const example = JSON.parse(await fs.readFile(examplePath));
32+
delete example.properties['template:new_field'];
33+
// when
34+
let valid = validate(example);
35+
36+
// then
37+
o(valid).equals(false);
38+
o(
39+
validate.errors.some((error) => error.message === "should have required property '['template:new_field']'"),
40+
).equals(true)(JSON.stringify(validate.errors));
41+
});
42+
});

tests/validation.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import axios from 'axios';
2+
import { dirname, join } from 'path';
3+
import { fileURLToPath } from 'url';
4+
import iriFormats from 'stac-node-validator/iri.js';
5+
6+
const directory = dirname(fileURLToPath(import.meta.url));
7+
8+
const Schemas = new Map();
9+
export function loadSchema(uri) {
10+
let existing = Schemas.get(uri);
11+
if (existing == null) {
12+
existing = loadSchemaFromUri(uri);
13+
Schemas.set(uri, existing);
14+
}
15+
return existing;
16+
}
17+
18+
/**
19+
* function passed in to Ajv instance which allows us to load schemas from a url at run time.
20+
*/
21+
export async function loadSchemaFromUri(uri) {
22+
try {
23+
let response = await axios.get(uri);
24+
return response.data;
25+
} catch (error) {
26+
throw new Error(`-- Schema at '${uri}' not found. Please ensure all entries in 'stac_extensions' are valid.`);
27+
}
28+
}
29+
30+
export const AjvOptions = { loadSchema, formats: Object.assign(iriFormats) };
31+
export const rootDirectory = dirname(directory);
32+
export const schemaPath = join(rootDirectory, 'json-schema/schema.json');

0 commit comments

Comments
 (0)