@itwin/core-backend
Version:
iTwin.js backend components
577 lines • 27.9 kB
JavaScript
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
if (value !== null && value !== void 0) {
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
var dispose, inner;
if (async) {
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
dispose = value[Symbol.asyncDispose];
}
if (dispose === void 0) {
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
dispose = value[Symbol.dispose];
if (async) inner = dispose;
}
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
env.stack.push({ value: value, dispose: dispose, async: async });
}
else if (async) {
env.stack.push({ async: true });
}
return value;
};
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
return function (env) {
function fail(e) {
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
env.hasError = true;
}
var r, s = 0;
function next() {
while (r = env.stack.pop()) {
try {
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
if (r.dispose) {
var result = r.dispose.call(r.value);
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
}
else s |= 1;
}
catch (e) {
fail(e);
}
}
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
if (env.hasError) throw env.error;
}
return next();
};
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
});
import { Schema, SchemaItemType, SchemaKey } from "@itwin/ecschema-metadata";
import { expect, use } from "chai";
import { TestContext } from "./TestContext";
import { IModelIncrementalSchemaLocater } from "../../IModelIncrementalSchemaLocater";
import * as deepEqualInAnyOrder from "deep-equal-in-any-order";
use(deepEqualInAnyOrder);
function findItem(name, rowData) {
const item = rowData.find((i) => i.name === name);
if (!item)
throw new Error(`Could not find schema item '${name}'`);
return item;
}
function findProperty(name, rowData) {
return rowData.find((i) => i.name === name);
}
function isECClass(item) {
return item.schemaItemType === SchemaItemType.EntityClass || item.schemaItemType === SchemaItemType.Mixin || item.schemaItemType === SchemaItemType.RelationshipClass ||
item.schemaItemType === SchemaItemType.StructClass || item.schemaItemType === SchemaItemType.CustomAttributeClass;
}
function isRelationshipClass(item) {
return "source" in item && "target" in item;
}
/**
* A test locater that exposes the protected methods of IModelIncrementalSchemaLocater for granular testing.
*/
class TestSchemaLocater extends IModelIncrementalSchemaLocater {
}
describe("ECSql query tests", function () {
function validateItem(name, itemPropObjects, schema) {
const actualJson = findItem(name, itemPropObjects);
const expectedItem = schema.getItemSync(name);
const expectedJson = expectedItem.toJSON();
// The following code exists because some data coming from the database will not match the
// data from the context due to default values. This is OK as long as the conditions are
// correct. For instance, schemaItem name will not exist in serialized JSON, but does exist
// coming from the DB. RelationshipConstraint's AbstractConstraint is set when only one
// constraint class exists coming from the database, but a serialized Relationship will not
// contain the abstract constraint. The one constraint is 'assumed' to be the abstract constraint.
expect(actualJson.name).to.equal(expectedItem?.name);
delete actualJson.name;
if (isECClass(actualJson)) {
if (expectedJson.schemaItemType === "Mixin") {
expect(actualJson.modifier).to.be.oneOf([undefined, 'Abstract']);
delete actualJson.modifier;
}
else if (expectedJson.modifier === undefined) {
expect(actualJson.modifier).to.be.oneOf([undefined, 'None']);
delete actualJson.modifier;
}
}
if (isRelationshipClass(actualJson)) {
// abstract can be set via database, but not via context for 1 constraint class
// so verify constraint and conditions are correct and delete property
const expectedRelationship = expectedJson;
if (actualJson.source.abstractConstraint !== expectedRelationship.source.abstractConstraint) {
expect(actualJson.source.abstractConstraint).to.equal(expectedRelationship.source.constraintClasses[0]);
expect(actualJson.source.constraintClasses.length).to.equal(1);
delete actualJson.source.abstractConstraint;
}
if (actualJson.target.abstractConstraint !== expectedRelationship.target.abstractConstraint) {
expect(actualJson.target.abstractConstraint).to.equal(expectedRelationship.target.constraintClasses[0]);
expect(actualJson.target.constraintClasses.length).to.equal(1);
delete actualJson.target.abstractConstraint;
}
}
if (actualJson.schemaItemType === SchemaItemType.Format) {
if (undefined !== actualJson.includeZero && undefined === expectedJson.includeZero) {
expect(actualJson.includeZero).to.equal(true);
delete actualJson.includeZero;
}
if (actualJson.composite && undefined !== actualJson.composite.includeZero && undefined === expectedJson.composite.includeZero) {
expect(actualJson.composite.includeZero).to.equal(true);
delete actualJson.composite.includeZero;
}
if (actualJson.composite && undefined !== actualJson.composite.spacer && undefined === expectedJson.composite.spacer) {
expect(actualJson.composite.spacer).to.equal(" ");
delete actualJson.composite.spacer;
}
if (undefined !== actualJson.decimalSeparator && undefined === expectedJson.decimalSeparator) {
expect(actualJson.decimalSeparator).to.equal(".");
delete actualJson.decimalSeparator;
}
if (undefined !== actualJson.roundFactor && undefined === expectedJson.roundFactor) {
expect(actualJson.roundFactor).to.equal(0);
delete actualJson.roundFactor;
}
if (undefined !== actualJson.showSignOption && undefined === expectedJson.showSignOption) {
expect(actualJson.showSignOption).to.equal("OnlyNegative");
delete actualJson.showSignOption;
}
if (undefined !== actualJson.thousandSeparator && undefined === expectedJson.thousandSeparator) {
expect(actualJson.thousandSeparator).to.equal(",");
delete actualJson.thousandSeparator;
}
if (undefined !== actualJson.uomSeparator && undefined === expectedJson.uomSeparator) {
expect(actualJson.uomSeparator).to.equal(" ");
delete actualJson.uomSeparator;
}
if (undefined !== actualJson.spacer && undefined === expectedJson.spacer) {
expect(actualJson.spacer).to.equal(" ");
delete actualJson.spacer;
}
if (undefined !== actualJson.formatTraits) {
actualJson.formatTraits = actualJson.formatTraits.map((trait) => {
return trait.charAt(0).toUpperCase() + trait.slice(1);
});
}
}
expect(actualJson).to.deep.equalInAnyOrder(expectedJson);
}
async function createTestContext() {
const testEnv = await TestContext.create();
return testEnv;
}
it("Schema query, props parsed successfully", async function () {
const env_1 = { stack: [], error: void 0, hasError: false };
try {
const testSchemaKey = new SchemaKey("SchemaTest", 1, 0, 0);
const env = __addDisposableResource(env_1, await createTestContext(), true);
const expectedSchema = await env.importAssetSchema(testSchemaKey);
const actualSchemaProps = await env.schemaLocater.getSchemaJson(testSchemaKey, env.schemaContext);
expect(actualSchemaProps).to.not.be.undefined;
const actualSchema = await Schema.fromJson(actualSchemaProps, env.schemaContext);
expect(actualSchema.toJSON()).to.deep.equal(expectedSchema?.toJSON());
}
catch (e_1) {
env_1.error = e_1;
env_1.hasError = true;
}
finally {
const result_1 = __disposeResources(env_1);
if (result_1)
await result_1;
}
});
it("Property query, props parsed successfully", async function () {
const env_2 = { stack: [], error: void 0, hasError: false };
try {
const testKey = new SchemaKey("PropertyTest", 1, 0, 0);
const env = __addDisposableResource(env_2, await createTestContext(), true);
const schema = await env.importAssetSchema(testKey);
const classPropsObjects = await env.schemaLocater.getEntities(testKey.name, env.schemaContext);
const entityOneProps = findItem("EntityOne", classPropsObjects);
const entityTwoProps = findItem("EntityTwo", classPropsObjects);
const expectedEntityOne = await schema.getEntityClass("EntityOne");
const expectedEntityTwo = await schema.getEntityClass("EntityTwo");
const validateProperty = (propertyName, actualItem = entityOneProps, expectedItem = expectedEntityOne) => {
const actualProperty = findProperty(propertyName, actualItem.properties);
const expectedProperty = expectedItem?.getPropertySync(propertyName);
// if maxOccurs is the maximum int value in the context Schema,
// the property from the DB will not have a value
if (expectedProperty.maxOccurs === 2147483647) {
expect(actualProperty.maxOccurs).to.be.undefined;
// set so comparison will pass
actualProperty.maxOccurs = 2147483647;
}
expect(actualProperty).to.deep.equal(expectedProperty?.toJSON());
};
// All but one testable property is in EntityOne
for (const property of await expectedEntityOne.getProperties(true)) {
validateProperty(property.name);
}
// Backward direction Navigation property is in EntityTwo
validateProperty("EntityTwoParent", entityTwoProps, expectedEntityTwo);
}
catch (e_2) {
env_2.error = e_2;
env_2.hasError = true;
}
finally {
const result_2 = __disposeResources(env_2);
if (result_2)
await result_2;
}
});
it("Entity query, props parsed successfully", async function () {
const env_3 = { stack: [], error: void 0, hasError: false };
try {
const testKey = new SchemaKey("EntityTest", 1, 0, 0);
const env = __addDisposableResource(env_3, await createTestContext(), true);
const schema = await env.importAssetSchema(testKey);
const classPropsObjects = await env.schemaLocater.getEntities(testKey.name, env.schemaContext);
expect(classPropsObjects.length).to.be.greaterThan(0);
validateItem("EntityModifierNone", classPropsObjects, schema);
validateItem("EntityModifierAbstract", classPropsObjects, schema);
validateItem("EntityModifierSealed", classPropsObjects, schema);
}
catch (e_3) {
env_3.error = e_3;
env_3.hasError = true;
}
finally {
const result_3 = __disposeResources(env_3);
if (result_3)
await result_3;
}
});
it("Struct query, props parsed successfully", async function () {
const env_4 = { stack: [], error: void 0, hasError: false };
try {
const testKey = new SchemaKey("StructTest", 1, 0, 0);
const env = __addDisposableResource(env_4, await createTestContext(), true);
const schema = await env.importAssetSchema(testKey);
const classPropsObjects = await env.schemaLocater.getStructs(testKey.name, env.schemaContext);
expect(classPropsObjects.length).to.be.greaterThan(0);
validateItem("StructModifierNone", classPropsObjects, schema);
validateItem("StructModifierAbstract", classPropsObjects, schema);
validateItem("StructModifierSealed", classPropsObjects, schema);
}
catch (e_4) {
env_4.error = e_4;
env_4.hasError = true;
}
finally {
const result_4 = __disposeResources(env_4);
if (result_4)
await result_4;
}
});
it("Mixin query, props parsed successfully", async function () {
const env_5 = { stack: [], error: void 0, hasError: false };
try {
const testKey = new SchemaKey("MixinTest", 1, 0, 0);
const env = __addDisposableResource(env_5, await createTestContext(), true);
const schema = await env.importAssetSchema(testKey);
const classPropsObjects = await env.schemaLocater.getMixins(testKey.name, env.schemaContext);
expect(classPropsObjects.length).to.be.greaterThan(0);
validateItem("IBaseMixin", classPropsObjects, schema);
validateItem("ITestMixin", classPropsObjects, schema);
}
catch (e_5) {
env_5.error = e_5;
env_5.hasError = true;
}
finally {
const result_5 = __disposeResources(env_5);
if (result_5)
await result_5;
}
});
it("Relationship query, props parsed successfully", async function () {
const env_6 = { stack: [], error: void 0, hasError: false };
try {
const testKey = new SchemaKey("RelationshipTest", 1, 0, 0);
const env = __addDisposableResource(env_6, await createTestContext(), true);
const schema = await env.importAssetSchema(testKey);
const classPropsObjects = await env.schemaLocater.getRelationships(testKey.name, env.schemaContext);
expect(classPropsObjects.length).to.be.greaterThan(0);
validateItem("OwnerOwnsVehicles", classPropsObjects, schema);
validateItem("OwnerOwnsCars", classPropsObjects, schema);
validateItem("OwnerOwnsAmericanCars", classPropsObjects, schema);
validateItem("PhysicalModelBreaksDownCarElement", classPropsObjects, schema);
}
catch (e_6) {
env_6.error = e_6;
env_6.hasError = true;
}
finally {
const result_6 = __disposeResources(env_6);
if (result_6)
await result_6;
}
});
it("CustomAttributeClass query, props parsed successfully", async function () {
const env_7 = { stack: [], error: void 0, hasError: false };
try {
const testKey = new SchemaKey("CustomAttributeClassTest", 1, 0, 0);
const env = __addDisposableResource(env_7, await createTestContext(), true);
const schema = await env.importAssetSchema(testKey);
const classPropsObjects = await env.schemaLocater.getCustomAttributeClasses(testKey.name, env.schemaContext);
expect(classPropsObjects.length).to.be.greaterThan(0);
validateItem("CustomAttributeModifierNone", classPropsObjects, schema);
validateItem("CustomAttributeModifierSealed", classPropsObjects, schema);
validateItem("CustomAttributeModifierAbstract", classPropsObjects, schema);
}
catch (e_7) {
env_7.error = e_7;
env_7.hasError = true;
}
finally {
const result_7 = __disposeResources(env_7);
if (result_7)
await result_7;
}
});
it("KindOfQuantity query, props parsed successfully", async function () {
const env_8 = { stack: [], error: void 0, hasError: false };
try {
const testKey = new SchemaKey("KindOfQuantityTest", 1, 0, 0);
const env = __addDisposableResource(env_8, await createTestContext(), true);
const schema = await env.importAssetSchema(testKey);
const itemPropsObjects = await env.schemaLocater.getKindOfQuantities(testKey.name, env.schemaContext);
expect(itemPropsObjects.length).to.be.greaterThan(0);
validateItem("ACCELERATION", itemPropsObjects, schema);
validateItem("ANGLE", itemPropsObjects, schema);
}
catch (e_8) {
env_8.error = e_8;
env_8.hasError = true;
}
finally {
const result_8 = __disposeResources(env_8);
if (result_8)
await result_8;
}
});
it("PropertyCategory query, props parsed successfully", async function () {
const env_9 = { stack: [], error: void 0, hasError: false };
try {
const testKey = new SchemaKey("PropertyCategoryTest", 1, 0, 0);
const env = __addDisposableResource(env_9, await createTestContext(), true);
const schema = await env.importAssetSchema(testKey);
const itemPropsObjects = await env.schemaLocater.getPropertyCategories(testKey.name, env.schemaContext);
expect(itemPropsObjects.length).to.be.greaterThan(0);
validateItem("PropertyCategory1", itemPropsObjects, schema);
validateItem("PropertyCategory2", itemPropsObjects, schema);
}
catch (e_9) {
env_9.error = e_9;
env_9.hasError = true;
}
finally {
const result_9 = __disposeResources(env_9);
if (result_9)
await result_9;
}
});
it("Enumeration query, props parsed successfully", async function () {
const env_10 = { stack: [], error: void 0, hasError: false };
try {
const testKey = new SchemaKey("EnumerationTest", 1, 0, 0);
const env = __addDisposableResource(env_10, await createTestContext(), true);
const schema = await env.importAssetSchema(testKey);
const itemPropsObjects = await env.schemaLocater.getEnumerations(testKey.name, env.schemaContext);
expect(itemPropsObjects.length).to.be.greaterThan(0);
validateItem("IntEnumeration", itemPropsObjects, schema);
validateItem("StringEnumeration", itemPropsObjects, schema);
}
catch (e_10) {
env_10.error = e_10;
env_10.hasError = true;
}
finally {
const result_10 = __disposeResources(env_10);
if (result_10)
await result_10;
}
});
it("Unit query, props parsed successfully", async function () {
const env_11 = { stack: [], error: void 0, hasError: false };
try {
const testKey = new SchemaKey("UnitTest", 1, 0, 0);
const env = __addDisposableResource(env_11, await createTestContext(), true);
const schema = await env.importAssetSchema(testKey);
const itemPropsObjects = await env.schemaLocater.getUnits(testKey.name, env.schemaContext);
expect(itemPropsObjects.length).to.be.greaterThan(0);
validateItem("LITRE", itemPropsObjects, schema);
validateItem("GALLON", itemPropsObjects, schema);
validateItem("ACRE", itemPropsObjects, schema);
validateItem("FAHRENHEIT", itemPropsObjects, schema);
}
catch (e_11) {
env_11.error = e_11;
env_11.hasError = true;
}
finally {
const result_11 = __disposeResources(env_11);
if (result_11)
await result_11;
}
});
it("InvertedUnit query, props parsed successfully", async function () {
const env_12 = { stack: [], error: void 0, hasError: false };
try {
const testKey = new SchemaKey("InvertedUnitTest", 1, 0, 0);
const env = __addDisposableResource(env_12, await createTestContext(), true);
const schema = await env.importAssetSchema(testKey);
const itemPropsObjects = await env.schemaLocater.getInvertedUnits(testKey.name, env.schemaContext);
expect(itemPropsObjects.length).to.be.greaterThan(0);
validateItem("FT_HORIZONTAL_PER_FT_VERTICAL", itemPropsObjects, schema);
}
catch (e_12) {
env_12.error = e_12;
env_12.hasError = true;
}
finally {
const result_12 = __disposeResources(env_12);
if (result_12)
await result_12;
}
});
it("UnitSystem query, props parsed successfully", async function () {
const env_13 = { stack: [], error: void 0, hasError: false };
try {
// There's a UnitSystem in there.
const testKey = new SchemaKey("InvertedUnitTest", 1, 0, 0);
const env = __addDisposableResource(env_13, await createTestContext(), true);
const schema = await env.importAssetSchema(testKey);
const itemPropsObjects = await env.schemaLocater.getUnitSystems(testKey.name, env.schemaContext);
expect(itemPropsObjects.length).to.be.greaterThan(0);
validateItem("USCUSTOM", itemPropsObjects, schema);
}
catch (e_13) {
env_13.error = e_13;
env_13.hasError = true;
}
finally {
const result_13 = __disposeResources(env_13);
if (result_13)
await result_13;
}
});
it("Constant query, props parsed successfully", async function () {
const env_14 = { stack: [], error: void 0, hasError: false };
try {
// There's a UnitSystem in there.
const testKey = new SchemaKey("ConstantTest", 1, 0, 0);
const env = __addDisposableResource(env_14, await createTestContext(), true);
const schema = await env.importAssetSchema(testKey);
const itemPropsObjects = await env.schemaLocater.getConstants(testKey.name, env.schemaContext);
expect(itemPropsObjects.length).to.be.greaterThan(0);
validateItem("KILO", itemPropsObjects, schema);
validateItem("HALF_PI", itemPropsObjects, schema);
}
catch (e_14) {
env_14.error = e_14;
env_14.hasError = true;
}
finally {
const result_14 = __disposeResources(env_14);
if (result_14)
await result_14;
}
});
it("Phenomenon query, props parsed successfully", async function () {
const env_15 = { stack: [], error: void 0, hasError: false };
try {
// There's a Phenomenon in there.
const testKey = new SchemaKey("ConstantTest", 1, 0, 0);
const env = __addDisposableResource(env_15, await createTestContext(), true);
const schema = await env.importAssetSchema(testKey);
const itemPropsObjects = await env.schemaLocater.getPhenomenon(testKey.name, env.schemaContext);
expect(itemPropsObjects.length).to.be.greaterThan(0);
validateItem("NUMBER", itemPropsObjects, schema);
validateItem("LENGTH_RATIO", itemPropsObjects, schema);
}
catch (e_15) {
env_15.error = e_15;
env_15.hasError = true;
}
finally {
const result_15 = __disposeResources(env_15);
if (result_15)
await result_15;
}
});
it("Format Schema parses successfully", async function () {
const env_16 = { stack: [], error: void 0, hasError: false };
try {
// Using installed Formats schema
const testKey = new SchemaKey("Formats", 1, 0, 0);
const env = __addDisposableResource(env_16, await createTestContext(), true);
const schema = await env.importAssetSchema(testKey);
const itemPropsObjects = await env.schemaLocater.getFormats(testKey.name, env.schemaContext);
expect(itemPropsObjects.length).to.be.greaterThan(0);
for (const props of itemPropsObjects) {
validateItem(props.name, itemPropsObjects, schema);
}
}
catch (e_16) {
env_16.error = e_16;
env_16.hasError = true;
}
finally {
const result_16 = __disposeResources(env_16);
if (result_16)
await result_16;
}
});
it("Comprehensive Format parses successfully", async function () {
const env_17 = { stack: [], error: void 0, hasError: false };
try {
const testKey = new SchemaKey("FormatTest", 1, 0, 0);
const env = __addDisposableResource(env_17, await createTestContext(), true);
const schema = await env.importAssetSchema(testKey);
const itemPropsObjects = await env.schemaLocater.getFormats(testKey.name, env.schemaContext);
expect(itemPropsObjects.length).to.be.greaterThan(0);
for (const props of itemPropsObjects) {
validateItem(props.name, itemPropsObjects, schema);
}
}
catch (e_17) {
env_17.error = e_17;
env_17.hasError = true;
}
finally {
const result_17 = __disposeResources(env_17);
if (result_17)
await result_17;
}
});
it("CustomAttribute instances parse successfully", async function () {
const env_18 = { stack: [], error: void 0, hasError: false };
try {
const testKey = new SchemaKey("CustomAttributeInstanceTest", 1, 0, 0);
const env = __addDisposableResource(env_18, await createTestContext(), true);
const schema = await env.importAssetSchema(testKey);
const itemPropsObjects = await env.schemaLocater.getStructs(testKey.name, env.schemaContext);
expect(itemPropsObjects.length).to.be.greaterThan(0);
for (const props of itemPropsObjects) {
validateItem(props.name, itemPropsObjects, schema);
}
}
catch (e_18) {
env_18.error = e_18;
env_18.hasError = true;
}
finally {
const result_18 = __disposeResources(env_18);
if (result_18)
await result_18;
}
});
});
//# sourceMappingURL=ECSqlQueries.test.js.map