Skip to content

Commit 00b9a0b

Browse files
committed
chore: fix merge conflicts
2 parents b514d7b + 4ce829a commit 00b9a0b

File tree

9 files changed

+230
-30
lines changed

9 files changed

+230
-30
lines changed

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/JSONSchemasInterface.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ export class JSONSchemasInterface {
2424
return schemasCache.get(schemaId);
2525
}
2626

27+
/**
28+
*
29+
* @param {Object} - external schema
30+
*/
31+
static registerSchema(schema) {
32+
schemasCache.set(schema.schemaId, schema);
33+
}
34+
2735
/**
2836
* @example <caption>Search by schemaId regex</caption>
2937
* JSONSchemasInterface.matchSchema({

src/context/index.js

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,32 @@
11
import { JSONSchemaFormDataProvider } from "./json_schema_provider";
22
import {
3-
ApplicationContextMixinBuilder,
3+
ApplicationContextMixin,
44
JobContextMixin,
5-
MaterialContextMixinBuilder,
6-
MaterialsContextMixinBuilder,
5+
MaterialContextMixin,
6+
MaterialsContextMixin,
77
MaterialsSetContextMixin,
88
MethodDataContextMixin,
99
WorkflowContextMixin,
1010
} from "./mixins";
1111
import { JobContextPickKeysForMixin, WorkflowContextPickKeysForMixin } from "./pickers";
1212
import { ContextProvider } from "./provider";
13-
import { ContextProviderRegistryContainer } from "./registry";
13+
import {
14+
ContextProviderRegistryContainer,
15+
createAndPatchRegistry,
16+
extendAndPatchRegistry,
17+
} from "./registry";
1418

1519
export {
1620
ContextProvider,
1721
ContextProviderRegistryContainer,
22+
extendAndPatchRegistry,
23+
createAndPatchRegistry,
1824
JobContextPickKeysForMixin,
1925
JSONSchemaFormDataProvider,
2026
WorkflowContextPickKeysForMixin,
21-
ApplicationContextMixinBuilder,
22-
MaterialContextMixinBuilder,
23-
MaterialsContextMixinBuilder,
27+
ApplicationContextMixin,
28+
MaterialContextMixin,
29+
MaterialsContextMixin,
2430
MaterialsSetContextMixin,
2531
MethodDataContextMixin,
2632
JobContextMixin,

src/context/mixins.js

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,31 @@ import CryptoJS from "crypto-js";
33

44
import { compareEntitiesInOrderedSetForSorting } from "../entity/set/ordered/utils";
55

6-
export const ApplicationContextMixinBuilder = (applicationCls) => (superclass) =>
6+
export const ApplicationContextMixin = (superclass) =>
77
class extends superclass {
88
constructor(config) {
99
super(config);
10-
if (!applicationCls)
11-
throw Error("ApplicationContextMixinBuilder: applicationCls is undefined");
10+
if (!this.constructor.Application)
11+
throw Error("ApplicationContextMixin: Application is undefined");
1212
this._application =
13-
(config.context && config.context.application) || applicationCls.createDefault();
13+
(config.context && config.context.application) ||
14+
this.constructor.Application.createDefault();
1415
}
1516

1617
get application() {
1718
return this._application;
1819
}
1920
};
2021

21-
export const MaterialContextMixinBuilder = (materialCls) => (superclass) =>
22+
export const MaterialContextMixin = (superclass) =>
2223
class extends superclass {
2324
constructor(config) {
2425
super(config);
25-
if (!materialCls) throw Error("MaterialContextMixinBuilder: materialCls is undefined");
26+
if (!this.constructor.Material) {
27+
throw Error("MaterialContextMixin: Material is undefined");
28+
}
2629
this._material = config.context && config.context.material;
27-
if (!this._material) this._material = materialCls.createDefault();
30+
if (!this._material) this._material = this.constructor.Material.createDefault();
2831
this.updateMaterialHash();
2932
}
3033

@@ -74,14 +77,18 @@ export const MaterialsSetContextMixin = (superclass) =>
7477
}
7578
};
7679

77-
export const MaterialsContextMixinBuilder = (materialCls) => (superclass) =>
80+
export const MaterialsContextMixin = (superclass) =>
7881
class extends superclass {
7982
constructor(config) {
8083
super(config);
8184
const materials = this.config.context && this.config.context.materials;
82-
if (!materialCls) throw Error("MaterialsContextMixinBuilder: materialCls is undefined");
85+
if (!this.constructor.Material) {
86+
throw Error("MaterialsContextMixin: Material is undefined");
87+
}
8388
this._materials =
84-
materials && materials.length ? materials : [materialCls.createDefault()];
89+
materials && materials.length
90+
? materials
91+
: [this.constructor.Material.createDefault()];
8592
}
8693

8794
get materials() {

src/context/registry.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,42 @@ export class ContextProviderRegistryContainer {
3131
this.providers = this.providers.filter((p) => p.name === name);
3232
}
3333
}
34+
35+
/** Extends an existing context provider registry container and patches static class variables if applicable.
36+
*
37+
* @param {ContextProviderRegistryContainer} registryContainer
38+
* @param {Object} classConfigMap
39+
* @param {Object} classesToPatch
40+
* @example
41+
* const classConfigMap = {
42+
* PlanewaveCutoffDataManager: {
43+
* providerCls: PlanewaveCutoffsContextProvider,
44+
* config: _makeImportant({ name: "cutoffs", entityName: "subworkflow" })
45+
* },
46+
* };
47+
*
48+
*/
49+
export const extendAndPatchRegistry = (registryContainer, classConfigMap, classesToPatch = {}) => {
50+
Object.entries(classConfigMap).forEach(([name, { providerCls, config }]) => {
51+
Object.entries(classesToPatch).forEach(([clsName, cls]) => {
52+
if (providerCls[clsName]) {
53+
providerCls[clsName] = cls;
54+
}
55+
});
56+
registryContainer.addProvider({
57+
instance: providerCls.getConstructorConfig(config),
58+
name,
59+
});
60+
});
61+
return registryContainer;
62+
};
63+
64+
/** Creates a new context provider registry container and patches static class variables if applicable.
65+
*
66+
* @param {Object} classConfigMap
67+
* @param {{Material: SpecificMockMaterial}} classesToPatch
68+
*/
69+
export const createAndPatchRegistry = (classConfigMap, classesToPatch = {}) => {
70+
const registryContainer = new ContextProviderRegistryContainer();
71+
return extendAndPatchRegistry(registryContainer, classConfigMap, classesToPatch);
72+
};

