From 3977b92a56295ba5ce1fc3b51bd1fcb59518848a Mon Sep 17 00:00:00 2001 From: Alexander Zech Date: Wed, 30 Aug 2023 18:15:42 -0700 Subject: [PATCH 01/11] chore: increase timeout for before hook --- tests/utils/yaml.combine.tests.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/utils/yaml.combine.tests.ts b/tests/utils/yaml.combine.tests.ts index 5a4f96b2..2fe2f3ef 100644 --- a/tests/utils/yaml.combine.tests.ts +++ b/tests/utils/yaml.combine.tests.ts @@ -1,7 +1,7 @@ /* eslint-disable no-unused-expressions */ // @ts-nocheck import { expect } from "chai"; -import fs from "fs"; +import fs from "fs/promises"; import yaml from "js-yaml"; import lodash from "lodash"; @@ -13,8 +13,10 @@ const combineSchema = yaml.DEFAULT_SCHEMA.extend([combineType, esseType]); describe("YAML tag: !combine", () => { let yamlFixture; - before(() => { - yamlFixture = fs.readFileSync(YAML_COMBINE_FILE, "utf8"); + // eslint-disable-next-line func-names + before(async function () { + this.timeout(5000); + yamlFixture = await fs.readFile(YAML_COMBINE_FILE, "utf8"); }); it("should correctly parse a custom !combine tag with forEach and config keys", () => { From 1198dac010c3020c382e275eb90a5105bf1c1b35 Mon Sep 17 00:00:00 2001 From: Alexander Zech Date: Wed, 30 Aug 2023 18:19:32 -0700 Subject: [PATCH 02/11] chore: remove fs/promises for compatibility with node 12 --- tests/utils/yaml.combine.tests.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/utils/yaml.combine.tests.ts b/tests/utils/yaml.combine.tests.ts index 2fe2f3ef..b6f7a2b6 100644 --- a/tests/utils/yaml.combine.tests.ts +++ b/tests/utils/yaml.combine.tests.ts @@ -1,7 +1,7 @@ /* eslint-disable no-unused-expressions */ // @ts-nocheck import { expect } from "chai"; -import fs from "fs/promises"; +import fs from "fs"; import yaml from "js-yaml"; import lodash from "lodash"; @@ -13,10 +13,9 @@ const combineSchema = yaml.DEFAULT_SCHEMA.extend([combineType, esseType]); describe("YAML tag: !combine", () => { let yamlFixture; - // eslint-disable-next-line func-names - before(async function () { + before(() => { this.timeout(5000); - yamlFixture = await fs.readFile(YAML_COMBINE_FILE, "utf8"); + yamlFixture = fs.readFileSync(YAML_COMBINE_FILE, "utf8"); }); it("should correctly parse a custom !combine tag with forEach and config keys", () => { From 3a6b356e0e06b8e0962ad57add80b005681fd846 Mon Sep 17 00:00:00 2001 From: Alexander Zech Date: Wed, 30 Aug 2023 18:29:33 -0700 Subject: [PATCH 03/11] fix: avoid arrow function for this.timeout --- tests/utils/yaml.combine.tests.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/utils/yaml.combine.tests.ts b/tests/utils/yaml.combine.tests.ts index b6f7a2b6..98c68b49 100644 --- a/tests/utils/yaml.combine.tests.ts +++ b/tests/utils/yaml.combine.tests.ts @@ -13,7 +13,8 @@ const combineSchema = yaml.DEFAULT_SCHEMA.extend([combineType, esseType]); describe("YAML tag: !combine", () => { let yamlFixture; - before(() => { + // eslint-disable-next-line func-names + before(function () { this.timeout(5000); yamlFixture = fs.readFileSync(YAML_COMBINE_FILE, "utf8"); }); From ffab1f5c4d9e74be4e1b6d575c216299bad9bb42 Mon Sep 17 00:00:00 2001 From: Alexander Zech Date: Thu, 31 Aug 2023 13:14:56 -0700 Subject: [PATCH 04/11] chore: rename fixture schemas.js -> rjsf_schemas.js --- tests/fixtures/{schemas.js => rjsf_schemas.js} | 0 tests/utils/schemas.tests.ts | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/fixtures/{schemas.js => rjsf_schemas.js} (100%) diff --git a/tests/fixtures/schemas.js b/tests/fixtures/rjsf_schemas.js similarity index 100% rename from tests/fixtures/schemas.js rename to tests/fixtures/rjsf_schemas.js diff --git a/tests/utils/schemas.tests.ts b/tests/utils/schemas.tests.ts index 86304d22..44d5f3ef 100644 --- a/tests/utils/schemas.tests.ts +++ b/tests/utils/schemas.tests.ts @@ -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", () => { From 7e7358dc7da13ad1974f9bca046920250584bfe3 Mon Sep 17 00:00:00 2001 From: Alexander Zech Date: Thu, 31 Aug 2023 13:18:07 -0700 Subject: [PATCH 05/11] docs: update JSDoc for registerGlobalSchema --- src/JSONSchemasInterface.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/JSONSchemasInterface.ts b/src/JSONSchemasInterface.ts index 4b5ddb22..60550fe3 100644 --- a/src/JSONSchemasInterface.ts +++ b/src/JSONSchemasInterface.ts @@ -78,7 +78,7 @@ export class JSONSchemasInterface { /** * - * @param {Object} - external schema + * @param globalSchema */ static registerGlobalSchema(globalSchema: JSONSchema) { if (JSONSchemasInterface._schema === globalSchema) { From 735ae747a3475302c18b1ce0137a2037b2d46b07 Mon Sep 17 00:00:00 2001 From: Alexander Zech Date: Thu, 31 Aug 2023 13:18:40 -0700 Subject: [PATCH 06/11] chore: add wrapper for registerGlobalSchema --- src/JSONSchemasInterface.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/JSONSchemasInterface.ts b/src/JSONSchemasInterface.ts index 60550fe3..4482066e 100644 --- a/src/JSONSchemasInterface.ts +++ b/src/JSONSchemasInterface.ts @@ -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); + } + } } From a2af722f5515325eba52298373bd5a7457b7a745 Mon Sep 17 00:00:00 2001 From: Alexander Zech Date: Thu, 31 Aug 2023 15:44:07 -0700 Subject: [PATCH 07/11] test: add mock global schema --- tests/fixtures/mock_esse_schema.js | 97 ++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 tests/fixtures/mock_esse_schema.js diff --git a/tests/fixtures/mock_esse_schema.js b/tests/fixtures/mock_esse_schema.js new file mode 100644 index 00000000..4a8d64dc --- /dev/null +++ b/tests/fixtures/mock_esse_schema.js @@ -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", + }, + }, + }, + }, + }, +}; From 7613498b2c3ebb3794a840a87f03c9711346372a Mon Sep 17 00:00:00 2001 From: Alexander Zech Date: Thu, 31 Aug 2023 15:45:52 -0700 Subject: [PATCH 08/11] chore: adjust schema registration in esse yaml tag --- src/utils/yaml.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/yaml.ts b/src/utils/yaml.ts index d5d0db4e..cdcf2449 100644 --- a/src/utils/yaml.ts +++ b/src/utils/yaml.ts @@ -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) { From 4f475f50a85e7439a31bc564143c876b74c4ece2 Mon Sep 17 00:00:00 2001 From: Alexander Zech Date: Thu, 31 Aug 2023 15:49:26 -0700 Subject: [PATCH 09/11] test: run yaml load in before hook --- tests/utils/yaml.combine.tests.ts | 23 ++--------------------- tests/utils/yaml.esse.tests.ts | 13 +++++++------ 2 files changed, 9 insertions(+), 27 deletions(-) diff --git a/tests/utils/yaml.combine.tests.ts b/tests/utils/yaml.combine.tests.ts index 98c68b49..53f2367c 100644 --- a/tests/utils/yaml.combine.tests.ts +++ b/tests/utils/yaml.combine.tests.ts @@ -12,15 +12,16 @@ const combineSchema = yaml.DEFAULT_SCHEMA.extend([combineType, esseType]); describe("YAML tag: !combine", () => { let yamlFixture; + let parsed; // eslint-disable-next-line func-names before(function () { this.timeout(5000); 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 }, @@ -32,72 +33,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 }, @@ -106,19 +92,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 }] }, @@ -136,7 +118,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 diff --git a/tests/utils/yaml.esse.tests.ts b/tests/utils/yaml.esse.tests.ts index ec46e9fb..2dae3ebd 100644 --- a/tests/utils/yaml.esse.tests.ts +++ b/tests/utils/yaml.esse.tests.ts @@ -9,10 +9,15 @@ import { YAML_ESSE_FILE } from "../enums"; const yamlSchema = yaml.DEFAULT_SCHEMA.extend([esseType]); describe("YAML tag: !esse", () => { - const yamlFixture = fs.readFileSync(YAML_ESSE_FILE, "utf8"); + let yamlFixture; + let parsed; + + before(() => { + 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#", @@ -29,24 +34,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); }); From a0bd59b1e43edb0dad560be174660a01ee97cf08 Mon Sep 17 00:00:00 2001 From: Alexander Zech Date: Thu, 31 Aug 2023 15:50:09 -0700 Subject: [PATCH 10/11] test: register global schema in before hook --- tests/utils/yaml.combine.tests.ts | 7 ++++--- tests/utils/yaml.esse.tests.ts | 3 +++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/utils/yaml.combine.tests.ts b/tests/utils/yaml.combine.tests.ts index 53f2367c..51f3bbc5 100644 --- a/tests/utils/yaml.combine.tests.ts +++ b/tests/utils/yaml.combine.tests.ts @@ -5,8 +5,10 @@ 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]); @@ -14,9 +16,8 @@ describe("YAML tag: !combine", () => { let yamlFixture; let parsed; - // eslint-disable-next-line func-names - before(function () { - this.timeout(5000); + before(() => { + JSONSchemasInterface.registerGlobalSchema(MOCK_GLOBAL_SCHEMA); yamlFixture = fs.readFileSync(YAML_COMBINE_FILE, "utf8"); parsed = yaml.load(yamlFixture, { schema: combineSchema }); }); diff --git a/tests/utils/yaml.esse.tests.ts b/tests/utils/yaml.esse.tests.ts index 2dae3ebd..21ea2cc3 100644 --- a/tests/utils/yaml.esse.tests.ts +++ b/tests/utils/yaml.esse.tests.ts @@ -3,8 +3,10 @@ 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]); @@ -13,6 +15,7 @@ describe("YAML tag: !esse", () => { let parsed; before(() => { + JSONSchemasInterface.registerGlobalSchema(MOCK_GLOBAL_SCHEMA); yamlFixture = fs.readFileSync(YAML_ESSE_FILE, "utf8"); parsed = yaml.load(yamlFixture, { schema: yamlSchema }); }); From 2903c59e6de2b9b9c38c0bddbb41ef10c81cd576 Mon Sep 17 00:00:00 2001 From: Alexander Zech Date: Thu, 31 Aug 2023 15:50:50 -0700 Subject: [PATCH 11/11] chore: adjust import for path module --- tests/enums.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/enums.ts b/tests/enums.ts index cb343f90..34123d97 100644 --- a/tests/enums.ts +++ b/tests/enums.ts @@ -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");