Skip to content
Merged
12 changes: 11 additions & 1 deletion src/JSONSchemasInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export class JSONSchemasInterface {

/**
*
* @param {Object} - external schema
* @param globalSchema
*/
static registerGlobalSchema(globalSchema: JSONSchema) {
if (JSONSchemasInterface._schema === globalSchema) {
Expand Down Expand Up @@ -159,4 +159,14 @@ export class JSONSchemasInterface {
}
return ajv.compile(schema);
}

/**
* Register global schema only if none has been registered yet.
* @param globalSchema
*/
static registerGlobalSchemaIfEmpty(globalSchema: JSONSchema) {
if (!JSONSchemasInterface._schema) {
JSONSchemasInterface.registerGlobalSchema(globalSchema);
}
}
}
2 changes: 1 addition & 1 deletion src/utils/yaml.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ export const esseType = new yaml.Type("!esse", {
},
construct(data) {
try {
JSONSchemasInterface.registerGlobalSchema(esseSchema);
JSONSchemasInterface.registerGlobalSchemaIfEmpty(esseSchema);
const { filePath: schemaId, objPath } = splitReference(data);
const schema = JSONSchemasInterface.schemaById(schemaId);
if (objPath) {
Expand Down
2 changes: 1 addition & 1 deletion tests/enums.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import path from "path";
import * as path from "path";

export const FIXTURES_DIR = path.resolve(__dirname, "./fixtures");
export const YAML_COMBINE_FILE = path.resolve(FIXTURES_DIR, "yaml_combine_tag.yml");
Expand Down
97 changes: 97 additions & 0 deletions tests/fixtures/mock_esse_schema.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
export const MOCK_GLOBAL_SCHEMA = {
$id: "esse-global-schema",
$schema: "http://json-schema.org/draft-04/schema#",
title: "Global schema",
type: "object",
definitions: {
"core:primitive:scalar": {
$id: "core/primitive/scalar",
$schema: "http://json-schema.org/draft-04/schema#",
title: "scalar schema",
type: "object",
required: ["value"],
properties: {
value: {
type: "number",
},
},
},
"definitions:units": {
$id: "definitions/units",
pressure: {
enum: ["kbar", "pa"],
},
},
"core:abstract::d-data": {
$id: "core/abstract/2d-data",
$schema: "http://json-schema.org/draft-04/schema#",
title: "2 dimension data schema",
type: "object",
properties: {
xDataArray: {
description: "array containing values of x Axis",
type: "array",
},
yDataSeries: {
$ref: "#/definitions/core:primitive::d-data-series",
},
},
required: ["xDataArray", "yDataSeries"],
},
"core:primitive::d-data-series": {
$id: "core/primitive/1d-data-series",
$schema: "http://json-schema.org/draft-04/schema#",
title: "1 dimension data series schema",
type: "array",
items: {
type: "array",
minItems: 1,
items: {
type: ["number", "string"],
},
},
},
"methods-directory:physical:pw": {
$id: "methods-directory/physical/pw",
$schema: "http://json-schema.org/draft-04/schema#",
title: "Plane wave method unit schema",
description: "Approximating the electronic wave function with a plane wave basis",
type: "object",
properties: {
name: {
type: "string",
},
categories: {
properties: {
tier1: {
description: "top-level category",
type: "string",
},
tier2: {
description: "second level category",
type: "string",
},
tier3: {
description: "third level category",
type: "string",
},
type: {
description: "general type of the entity",
type: "string",
},
subtype: {
description: "general subtype of the entity",
type: "string",
},
},
},
tags: {
type: "array",
items: {
type: "string",
},
},
},
},
},
};
File renamed without changes.
2 changes: 1 addition & 1 deletion tests/utils/schemas.tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
TREE_SIMPLE,
TREE_STATIC_TERMINAL,
UNEVEN_TREE,
} from "../fixtures/schemas";
} from "../fixtures/rjsf_schemas";

describe("RJSF schema", () => {
it("dependencies block can be created from tree", () => {
Expand Down
26 changes: 5 additions & 21 deletions tests/utils/yaml.combine.tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,24 @@ import fs from "fs";
import yaml from "js-yaml";
import lodash from "lodash";

import { JSONSchemasInterface } from "../../src/JSONSchemasInterface";
import { combineType, esseType } from "../../src/utils/yaml";
import { YAML_COMBINE_FILE } from "../enums";
import { MOCK_GLOBAL_SCHEMA } from "../fixtures/mock_esse_schema";

const combineSchema = yaml.DEFAULT_SCHEMA.extend([combineType, esseType]);

describe("YAML tag: !combine", () => {
let yamlFixture;
let parsed;

before(() => {
JSONSchemasInterface.registerGlobalSchema(MOCK_GLOBAL_SCHEMA);
yamlFixture = fs.readFileSync(YAML_COMBINE_FILE, "utf8");
parsed = yaml.load(yamlFixture, { schema: combineSchema });
});

it("should correctly parse a custom !combine tag with forEach and config keys", () => {
const parsed = yaml.load(yamlFixture, { schema: combineSchema });
const expectedResult = [
{ name: "mytest", a: 1, b: 3, c: 5 },
{ name: "mytest", a: 1, b: 4, c: 5 },
Expand All @@ -30,72 +34,57 @@ describe("YAML tag: !combine", () => {
});

it("should correctly parse a custom !combine tag with only a name key", () => {
const parsed = yaml.load(yamlFixture, { schema: combineSchema });
const expectedResult = [{ name: "mytest" }];

expect(parsed.case2).to.have.deep.members(expectedResult);
});

it("should correctly parse a custom !combine tag with forEach key and no values", () => {
const parsed = yaml.load(yamlFixture, { schema: combineSchema });
const expectedResult = [{ name: "mytest" }];

expect(parsed.case3).to.have.deep.members(expectedResult);
});

it("should correctly parse a custom !combine tag with an empty forEach key and a config key", () => {
const parsed = yaml.load(yamlFixture, { schema: combineSchema });
const expectedResult = [{ name: "mytest", c: 5 }];

expect(parsed.case4).to.have.deep.members(expectedResult);
});

it("should correctly generate name based on template", () => {
const parsed = yaml.load(yamlFixture, { schema: combineSchema });
const expectedResult = [
{ name: "A1 with B2 and C5", a: 1, b: "two", c: 5 },
{ name: "A1 with B4 and C5", a: 1, b: "four", c: 5 },
];

expect(parsed.case5).to.have.deep.members(expectedResult);
});

it("should correctly parse a custom !combine tag with additional property", () => {
const parsed = yaml.load(yamlFixture, { schema: combineSchema });
const expectedResult = [
{ name: "mytest", a: 1, b: 3 },
{ name: "mytest", a: 1, b: 4 },
{ name: "additional property", x: 7 },
];

expect(parsed.case6).to.have.deep.members(expectedResult);
});

it("should correctly parse a custom !combine tag with additional property from !combine tag", () => {
const parsed = yaml.load(yamlFixture, { schema: combineSchema });
const expectedResult = [
{ name: "mytest", a: 1, b: 3 },
{ name: "mytest", a: 1, b: 4 },
{ name: "additional property", x: 7, y: 9 },
{ name: "additional property", x: 8, y: 9 },
];

expect(parsed.case7).to.have.deep.members(expectedResult);
});

it("should create an additional config when falsy parameter is provided", () => {
const parsed = yaml.load(yamlFixture, { schema: combineSchema });
const expectedResult = [
{ name: "A1 with B2", a: 1, b: "two" },
{ name: "A1 with B4", a: 1, b: "four" },
{ name: "A1", a: 1 },
];

expect(parsed.case8).to.have.deep.members(expectedResult);
});

it("should create all combinations of n optional parameters", () => {
const parsed = yaml.load(yamlFixture, { schema: combineSchema });
const expectedResult = [
{ name: "optional params", a: 1 },
{ name: "optional params", a: 1, b: 2 },
Expand All @@ -104,19 +93,15 @@ describe("YAML tag: !combine", () => {
{ name: "optional params", a: 1, b: 2, c: 4 },
{ name: "optional params", a: 1, b: 3, c: 4 },
];

expect(parsed.case9).to.have.deep.members(expectedResult);
});

it("should allow to exclude certain parameter-specified combinations", () => {
const parsed = yaml.load(yamlFixture, { schema: combineSchema });
const expectedResult = [{ name: "ignore test", a: { c: 3 }, d: 4 }];

expect(parsed.case10).to.have.deep.members(expectedResult);
});

it("should use the push action to add value to an array parameter", () => {
const parsed = yaml.load(yamlFixture, { schema: combineSchema });
const expectedResult = [
{ name: "push test", units: [{ a: 1 }, { b: 4 }] },
{ name: "push test", units: [{ a: 2 }, { b: 4 }] },
Expand All @@ -134,7 +119,6 @@ describe("YAML tag: !combine", () => {
});

it("should use cloned objects when pushing to array", () => {
const parsed = yaml.load(yamlFixture, { schema: combineSchema });
const [config1, config2] = parsed.case12;

// deleting property in one should not affect the other
Expand Down
16 changes: 10 additions & 6 deletions tests/utils/yaml.esse.tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,24 @@ import { expect } from "chai";
import fs from "fs";
import yaml from "js-yaml";

import { JSONSchemasInterface } from "../../src/JSONSchemasInterface";
import { esseType } from "../../src/utils/yaml";
import { YAML_ESSE_FILE } from "../enums";
import { MOCK_GLOBAL_SCHEMA } from "../fixtures/mock_esse_schema";

const yamlSchema = yaml.DEFAULT_SCHEMA.extend([esseType]);

describe("YAML tag: !esse", () => {
const yamlFixture = fs.readFileSync(YAML_ESSE_FILE, "utf8");
let yamlFixture;
let parsed;

before(() => {
JSONSchemasInterface.registerGlobalSchema(MOCK_GLOBAL_SCHEMA);
yamlFixture = fs.readFileSync(YAML_ESSE_FILE, "utf8");
parsed = yaml.load(yamlFixture, { schema: yamlSchema });
});

it("should correctly parse a custom !esse tag and return ESSE schema", () => {
const parsed = yaml.load(yamlFixture, { schema: yamlSchema });
const expected = {
$id: "core/primitive/scalar",
$schema: "http://json-schema.org/draft-04/schema#",
Expand All @@ -29,24 +37,20 @@ describe("YAML tag: !esse", () => {
});

it("should return the original data when an error occurs", () => {
const parsed = yaml.load(yamlFixture, { schema: yamlSchema });
expect(parsed.case2).to.be.equal("non-existent-schema-id");
});

it("should parse a custom !esse tag and return a value from the ESSE schema", () => {
const parsed = yaml.load(yamlFixture, { schema: yamlSchema });
const expected = ["kbar", "pa"];
expect(parsed.case3).to.have.deep.members(expected);
});

it("should correctly return nested value from esse schema", () => {
const parsed = yaml.load(yamlFixture, { schema: yamlSchema });
const expected = "array containing values of x Axis";
expect(parsed.case4).to.be.eql(expected);
});

it("should correctly return array item from esse schema", () => {
const parsed = yaml.load(yamlFixture, { schema: yamlSchema });
const expected = "yDataSeries";
expect(parsed.case5).to.be.eql(expected);
});
Expand Down