src/utils/schemas.js

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,31 +24,35 @@ export const baseSchemas = {
2424
Unit: "workflow/unit",
2525
};
2626

27-
const entityMix = [
27+
export const entityMix = [
2828
"system/description-object",
2929
"system/base-entity-set",
3030
"system/sharing",
3131
"system/metadata",
3232
"system/defaultable",
3333
];
3434

35-
const subWorkflowMix = ["system/system-name", "system/is-multi-material"];
35+
export const subWorkflowMix = ["system/system-name", "system/is-multi-material"];
3636

37-
const workflowMix = ["workflow/base-flow", "system/history", "system/is-outdated"];
37+
export const workflowMix = ["workflow/base-flow", "system/history", "system/is-outdated"];
3838

39-
const bankMaterialMix = ["material/conventional", "system/creator-account"];
39+
export const bankMaterialMix = ["material/conventional", "system/creator-account"];
4040

41-
const bankWorkflowMix = ["system/creator-account"];
41+
export const bankWorkflowMix = ["system/creator-account"];
4242

43-
const jobMix = ["system/status", "system/job-extended"];
43+
export const jobMix = ["system/status", "system/job-extended"];
4444

45-
const unitMix = ["system/unit-extended", "system/status", "workflow/unit/runtime/runtime-items"];
45+
export const unitMix = [
46+
"system/unit-extended",
47+
"system/status",
48+
"workflow/unit/runtime/runtime-items",
49+
];
4650

47-
const assignmentUnitMix = ["system/scope"];
51+
export const assignmentUnitMix = ["system/scope"];
4852

49-
const flavorMix = ["system/is-multi-material"];
53+
export const flavorMix = ["system/is-multi-material"];
5054

51-
const systemEntityMix = ["system/entity"];
55+
export const systemEntityMix = ["system/entity"];
5256

5357
export const mixSchemas = {
5458
Entity: [...entityMix],
@@ -83,3 +87,14 @@ export function getMixSchemasByClassName(className) {
8387
? mixSchemas[className].map((schemaId) => JSONSchemasInterface.schemaById(schemaId))
8488
: [];
8589
}
90+
91+
/**
92+
* Register additional Entity classes to be resolved with jsonSchema property
93+
* @param {String} className - class name derived from InMemoryEntity
94+
* @param {String} classBaseSchema - base schemaId
95+
* @param {Array} classMixSchemas - array of schemaId to mix
96+
*/
97+
export function registerClassName(className, classBaseSchema, classMixSchemas) {
98+
baseSchemas[className] = classBaseSchema;
99+
mixSchemas[className] = classMixSchemas;
100+
}

tests/JSONSchemasInterface.tests.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,18 @@ describe("JSONSchemasInterface", () => {
3030

3131
expect(schema).to.be.an("object");
3232
});
33+
34+
it("can find registered schemas", () => {
35+
JSONSchemasInterface.registerSchema({
36+
schemaId: "test-schema-id",
37+
properties: {
38+
testProp: {
39+
type: "string",
40+
},
41+
},
42+
});
43+
44+
const schema = JSONSchemasInterface.schemaById("test-schema-id");
45+
expect(schema).to.be.an("object");
46+
});
3347
});

