Skip to content

Commit

Permalink
Add exports and type attributes to package.json (#754)
Browse files Browse the repository at this point in the history
* components

* testing

* change

* Fix internal imports from `presentation-components`

* Fix internal imports from `presentation-testing`

* Remove `*:watch` scripts. Can use `build -- -w` instead.

* attempt to start docs build
  • Loading branch information
grigasp authored Oct 28, 2024
1 parent 7a5b2a0 commit 24c6553
Show file tree
Hide file tree
Showing 145 changed files with 684 additions and 591 deletions.
10 changes: 10 additions & 0 deletions .changeset/polite-mails-count.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
"@itwin/presentation-components": minor
"@itwin/presentation-testing": minor
---

Define `type` and `exports` attributes in `package.json`.

The change moves this package a step closer towards dropping CommonJS support - it's now transpiled from ESM to CommonJS instead of the opposite.

In addition, the `exports` attribute has been added to `package.json` to prohibit access to APIs that are not intended to be used by external consumers.
10 changes: 10 additions & 0 deletions .changeset/selfish-parents-appear.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
"@itwin/presentation-testing": minor
---

Export file name utility functions.

- `getTestOutputDir` and `setTestOutputDir` - get/set functions for the global test output directory used by this package.
- `setupOutputFileLocation` - given a file name, returns a full path to the file in the test output directory.
- `createFileNameFromString` - creates a valid, sanitized file name from any string.
- `limitFilePathLength` - makes sure the given file path is shorter than 260 characters.
1 change: 0 additions & 1 deletion apps/full-stack-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
"private": true,
"scripts": {
"build": "node ./scripts/setup-tests.cjs && tsc",
"build:watch": "npm run build -- -w",
"clean": "rimraf lib build",
"cover": "npm run -s test",
"lint": "eslint ./src/**/*.{ts,tsx}",
Expand Down
7 changes: 1 addition & 6 deletions apps/full-stack-tests/src/IModelUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,7 @@ import { ECDb, ECSqlStatement } from "@itwin/core-backend";
import { BentleyError, DbResult, Guid, Id64, Id64String, OrderedId64Iterable } from "@itwin/core-bentley";
import { IModelConnection } from "@itwin/core-frontend";
import { ECSqlBinding, parseFullClassName, PrimitiveValue } from "@itwin/presentation-shared";
import { buildTestIModel, TestIModelBuilder } from "@itwin/presentation-testing";
import {
createFileNameFromString,
limitFilePathLength,
setupOutputFileLocation,
} from "@itwin/presentation-testing/lib/cjs/presentation-testing/InternalUtils.js";
import { buildTestIModel, createFileNameFromString, limitFilePathLength, setupOutputFileLocation, TestIModelBuilder } from "@itwin/presentation-testing";

function isBinding(value: ECSqlBinding | PrimitiveValue): value is ECSqlBinding {
return typeof value === "object" && (value as ECSqlBinding).type !== undefined && (value as ECSqlBinding).value !== undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ import {
insertSubCategory,
insertSubject,
} from "presentation-test-utilities";
import { Id64, using } from "@itwin/core-bentley";
import { Id64 } from "@itwin/core-bentley";
import { InstanceKey, KeySet } from "@itwin/presentation-common";
import { ViewportSelectionHandler } from "@itwin/presentation-components/lib/cjs/presentation-components/viewport/ViewportSelectionHandler.js";
import { viewWithUnifiedSelection } from "@itwin/presentation-components";
import { Presentation, TRANSIENT_ELEMENT_CLASSNAME } from "@itwin/presentation-frontend";
import { buildTestIModel as buildTestIModel } from "@itwin/presentation-testing";
import { waitFor } from "@testing-library/react";
import { render, waitFor } from "@testing-library/react";
import { initialize, terminate } from "../../IntegrationTests.js";

describe("Unified Selection", () => {
Expand All @@ -29,6 +29,10 @@ describe("Unified Selection", () => {
await terminate();
});

const UnifiedSelectionComponent = viewWithUnifiedSelection(function () {
return null;
});

describe("Hiliting selection", () => {
describe("Subject", () => {
it("hilites models directly under subject", async function () {
Expand All @@ -42,16 +46,17 @@ describe("Unified Selection", () => {
insertPhysicalModelWithPartition({ builder, codeValue: "model 2", partitionParentId: subjectKey.id }),
];
});
await using(new ViewportSelectionHandler({ imodel }), async (_) => {
Presentation.selection.replaceSelection("", imodel, new KeySet([subjectKey!]));
await waitFor(() => {
expect(imodel.hilited.models.toId64Array())
.to.have.lengthOf(modelKeys.length)
.and.to.include.members(modelKeys.map((k) => k.id));
expect(imodel.hilited.subcategories.isEmpty).to.be.true;
expect(imodel.hilited.elements.isEmpty).to.be.true;
expect(imodel.selectionSet.size).to.eq(0);
});

render(<UnifiedSelectionComponent imodel={imodel} />);

Presentation.selection.replaceSelection("", imodel, new KeySet([subjectKey!]));
await waitFor(() => {
expect(imodel.hilited.models.toId64Array())
.to.have.lengthOf(modelKeys.length)
.and.to.include.members(modelKeys.map((k) => k.id));
expect(imodel.hilited.subcategories.isEmpty).to.be.true;
expect(imodel.hilited.elements.isEmpty).to.be.true;
expect(imodel.selectionSet.size).to.eq(0);
});
});

Expand All @@ -69,16 +74,17 @@ describe("Unified Selection", () => {
insertPhysicalModelWithPartition({ builder, codeValue: "model 2", partitionParentId: subject4.id }),
];
});
await using(new ViewportSelectionHandler({ imodel }), async (_) => {
Presentation.selection.replaceSelection("", imodel, new KeySet([subjectKey!]));
await waitFor(() => {
expect(imodel.hilited.models.toId64Array())
.to.have.lengthOf(modelKeys.length)
.and.to.include.members(modelKeys.map((k) => k.id));
expect(imodel.hilited.subcategories.isEmpty).to.be.true;
expect(imodel.hilited.elements.isEmpty).to.be.true;
expect(imodel.selectionSet.size).to.eq(0);
});

render(<UnifiedSelectionComponent imodel={imodel} />);

Presentation.selection.replaceSelection("", imodel, new KeySet([subjectKey!]));
await waitFor(() => {
expect(imodel.hilited.models.toId64Array())
.to.have.lengthOf(modelKeys.length)
.and.to.include.members(modelKeys.map((k) => k.id));
expect(imodel.hilited.subcategories.isEmpty).to.be.true;
expect(imodel.hilited.elements.isEmpty).to.be.true;
expect(imodel.selectionSet.size).to.eq(0);
});
});
});
Expand All @@ -90,14 +96,15 @@ describe("Unified Selection", () => {
const imodel = await buildTestIModel(this, async (builder) => {
modelKey = insertPhysicalModelWithPartition({ builder, codeValue: "test model" });
});
await using(new ViewportSelectionHandler({ imodel }), async (_) => {
Presentation.selection.replaceSelection("", imodel, new KeySet([modelKey!]));
await waitFor(() => {
expect(imodel.hilited.models.toId64Array()).to.have.lengthOf(1).and.to.include(modelKey.id);
expect(imodel.hilited.subcategories.isEmpty).to.be.true;
expect(imodel.hilited.elements.isEmpty).to.be.true;
expect(imodel.selectionSet.size).to.eq(0);
});

render(<UnifiedSelectionComponent imodel={imodel} />);

Presentation.selection.replaceSelection("", imodel, new KeySet([modelKey!]));
await waitFor(() => {
expect(imodel.hilited.models.toId64Array()).to.have.lengthOf(1).and.to.include(modelKey.id);
expect(imodel.hilited.subcategories.isEmpty).to.be.true;
expect(imodel.hilited.elements.isEmpty).to.be.true;
expect(imodel.selectionSet.size).to.eq(0);
});
});
});
Expand All @@ -115,16 +122,17 @@ describe("Unified Selection", () => {
insertSubCategory({ builder, codeValue: "sub 2", parentCategoryId: categoryKey.id }),
];
});
await using(new ViewportSelectionHandler({ imodel }), async (_) => {
Presentation.selection.replaceSelection("", imodel, new KeySet([categoryKey!]));
await waitFor(() => {
expect(imodel.hilited.models.isEmpty).to.be.true;
expect(imodel.hilited.subcategories.toId64Array())
.to.have.lengthOf(subCategoryKeys.length)
.and.to.include.members(subCategoryKeys.map((k) => k.id));
expect(imodel.hilited.elements.isEmpty).to.be.true;
expect(imodel.selectionSet.size).to.eq(0);
});

render(<UnifiedSelectionComponent imodel={imodel} />);

Presentation.selection.replaceSelection("", imodel, new KeySet([categoryKey!]));
await waitFor(() => {
expect(imodel.hilited.models.isEmpty).to.be.true;
expect(imodel.hilited.subcategories.toId64Array())
.to.have.lengthOf(subCategoryKeys.length)
.and.to.include.members(subCategoryKeys.map((k) => k.id));
expect(imodel.hilited.elements.isEmpty).to.be.true;
expect(imodel.selectionSet.size).to.eq(0);
});
});

Expand All @@ -135,14 +143,15 @@ describe("Unified Selection", () => {
categoryKey = insertSpatialCategory({ builder, codeValue: "test category" });
});
const subCategoryKey = getDefaultSubcategoryKey(categoryKey!.id);
await using(new ViewportSelectionHandler({ imodel }), async (_) => {
Presentation.selection.replaceSelection("", imodel, new KeySet([subCategoryKey]));
await waitFor(() => {
expect(imodel.hilited.models.isEmpty).to.be.true;
expect(imodel.hilited.subcategories.toId64Array()).to.have.lengthOf(1).and.to.include(subCategoryKey.id);
expect(imodel.hilited.elements.isEmpty).to.be.true;
expect(imodel.selectionSet.size).to.eq(0);
});

render(<UnifiedSelectionComponent imodel={imodel} />);

Presentation.selection.replaceSelection("", imodel, new KeySet([subCategoryKey]));
await waitFor(() => {
expect(imodel.hilited.models.isEmpty).to.be.true;
expect(imodel.hilited.subcategories.toId64Array()).to.have.lengthOf(1).and.to.include(subCategoryKey.id);
expect(imodel.hilited.elements.isEmpty).to.be.true;
expect(imodel.selectionSet.size).to.eq(0);
});
});
});
Expand Down Expand Up @@ -174,18 +183,19 @@ describe("Unified Selection", () => {
const element5 = insertPhysicalElement({ builder, userLabel: "element 5", modelId: modelKey.id, categoryId: categoryKey.id, parentId: element3.id });
expectedHighlightedElementKeys = [assemblyKey, element2, element3, element4, element5];
});
await using(new ViewportSelectionHandler({ imodel }), async (_) => {
Presentation.selection.replaceSelection("", imodel, new KeySet([assemblyKey!]));
await waitFor(() => {
expect(imodel.hilited.models.isEmpty).to.be.true;
expect(imodel.hilited.subcategories.isEmpty).to.be.true;
expect(imodel.hilited.elements.toId64Array())
.to.have.lengthOf(expectedHighlightedElementKeys.length)
.and.to.include.members(expectedHighlightedElementKeys.map((k) => k.id));
expect([...imodel.selectionSet.elements])
.to.have.lengthOf(expectedHighlightedElementKeys.length)
.and.to.include.members(expectedHighlightedElementKeys.map((k) => k.id));
});

render(<UnifiedSelectionComponent imodel={imodel} />);

Presentation.selection.replaceSelection("", imodel, new KeySet([assemblyKey!]));
await waitFor(() => {
expect(imodel.hilited.models.isEmpty).to.be.true;
expect(imodel.hilited.subcategories.isEmpty).to.be.true;
expect(imodel.hilited.elements.toId64Array())
.to.have.lengthOf(expectedHighlightedElementKeys.length)
.and.to.include.members(expectedHighlightedElementKeys.map((k) => k.id));
expect([...imodel.selectionSet.elements])
.to.have.lengthOf(expectedHighlightedElementKeys.length)
.and.to.include.members(expectedHighlightedElementKeys.map((k) => k.id));
});
});

Expand All @@ -197,61 +207,64 @@ describe("Unified Selection", () => {
const categoryKey = insertSpatialCategory({ builder, codeValue: "test category" });
elementKey = insertPhysicalElement({ builder, userLabel: "element", modelId: modelKey.id, categoryId: categoryKey.id });
});
await using(new ViewportSelectionHandler({ imodel }), async (_) => {
Presentation.selection.replaceSelection("", imodel, new KeySet([elementKey!]));
await waitFor(() => {
expect(imodel.hilited.models.isEmpty).to.be.true;
expect(imodel.hilited.subcategories.isEmpty).to.be.true;
expect(imodel.hilited.elements.toId64Array()).to.have.lengthOf(1).and.to.include(elementKey.id);
expect([...imodel.selectionSet.elements])
.to.have.lengthOf(1)
.and.to.include(elementKey.id);
});

render(<UnifiedSelectionComponent imodel={imodel} />);

Presentation.selection.replaceSelection("", imodel, new KeySet([elementKey!]));
await waitFor(() => {
expect(imodel.hilited.models.isEmpty).to.be.true;
expect(imodel.hilited.subcategories.isEmpty).to.be.true;
expect(imodel.hilited.elements.toId64Array()).to.have.lengthOf(1).and.to.include(elementKey.id);
expect([...imodel.selectionSet.elements])
.to.have.lengthOf(1)
.and.to.include(elementKey.id);
});
});

it("hilites transient element", async function () {
// eslint-disable-next-line deprecation/deprecation
const imodel = await buildTestIModel(this, async (_) => {});
const transientElementKey = { className: TRANSIENT_ELEMENT_CLASSNAME, id: Id64.fromLocalAndBriefcaseIds(123, 0xffffff) };
await using(new ViewportSelectionHandler({ imodel }), async (_) => {
Presentation.selection.replaceSelection("", imodel, new KeySet([transientElementKey]));
await waitFor(() => {
expect(imodel.hilited.models.isEmpty).to.be.true;
expect(imodel.hilited.subcategories.isEmpty).to.be.true;
expect(imodel.hilited.elements.toId64Array()).to.have.lengthOf(1).and.to.include(transientElementKey.id);
expect([...imodel.selectionSet.elements])
.to.have.lengthOf(1)
.and.to.include(transientElementKey.id);
});

render(<UnifiedSelectionComponent imodel={imodel} />);

Presentation.selection.replaceSelection("", imodel, new KeySet([transientElementKey]));
await waitFor(() => {
expect(imodel.hilited.models.isEmpty).to.be.true;
expect(imodel.hilited.subcategories.isEmpty).to.be.true;
expect(imodel.hilited.elements.toId64Array()).to.have.lengthOf(1).and.to.include(transientElementKey.id);
expect([...imodel.selectionSet.elements])
.to.have.lengthOf(1)
.and.to.include(transientElementKey.id);
});
});

it("hilites transient element after removing and adding it back", async function () {
// eslint-disable-next-line deprecation/deprecation
const imodel = await buildTestIModel(this, async (_) => {});
const transientElementKey = { className: TRANSIENT_ELEMENT_CLASSNAME, id: Id64.fromLocalAndBriefcaseIds(123, 0xffffff) };
await using(new ViewportSelectionHandler({ imodel }), async (_) => {
// set up the selection to contain a transient element
Presentation.selection.replaceSelection("", imodel, new KeySet([transientElementKey]));
await waitFor(() => {
expect(imodel.hilited.elements.toId64Array()).to.have.lengthOf(1).and.to.include(transientElementKey.id);
expect([...imodel.selectionSet.elements])
.to.have.lengthOf(1)
.and.to.include(transientElementKey.id);
});

// remove and add back the transient element
imodel.selectionSet.remove(transientElementKey.id);
imodel.selectionSet.replace(transientElementKey.id);
render(<UnifiedSelectionComponent imodel={imodel} />);

// expect the transient element to be both hilited and selected
await waitFor(() => {
expect(imodel.hilited.elements.toId64Array()).to.have.lengthOf(1).and.to.include(transientElementKey.id);
expect([...imodel.selectionSet.elements])
.to.have.lengthOf(1)
.and.to.include(transientElementKey.id);
});
// set up the selection to contain a transient element
Presentation.selection.replaceSelection("", imodel, new KeySet([transientElementKey]));
await waitFor(() => {
expect(imodel.hilited.elements.toId64Array()).to.have.lengthOf(1).and.to.include(transientElementKey.id);
expect([...imodel.selectionSet.elements])
.to.have.lengthOf(1)
.and.to.include(transientElementKey.id);
});

// remove and add back the transient element
imodel.selectionSet.remove(transientElementKey.id);
imodel.selectionSet.replace(transientElementKey.id);

// expect the transient element to be both hilited and selected
await waitFor(() => {
expect(imodel.hilited.elements.toId64Array()).to.have.lengthOf(1).and.to.include(transientElementKey.id);
expect([...imodel.selectionSet.elements])
.to.have.lengthOf(1)
.and.to.include(transientElementKey.id);
});
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import {
mergeProviders,
} from "@itwin/presentation-hierarchies";
import { createBisInstanceLabelSelectClauseFactory, ECSqlBinding, InstanceKey } from "@itwin/presentation-shared";
import { createFileNameFromString } from "@itwin/presentation-testing/lib/cjs/presentation-testing/InternalUtils.js";
import { createFileNameFromString } from "@itwin/presentation-testing";
import { buildIModel, importSchema, withECDb } from "../IModelUtils.js";
import { initialize, terminate } from "../IntegrationTests.js";
import { NodeValidators, validateHierarchy } from "./HierarchyValidation.js";
Expand Down
2 changes: 1 addition & 1 deletion apps/full-stack-tests/src/hierarchies/Update.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import { ECSchemaRpcImpl } from "@itwin/ecschema-rpcinterface-impl";
import { registerTxnListeners } from "@itwin/presentation-core-interop";
import { createNodesQueryClauseFactory, HierarchyDefinition } from "@itwin/presentation-hierarchies";
import { createBisInstanceLabelSelectClauseFactory, ECSql } from "@itwin/presentation-shared";
import { createFileNameFromString, setupOutputFileLocation } from "@itwin/presentation-testing/lib/cjs/presentation-testing/InternalUtils.js";
import { createFileNameFromString, setupOutputFileLocation } from "@itwin/presentation-testing";
import { NodeValidators, validateHierarchyLevel } from "./HierarchyValidation.js";
import { createClassECSqlSelector, createIModelAccess, createProvider } from "./Utils.js";

Expand Down
1 change: 0 additions & 1 deletion apps/performance-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"benchmark:hierarchies": "npm run test:hierarchies -- -O BENCHMARK_OUTPUT_PATH=./hierarchies-benchmark.json",
"benchmark:unified-selection": "npm run test:unified-selection -- -O BENCHMARK_OUTPUT_PATH=./unified-selection-benchmark.json",
"build": "tsc",
"build:watch": "tsc -w",
"clean": "rimraf lib temp",
"docs": "betools extract --fileExt=ts --extractFrom=./src --recursive --out=./build/docs/extract",
"lint": "eslint \"./src/**/*.ts\"",
Expand Down
2 changes: 1 addition & 1 deletion packages/components/.mocharc.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"require": ["ignore-styles", "./lib/cjs/test/setup"],
"require": ["ignore-styles", "./lib/cjs/test/setup.js"],
"checkLeaks": true,
"global": ["IS_REACT_ACT_ENVIRONMENT", "__iui"],
"timeout": 60000,
Expand Down
4 changes: 1 addition & 3 deletions packages/components/.nycrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@
"functions": 100,
"branches": 100,
"lines": 100,
"include": ["src/**/*", "lib/cjs/**/*"],
"exclude": ["src/presentation-components.ts", "src/test/**", "lib/cjs/test/**"],
"extension": [".ts", ".tsx"],
"include": ["src/presentation-components/**/*", "lib/cjs/presentation-components/**/*"],
"temp-dir": "./lib/test/coverage/.nyc_output",
"report-dir": "./lib/test/coverage",
"reporter": ["text-summary", "lcov", "cobertura"]
Expand Down
Loading

0 comments on commit 24c6553

Please sign in to comment.