mirror of
https://github.com/bitwarden/browser.git
synced 2025-02-01 23:01:28 +01:00
[PM-16917] Remove jest-extended dependency (#12798)
* add toContainPartialObjects matcher (replacing toIncludeAllPartialMembers from jest-extended) * replace jest-extended matchers with equivalent default matchers
This commit is contained in:
parent
bdab4aa939
commit
8c13ea894b
2
.github/renovate.json
vendored
2
.github/renovate.json
vendored
@ -210,10 +210,10 @@
|
||||
"eslint-plugin-storybook",
|
||||
"eslint-plugin-tailwindcss",
|
||||
"husky",
|
||||
"jest-extended",
|
||||
"jest-junit",
|
||||
"jest-mock-extended",
|
||||
"jest-preset-angular",
|
||||
"jest-diff",
|
||||
"lint-staged",
|
||||
"ts-jest"
|
||||
],
|
||||
|
@ -152,7 +152,7 @@ describe("VaultHeaderV2Component", () => {
|
||||
it("defaults the initial state to true", (done) => {
|
||||
// The initial value of the `state$` variable above is undefined
|
||||
component["initialDisclosureVisibility$"].subscribe((initialVisibility) => {
|
||||
expect(initialVisibility).toBeTrue();
|
||||
expect(initialVisibility).toBe(true);
|
||||
done();
|
||||
});
|
||||
|
||||
|
@ -179,7 +179,7 @@ describe("ViewV2Component", () => {
|
||||
|
||||
flush(); // Resolve all promises
|
||||
|
||||
expect(doAutofill).toHaveBeenCalledOnce();
|
||||
expect(doAutofill).toHaveBeenCalledTimes(1);
|
||||
}));
|
||||
|
||||
it('invokes `copy` when action="copy-username"', fakeAsync(() => {
|
||||
@ -187,7 +187,7 @@ describe("ViewV2Component", () => {
|
||||
|
||||
flush(); // Resolve all promises
|
||||
|
||||
expect(copy).toHaveBeenCalledOnce();
|
||||
expect(copy).toHaveBeenCalledTimes(1);
|
||||
}));
|
||||
|
||||
it('invokes `copy` when action="copy-password"', fakeAsync(() => {
|
||||
@ -195,7 +195,7 @@ describe("ViewV2Component", () => {
|
||||
|
||||
flush(); // Resolve all promises
|
||||
|
||||
expect(copy).toHaveBeenCalledOnce();
|
||||
expect(copy).toHaveBeenCalledTimes(1);
|
||||
}));
|
||||
|
||||
it('invokes `copy` when action="copy-totp"', fakeAsync(() => {
|
||||
@ -203,7 +203,7 @@ describe("ViewV2Component", () => {
|
||||
|
||||
flush(); // Resolve all promises
|
||||
|
||||
expect(copy).toHaveBeenCalledOnce();
|
||||
expect(copy).toHaveBeenCalledTimes(1);
|
||||
}));
|
||||
|
||||
it("closes the popout after a load action", fakeAsync(() => {
|
||||
@ -218,9 +218,9 @@ describe("ViewV2Component", () => {
|
||||
|
||||
flush(); // Resolve all promises
|
||||
|
||||
expect(doAutofill).toHaveBeenCalledOnce();
|
||||
expect(doAutofill).toHaveBeenCalledTimes(1);
|
||||
expect(focusSpy).toHaveBeenCalledWith(99);
|
||||
expect(closeSpy).toHaveBeenCalledOnce();
|
||||
expect(closeSpy).toHaveBeenCalledTimes(1);
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
@ -488,7 +488,7 @@ describe("VaultPopupListFiltersService", () => {
|
||||
state$.next(true);
|
||||
|
||||
service.filterVisibilityState$.subscribe((filterVisibility) => {
|
||||
expect(filterVisibility).toBeTrue();
|
||||
expect(filterVisibility).toBe(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
@ -496,7 +496,7 @@ describe("VaultPopupListFiltersService", () => {
|
||||
it("updates stored filter state", async () => {
|
||||
await service.updateFilterVisibility(false);
|
||||
|
||||
expect(update).toHaveBeenCalledOnce();
|
||||
expect(update).toHaveBeenCalledTimes(1);
|
||||
// Get callback passed to `update`
|
||||
const updateCallback = update.mock.calls[0][0];
|
||||
expect(updateCallback()).toBe(false);
|
||||
|
@ -91,7 +91,7 @@ describe("DefaultvNextCollectionService", () => {
|
||||
|
||||
// Assert emitted values
|
||||
expect(result.length).toBe(2);
|
||||
expect(result).toIncludeAllPartialMembers([
|
||||
expect(result).toContainPartialObjects([
|
||||
{
|
||||
id: collection1.id,
|
||||
name: "DEC_NAME_" + collection1.id,
|
||||
@ -167,7 +167,7 @@ describe("DefaultvNextCollectionService", () => {
|
||||
const result = await firstValueFrom(collectionService.encryptedCollections$(userId));
|
||||
|
||||
expect(result.length).toBe(2);
|
||||
expect(result).toIncludeAllPartialMembers([
|
||||
expect(result).toContainPartialObjects([
|
||||
{
|
||||
id: collection1.id,
|
||||
name: makeEncString("ENC_NAME_" + collection1.id),
|
||||
@ -205,7 +205,7 @@ describe("DefaultvNextCollectionService", () => {
|
||||
|
||||
const result = await firstValueFrom(collectionService.encryptedCollections$(userId));
|
||||
expect(result.length).toBe(3);
|
||||
expect(result).toIncludeAllPartialMembers([
|
||||
expect(result).toContainPartialObjects([
|
||||
{
|
||||
id: collection1.id,
|
||||
name: makeEncString("UPDATED_ENC_NAME_" + collection1.id),
|
||||
@ -230,7 +230,7 @@ describe("DefaultvNextCollectionService", () => {
|
||||
|
||||
const result = await firstValueFrom(collectionService.encryptedCollections$(userId));
|
||||
expect(result.length).toBe(1);
|
||||
expect(result).toIncludeAllPartialMembers([
|
||||
expect(result).toContainPartialObjects([
|
||||
{
|
||||
id: collection1.id,
|
||||
name: makeEncString("ENC_NAME_" + collection1.id),
|
||||
@ -253,7 +253,7 @@ describe("DefaultvNextCollectionService", () => {
|
||||
|
||||
const result = await firstValueFrom(collectionService.encryptedCollections$(userId));
|
||||
expect(result.length).toBe(1);
|
||||
expect(result).toIncludeAllPartialMembers([
|
||||
expect(result).toContainPartialObjects([
|
||||
{
|
||||
id: newCollection3.id,
|
||||
name: makeEncString("ENC_NAME_" + newCollection3.id),
|
||||
|
@ -1,6 +1,10 @@
|
||||
import { webcrypto } from "crypto";
|
||||
|
||||
import { addCustomMatchers } from "@bitwarden/common/spec";
|
||||
import "jest-preset-angular/setup-jest";
|
||||
|
||||
addCustomMatchers();
|
||||
|
||||
Object.defineProperty(window, "CSS", { value: null });
|
||||
Object.defineProperty(window, "getComputedStyle", {
|
||||
value: () => {
|
||||
|
@ -8,6 +8,6 @@
|
||||
"@bitwarden/key-management": ["../key-management/src"]
|
||||
}
|
||||
},
|
||||
"include": ["src", "spec"],
|
||||
"include": ["src", "spec", "../../libs/common/custom-matchers.d.ts"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
|
@ -1,16 +1,12 @@
|
||||
import * as matchers from "jest-extended";
|
||||
|
||||
import { toBeFulfilled, toBeResolved, toBeRejected } from "./promise-fulfilled";
|
||||
import { toAlmostEqual } from "./to-almost-equal";
|
||||
import { toContainPartialObjects } from "./to-contain-partial-objects";
|
||||
import { toEqualBuffer } from "./to-equal-buffer";
|
||||
|
||||
export * from "./to-equal-buffer";
|
||||
export * from "./to-almost-equal";
|
||||
export * from "./promise-fulfilled";
|
||||
|
||||
// add all jest-extended matchers
|
||||
expect.extend(matchers);
|
||||
|
||||
export function addCustomMatchers() {
|
||||
expect.extend({
|
||||
toEqualBuffer: toEqualBuffer,
|
||||
@ -18,6 +14,7 @@ export function addCustomMatchers() {
|
||||
toBeFulfilled: toBeFulfilled,
|
||||
toBeResolved: toBeResolved,
|
||||
toBeRejected: toBeRejected,
|
||||
toContainPartialObjects,
|
||||
});
|
||||
}
|
||||
|
||||
@ -59,4 +56,9 @@ export interface CustomMatchers<R = unknown> {
|
||||
* @returns CustomMatcherResult indicating whether or not the test passed
|
||||
*/
|
||||
toBeRejected(withinMs?: number): Promise<R>;
|
||||
/**
|
||||
* Matches if the received array contains all the expected objects using partial matching (expect.objectContaining).
|
||||
* @param expected An array of partial objects that should be contained in the received array.
|
||||
*/
|
||||
toContainPartialObjects<T>(expected: Array<T>): R;
|
||||
}
|
||||
|
77
libs/common/spec/matchers/to-contain-partial-objects.spec.ts
Normal file
77
libs/common/spec/matchers/to-contain-partial-objects.spec.ts
Normal file
@ -0,0 +1,77 @@
|
||||
describe("toContainPartialObjects", () => {
|
||||
describe("matches", () => {
|
||||
it("if the array only contains the partial objects", () => {
|
||||
const actual = [
|
||||
{
|
||||
id: 1,
|
||||
name: "foo",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "bar",
|
||||
},
|
||||
];
|
||||
|
||||
const expected = [{ id: 1 }, { id: 2 }];
|
||||
|
||||
expect(actual).toContainPartialObjects(expected);
|
||||
});
|
||||
|
||||
it("if the array contains the partial objects and other objects", () => {
|
||||
const actual = [
|
||||
{
|
||||
id: 1,
|
||||
name: "foo",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "bar",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "baz",
|
||||
},
|
||||
];
|
||||
|
||||
const expected = [{ id: 1 }, { id: 2 }];
|
||||
|
||||
expect(actual).toContainPartialObjects(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe("doesn't match", () => {
|
||||
it("if the array does not contain any partial objects", () => {
|
||||
const actual = [
|
||||
{
|
||||
id: 1,
|
||||
name: "foo",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "bar",
|
||||
},
|
||||
];
|
||||
|
||||
const expected = [{ id: 1, name: "Foo" }];
|
||||
|
||||
expect(actual).not.toContainPartialObjects(expected);
|
||||
});
|
||||
|
||||
it("if the array contains some but not all partial objects", () => {
|
||||
const actual = [
|
||||
{
|
||||
id: 1,
|
||||
name: "foo",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "bar",
|
||||
},
|
||||
];
|
||||
|
||||
const expected = [{ id: 2 }, { id: 3 }];
|
||||
|
||||
expect(actual).not.toContainPartialObjects(expected);
|
||||
});
|
||||
});
|
||||
});
|
31
libs/common/spec/matchers/to-contain-partial-objects.ts
Normal file
31
libs/common/spec/matchers/to-contain-partial-objects.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import { EOL } from "os";
|
||||
|
||||
import { diff } from "jest-diff";
|
||||
|
||||
export const toContainPartialObjects: jest.CustomMatcher = function (
|
||||
received: Array<any>,
|
||||
expected: Array<any>,
|
||||
) {
|
||||
const matched = this.equals(
|
||||
received,
|
||||
expect.arrayContaining(expected.map((e) => expect.objectContaining(e))),
|
||||
);
|
||||
|
||||
if (matched) {
|
||||
return {
|
||||
message: () =>
|
||||
"Expected the received array NOT to include partial matches for all expected objects." +
|
||||
EOL +
|
||||
diff(expected, received),
|
||||
pass: true,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
message: () =>
|
||||
"Expected the received array to contain partial matches for all expected objects." +
|
||||
EOL +
|
||||
diff(expected, received),
|
||||
pass: false,
|
||||
};
|
||||
};
|
@ -184,7 +184,7 @@ describe("KeyServiceLegacyEncryptorProvider", () => {
|
||||
|
||||
singleUserId$.complete();
|
||||
|
||||
expect(completed).toBeTrue();
|
||||
expect(completed).toBe(true);
|
||||
});
|
||||
|
||||
it("completes when `userKey$` emits a falsy value after emitting a truthy value", () => {
|
||||
@ -199,7 +199,7 @@ describe("KeyServiceLegacyEncryptorProvider", () => {
|
||||
|
||||
userKey$.next(null);
|
||||
|
||||
expect(completed).toBeTrue();
|
||||
expect(completed).toBe(true);
|
||||
});
|
||||
|
||||
it("completes once `dependencies.singleUserId$` emits and `userKey$` completes", () => {
|
||||
@ -214,7 +214,7 @@ describe("KeyServiceLegacyEncryptorProvider", () => {
|
||||
|
||||
userKey$.complete();
|
||||
|
||||
expect(completed).toBeTrue();
|
||||
expect(completed).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@ -445,7 +445,7 @@ describe("KeyServiceLegacyEncryptorProvider", () => {
|
||||
|
||||
singleOrganizationId$.complete();
|
||||
|
||||
expect(completed).toBeTrue();
|
||||
expect(completed).toBe(true);
|
||||
});
|
||||
|
||||
it("completes when `orgKeys$` emits a falsy value after emitting a truthy value", () => {
|
||||
@ -466,7 +466,7 @@ describe("KeyServiceLegacyEncryptorProvider", () => {
|
||||
orgKey$.next(OrgRecords);
|
||||
orgKey$.next(null);
|
||||
|
||||
expect(completed).toBeTrue();
|
||||
expect(completed).toBe(true);
|
||||
});
|
||||
|
||||
it("completes once `dependencies.singleOrganizationId$` emits and `userKey$` completes", () => {
|
||||
@ -486,7 +486,7 @@ describe("KeyServiceLegacyEncryptorProvider", () => {
|
||||
|
||||
orgKey$.complete();
|
||||
|
||||
expect(completed).toBeTrue();
|
||||
expect(completed).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -56,7 +56,7 @@ describe("errorOnChange", () => {
|
||||
|
||||
source$.complete();
|
||||
|
||||
expect(complete).toBeTrue();
|
||||
expect(complete).toBe(true);
|
||||
});
|
||||
|
||||
it("errors when the input changes", async () => {
|
||||
|
@ -77,7 +77,7 @@ describe("Folder Service", () => {
|
||||
const result = await firstValueFrom(folderService.folders$(mockUserId));
|
||||
|
||||
expect(result.length).toBe(2);
|
||||
expect(result).toIncludeAllPartialMembers([
|
||||
expect(result).toContainPartialObjects([
|
||||
{ id: "1", name: makeEncString("ENC_STRING_1") },
|
||||
{ id: "2", name: makeEncString("ENC_STRING_2") },
|
||||
]);
|
||||
@ -98,7 +98,7 @@ describe("Folder Service", () => {
|
||||
const result = await firstValueFrom(folderService.folderViews$(mockUserId));
|
||||
|
||||
expect(result.length).toBe(3);
|
||||
expect(result).toIncludeAllPartialMembers([
|
||||
expect(result).toContainPartialObjects([
|
||||
{ id: "1", name: "DEC" },
|
||||
{ id: "2", name: "DEC" },
|
||||
{ name: "No Folder" },
|
||||
|
24
package-lock.json
generated
24
package-lock.json
generated
@ -151,7 +151,7 @@
|
||||
"html-webpack-injector": "1.1.4",
|
||||
"html-webpack-plugin": "5.6.3",
|
||||
"husky": "9.1.4",
|
||||
"jest-extended": "4.0.2",
|
||||
"jest-diff": "29.7.0",
|
||||
"jest-junit": "16.0.0",
|
||||
"jest-mock-extended": "3.0.7",
|
||||
"jest-preset-angular": "14.1.1",
|
||||
@ -20729,28 +20729,6 @@
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jest-extended": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/jest-extended/-/jest-extended-4.0.2.tgz",
|
||||
"integrity": "sha512-FH7aaPgtGYHc9mRjriS0ZEHYM5/W69tLrFTIdzm+yJgeoCmmrSB/luSfMSqWP9O29QWHPEmJ4qmU6EwsZideog==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"jest-diff": "^29.0.0",
|
||||
"jest-get-type": "^29.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"jest": ">=27.2.5"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"jest": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/jest-get-type": {
|
||||
"version": "29.6.3",
|
||||
"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz",
|
||||
|
@ -111,7 +111,7 @@
|
||||
"html-webpack-injector": "1.1.4",
|
||||
"html-webpack-plugin": "5.6.3",
|
||||
"husky": "9.1.4",
|
||||
"jest-extended": "4.0.2",
|
||||
"jest-diff": "29.7.0",
|
||||
"jest-junit": "16.0.0",
|
||||
"jest-mock-extended": "3.0.7",
|
||||
"jest-preset-angular": "14.1.1",
|
||||
|
Loading…
Reference in New Issue
Block a user