tests/context.tests.js

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import { expect } from "chai";
2+
import { mix } from "mixwith";
3+
4+
import {
5+
ApplicationContextMixin,
6+
ContextProvider,
7+
createAndPatchRegistry,
8+
MaterialContextMixin,
9+
} from "../src/context";
10+
11+
class MockMaterial {
12+
static createDefault() {
13+
return "defaultMockMaterial";
14+
}
15+
}
16+
17+
class SpecificMockMaterial {
18+
static createDefault() {
19+
return "defaultSpecificMockMaterial";
20+
}
21+
}
22+
23+
class MockApplication {
24+
static createDefault() {
25+
return "defaultMockApplication";
26+
}
27+
}
28+
29+
class SpecificMockApplication {
30+
static createDefault() {
31+
return "defaultSpecificMockApplication";
32+
}
33+
}
34+
35+
class ProviderEntity extends mix(ContextProvider).with(
36+
MaterialContextMixin,
37+
ApplicationContextMixin,
38+
) {
39+
static Material = MockMaterial;
40+
41+
static Application = MockApplication;
42+
}
43+
44+
class DerivedProviderEntity extends ProviderEntity {
45+
static Material = SpecificMockMaterial;
46+
47+
static Application = SpecificMockApplication;
48+
}
49+
50+
class ApplicationContextProvider extends mix(ContextProvider).with(ApplicationContextMixin) {
51+
static Application = SpecificMockApplication;
52+
}
53+
54+
describe("Material & Application ContextMixin", () => {
55+
const config = {};
56+
57+
it("uses static entity class", () => {
58+
const provider = new ProviderEntity(config);
59+
expect(provider.material).to.be.equal("defaultMockMaterial");
60+
expect(provider.application).to.be.equal("defaultMockApplication");
61+
});
62+
63+
it("uses static entity class from derived class", () => {
64+
const provider = new DerivedProviderEntity(config);
65+
expect(provider.material).to.be.equal("defaultSpecificMockMaterial");
66+
expect(provider.application).to.be.equal("defaultSpecificMockApplication");
67+
});
68+
});
69+
70+
describe("ContextProviderRegistryContainer", () => {
71+
const classConfigObj = {
72+
DataManager: {
73+
providerCls: ProviderEntity,
74+
config: { name: "example1", domain: "important" },
75+
},
76+
ApplicationDataManager: {
77+
providerCls: ApplicationContextProvider,
78+
config: { name: "example2", domain: "important" },
79+
},
80+
};
81+
82+
it("can be created and patched", () => {
83+
const registry = createAndPatchRegistry(classConfigObj, { Material: SpecificMockMaterial });
84+
const _dataProvider = registry.findProviderInstanceByName("DataManager");
85+
const dataProvider = new _dataProvider.constructor(_dataProvider.config);
86+
const _appProvider = registry.findProviderInstanceByName("ApplicationDataManager");
87+
const appProvider = new _appProvider.constructor(_appProvider.config);
88+
expect(dataProvider.material).to.be.equal("defaultSpecificMockMaterial");
89+
expect(appProvider.application).to.be.equal("defaultSpecificMockApplication");
90+
});
91+
});

tests/in_memory.tests.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
/* eslint-disable max-classes-per-file */
12
import { expect } from "chai";
23

34
import { InMemoryEntity } from "../src/entity/in_memory";
5+
import { entityMix, registerClassName } from "../src/utils/schemas";
46

57
describe("InMemoryEntity", () => {
68
const obj = {
@@ -60,4 +62,22 @@ describe("InMemoryEntity", () => {
6062
expect(Entity.jsonSchema).to.have.nested.property("properties.isDefault"); // check mix schemas
6163
expect(Entity.jsonSchema).to.have.nested.property("properties.nested.type"); // check custom properties
6264
});
65+
66+
it("jsonSchema returns correct registered schema", () => {
67+
class RegisteredEntity extends InMemoryEntity {
68+
static get customJsonSchemaProperties() {
69+
return {
70+
nested: {
71+
type: "string",
72+
},
73+
};
74+
}
75+
}
76+
77+
registerClassName(RegisteredEntity.name, "system/entity", entityMix);
78+
79+
expect(RegisteredEntity.jsonSchema).to.be.an("object");
80+
expect(RegisteredEntity.jsonSchema).to.have.nested.property("properties.isDefault"); // check mix schemas
81+
expect(RegisteredEntity.jsonSchema).to.have.nested.property("properties.nested.type"); // check custom properties
82+
});
6383
});

0 commit comments

Comments
 (0)