Remove dead code (#9035)

This commit is contained in:
Šimon Brandner 2022-07-11 07:52:44 +02:00 committed by GitHub
parent d1928d2cb3
commit 19e514d83c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 6 additions and 412 deletions

View file

@ -109,33 +109,6 @@ export function unicodeToShortcode(char: string): string {
return shortcodes?.length ? `:${shortcodes[0]}:` : ''; return shortcodes?.length ? `:${shortcodes[0]}:` : '';
} }
export function processHtmlForSending(html: string): string {
const contentDiv = document.createElement('div');
contentDiv.innerHTML = html;
if (contentDiv.children.length === 0) {
return contentDiv.innerHTML;
}
let contentHTML = "";
for (let i = 0; i < contentDiv.children.length; i++) {
const element = contentDiv.children[i];
if (element.tagName.toLowerCase() === 'p') {
contentHTML += element.innerHTML;
// Don't add a <br /> for the last <p>
if (i !== contentDiv.children.length - 1) {
contentHTML += '<br />';
}
} else {
const temp = document.createElement('div');
temp.appendChild(element.cloneNode(true));
contentHTML += temp.innerHTML;
}
}
return contentHTML;
}
/* /*
* Given an untrusted HTML string, return a React node with an sanitized version * Given an untrusted HTML string, return a React node with an sanitized version
* of that HTML. * of that HTML.

View file

@ -83,11 +83,3 @@ export function isOnlyCtrlOrCmdKeyEvent(ev) {
return ev.ctrlKey && !ev.altKey && !ev.metaKey && !ev.shiftKey; return ev.ctrlKey && !ev.altKey && !ev.metaKey && !ev.shiftKey;
} }
} }
export function isOnlyCtrlOrCmdIgnoreShiftKeyEvent(ev) {
if (IS_MAC) {
return ev.metaKey && !ev.altKey && !ev.ctrlKey;
} else {
return ev.ctrlKey && !ev.altKey && !ev.metaKey;
}
}

View file

@ -35,38 +35,6 @@ export enum RoomNotifState {
Mute = 'mute', Mute = 'mute',
} }
export const BADGE_STATES = [RoomNotifState.AllMessages, RoomNotifState.AllMessagesLoud];
export const MENTION_BADGE_STATES = [...BADGE_STATES, RoomNotifState.MentionsOnly];
export function shouldShowNotifBadge(roomNotifState: RoomNotifState): boolean {
return BADGE_STATES.includes(roomNotifState);
}
export function shouldShowMentionBadge(roomNotifState: RoomNotifState): boolean {
return MENTION_BADGE_STATES.includes(roomNotifState);
}
export function aggregateNotificationCount(rooms: Room[]): {count: number, highlight: boolean} {
return rooms.reduce<{count: number, highlight: boolean}>((result, room) => {
const roomNotifState = getRoomNotifsState(room.roomId);
const highlight = room.getUnreadNotificationCount(NotificationCountType.Highlight) > 0;
// use helper method to include highlights in the previous version of the room
const notificationCount = getUnreadNotificationCount(room);
const notifBadges = notificationCount > 0 && shouldShowNotifBadge(roomNotifState);
const mentionBadges = highlight && shouldShowMentionBadge(roomNotifState);
const badges = notifBadges || mentionBadges;
if (badges) {
result.count += notificationCount;
if (highlight) {
result.highlight = true;
}
}
return result;
}, { count: 0, highlight: false });
}
export function getRoomNotifsState(roomId: string): RoomNotifState { export function getRoomNotifsState(roomId: string): RoomNotifState {
if (MatrixClientPeg.get().isGuest()) return RoomNotifState.AllMessages; if (MatrixClientPeg.get().isGuest()) return RoomNotifState.AllMessages;

View file

@ -44,25 +44,6 @@ export function getDisplayAliasForAliasSet(canonicalAlias: string, altAliases: s
return canonicalAlias || altAliases?.[0]; return canonicalAlias || altAliases?.[0];
} }
export function looksLikeDirectMessageRoom(room: Room, myUserId: string): boolean {
const myMembership = room.getMyMembership();
const me = room.getMember(myUserId);
if (myMembership == "join" || myMembership === "ban" || (me && me.isKicked())) {
// Used to split rooms via tags
const tagNames = Object.keys(room.tags);
// Used for 1:1 direct messages
// Show 1:1 chats in separate "Direct Messages" section as long as they haven't
// been moved to a different tag section
const totalMemberCount = room.currentState.getJoinedMemberCount() +
room.currentState.getInvitedMemberCount();
if (totalMemberCount === 2 && !tagNames.length) {
return true;
}
}
return false;
}
export function guessAndSetDMRoom(room: Room, isDirect: boolean): Promise<void> { export function guessAndSetDMRoom(room: Room, isDirect: boolean): Promise<void> {
let newTarget; let newTarget;
if (isDirect) { if (isDirect) {

View file

@ -752,7 +752,3 @@ export function stopListening(): void {
logger.error(e); logger.error(e);
} }
} }
export function setOpenManagerUrl(url: string): void {
openManagerUrl = url;
}

View file

@ -24,24 +24,6 @@ export enum AddressType {
MatrixRoomId = "mx-room-id", MatrixRoomId = "mx-room-id",
} }
export const addressTypes = [AddressType.Email, AddressType.MatrixRoomId, AddressType.MatrixUserId];
// PropType definition for an object describing
// an address that can be invited to a room (which
// could be a third party identifier or a matrix ID)
// along with some additional information about the
// address / target.
export interface IUserAddress {
addressType: AddressType;
address: string;
displayName?: string;
avatarMxc?: string;
// true if the address is known to be a valid address (eg. is a real
// user we've seen) or false otherwise (eg. is just an address the
// user has entered)
isKnown?: boolean;
}
export function getAddressType(inputText: string): AddressType | null { export function getAddressType(inputText: string): AddressType | null {
if (emailRegex.test(inputText)) { if (emailRegex.test(inputText)) {
return AddressType.Email; return AddressType.Email;

View file

@ -570,7 +570,6 @@ export function createMenu(ElementClass, props) {
// re-export the semantic helper components for simplicity // re-export the semantic helper components for simplicity
export { ContextMenuButton } from "../../accessibility/context_menu/ContextMenuButton"; export { ContextMenuButton } from "../../accessibility/context_menu/ContextMenuButton";
export { ContextMenuTooltipButton } from "../../accessibility/context_menu/ContextMenuTooltipButton"; export { ContextMenuTooltipButton } from "../../accessibility/context_menu/ContextMenuTooltipButton";
export { MenuGroup } from "../../accessibility/context_menu/MenuGroup";
export { MenuItem } from "../../accessibility/context_menu/MenuItem"; export { MenuItem } from "../../accessibility/context_menu/MenuItem";
export { MenuItemCheckbox } from "../../accessibility/context_menu/MenuItemCheckbox"; export { MenuItemCheckbox } from "../../accessibility/context_menu/MenuItemCheckbox";
export { MenuItemRadio } from "../../accessibility/context_menu/MenuItemRadio"; export { MenuItemRadio } from "../../accessibility/context_menu/MenuItemRadio";

View file

@ -37,7 +37,7 @@ interface IProps {
hasCancel?: boolean; hasCancel?: boolean;
} }
const AnalyticsLearnMoreDialog: React.FC<IProps> = ({ export const AnalyticsLearnMoreDialog: React.FC<IProps> = ({
onFinished, onFinished,
analyticsOwner, analyticsOwner,
privacyPolicyUrl, privacyPolicyUrl,
@ -105,5 +105,3 @@ export const showDialog = (props: Omit<IProps, "cookiePolicyUrl" | "analyticsOwn
...props, ...props,
}, "mx_AnalyticsLearnMoreDialog_wrapper"); }, "mx_AnalyticsLearnMoreDialog_wrapper");
}; };
export default AnalyticsLearnMoreDialog;

View file

@ -104,16 +104,3 @@ export const shareLocation = (
handleShareError(error, openMenu, shareType); handleShareError(error, openMenu, shareType);
} }
}; };
export function textForLocation(
uri: string,
ts: number,
description: string | null,
): string {
const date = new Date(ts).toISOString();
if (description) {
return `Location "${description}" ${uri} at ${date}`;
} else {
return `Location ${uri} at ${date}`;
}
}

View file

@ -45,5 +45,3 @@ export const CollapsibleButton = ({ title, children, className, iconClassName, .
{ children } { children }
</AccessibleTooltipButton>; </AccessibleTooltipButton>;
}; };
export default CollapsibleButton;

View file

@ -63,5 +63,3 @@ export const KeyboardShortcut: React.FC<IKeyboardShortcutProps> = ({ value }) =>
<KeyboardKey name={value.key} last /> <KeyboardKey name={value.key} last />
</div>; </div>;
}; };
export default KeyboardShortcut;

View file

@ -371,5 +371,3 @@ const SpaceTreeLevel: React.FC<ITreeLevelProps> = ({
}) } }) }
</ul>; </ul>;
}; };
export default SpaceTreeLevel;

View file

@ -14,16 +14,6 @@
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/**
* Defines the constructor of a canvas based room effect
*/
export interface ICanvasEffectConstructable {
/**
* @param {{[key:string]:any}} options? Optional animation options
* @returns ICanvasEffect Returns a new instance of the canvas effect
*/
new(options?: { [key: string]: any }): ICanvasEffect;
}
/** /**
* Defines the interface of a canvas based room effect * Defines the interface of a canvas based room effect

View file

@ -1,19 +0,0 @@
/*
Copyright 2022 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { MatrixClient, MatrixEvent } from "matrix-js-sdk/src/matrix";
export type ActionableEventTransformFunction = (event: MatrixEvent, cli: MatrixClient) => MatrixEvent | null;

View file

@ -1,19 +0,0 @@
/*
Copyright 2022 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { MatrixClient, MatrixEvent } from "matrix-js-sdk/src/matrix";
export type ActionableEventTransformFunction = (event: MatrixEvent, cli: MatrixClient) => MatrixEvent | null;

View file

@ -21,7 +21,6 @@ import linkifyElement from 'linkify-element';
import linkifyString from 'linkify-string'; import linkifyString from 'linkify-string';
import { RoomMember } from 'matrix-js-sdk/src/models/room-member'; import { RoomMember } from 'matrix-js-sdk/src/models/room-member';
import { baseUrl } from "./utils/permalinks/MatrixToPermalinkConstructor";
import { import {
parsePermalink, parsePermalink,
tryTransformEntityToPermalink, tryTransformEntityToPermalink,
@ -144,11 +143,6 @@ export const ELEMENT_URL_PATTERN =
"(?:app|beta|staging|develop)\\.element\\.io/" + "(?:app|beta|staging|develop)\\.element\\.io/" +
")(#.*)"; ")(#.*)";
export const MATRIXTO_URL_PATTERN = "^(?:https?://)?(?:www\\.)?matrix\\.to/#/(([#@!+]).*)";
export const MATRIXTO_MD_LINK_PATTERN =
'\\[([^\\]]*)\\]\\((?:https?://)?(?:www\\.)?matrix\\.to/#/([#@!+][^\\)]*)\\)';
export const MATRIXTO_BASE_URL= baseUrl;
export const options = { export const options = {
events: function(href: string, type: Type | string): Partial<GlobalEventHandlers> { events: function(href: string, type: Type | string): Partial<GlobalEventHandlers> {
switch (type) { switch (type) {

View file

@ -24,9 +24,6 @@ export interface IContentRules {
externalRules: IAnnotatedPushRule[]; externalRules: IAnnotatedPushRule[];
} }
export const SCOPE = "global";
export const KIND = "content";
export class ContentRules { export class ContentRules {
/** /**
* Extract the keyword rules from a list of rules, and parse them * Extract the keyword rules from a list of rules, and parse them

View file

@ -99,8 +99,6 @@ interface IHandlerMap {
[level: SettingLevel]: SettingsHandler; [level: SettingLevel]: SettingsHandler;
} }
export type LabsFeatureState = "labs" | "disable" | "enable" | string;
/** /**
* Controls and manages application settings by providing varying levels at which the * Controls and manages application settings by providing varying levels at which the
* setting value may be specified. The levels are then used to determine what the setting * setting value may be specified. The levels are then used to determine what the setting

View file

@ -27,11 +27,6 @@ export function isSelf(event: MatrixEvent): boolean {
return event.getSender() === selfUserId; return event.getSender() === selfUserId;
} }
export function isSelfTarget(event: MatrixEvent): boolean {
const selfUserId = MatrixClientPeg.get().getUserId();
return event.getStateKey() === selfUserId;
}
export function shouldPrefixMessagesIn(roomId: string, tagId: TagID): boolean { export function shouldPrefixMessagesIn(roomId: string, tagId: TagID): boolean {
if (tagId !== DefaultTagID.DM) return true; if (tagId !== DefaultTagID.DM) return true;
@ -44,7 +39,3 @@ export function shouldPrefixMessagesIn(roomId: string, tagId: TagID): boolean {
export function getSenderName(event: MatrixEvent): string { export function getSenderName(event: MatrixEvent): string {
return event.sender ? event.sender.name : event.getSender(); return event.sender ? event.sender.name : event.getSender();
} }
export function getTargetName(event: MatrixEvent): string {
return event.target ? event.target.name : event.getStateKey();
}

View file

@ -1,38 +0,0 @@
/*
Copyright 2016 - 2021 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { ReceiptType } from "matrix-js-sdk/src/@types/read_receipts";
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
/**
* Given MatrixEvent containing receipts, return the first
* read receipt from the given user ID, or null if no such
* receipt exists.
*
* @param {Object} receiptEvent A Matrix Event
* @param {string} userId A user ID
* @returns {Object} Read receipt
*/
export function findReadReceiptFromUserId(receiptEvent: MatrixEvent, userId: string): object | null {
const receiptKeys = Object.keys(receiptEvent.getContent());
for (let i = 0; i < receiptKeys.length; ++i) {
const rcpt = receiptEvent.getContent()[receiptKeys[i]];
if (rcpt[ReceiptType.Read]?.[userId]) return rcpt;
if (rcpt[ReceiptType.ReadPrivate]?.[userId]) return rcpt;
}
return null;
}

View file

@ -1,36 +0,0 @@
/*
Copyright 2021 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* Fetch an image using the best available method based on browser compatibility
* @param url the URL of the image to fetch
* @returns a canvas drawable object
*/
export async function getDrawable(url: string): Promise<CanvasImageSource> {
if ('createImageBitmap' in window) {
const response = await fetch(url);
const blob = await response.blob();
return createImageBitmap(blob);
} else {
return new Promise<HTMLImageElement>((resolve, reject) => {
const img = document.createElement("img");
img.crossOrigin = "anonymous";
img.onload = () => resolve(img);
img.onerror = (e) => reject(e);
img.src = url;
});
}
}

View file

@ -14,11 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { arrayDiff, arrayUnion, arrayIntersection } from "./arrays"; import { arrayDiff, arrayIntersection } from "./arrays";
export function iterableUnion<T>(a: Iterable<T>, b: Iterable<T>): Iterable<T> {
return arrayUnion(Array.from(a), Array.from(b));
}
export function iterableIntersection<T>(a: Iterable<T>, b: Iterable<T>): Iterable<T> { export function iterableIntersection<T>(a: Iterable<T>, b: Iterable<T>): Iterable<T> {
return arrayIntersection(Array.from(a), Array.from(b)); return arrayIntersection(Array.from(a), Array.from(b));

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import { arrayDiff, arrayUnion, arrayIntersection } from "./arrays"; import { arrayDiff, arrayIntersection } from "./arrays";
/** /**
* Determines the keys added, changed, and removed between two Maps. * Determines the keys added, changed, and removed between two Maps.
@ -33,18 +33,6 @@ export function mapDiff<K, V>(a: Map<K, V>, b: Map<K, V>): { changed: K[], added
return { changed: changes, added: keyDiff.added, removed: keyDiff.removed }; return { changed: changes, added: keyDiff.added, removed: keyDiff.removed };
} }
/**
* Gets all the key changes (added, removed, or value difference) between two Maps.
* Triple equals is used to compare values, not in-depth tree checking.
* @param a The first Map. Must be defined.
* @param b The second Map. Must be defined.
* @returns The keys which have been added, removed, or changed between the two Maps.
*/
export function mapKeyChanges<K, V>(a: Map<K, V>, b: Map<K, V>): K[] {
const diff = mapDiff(a, b);
return arrayUnion(diff.removed, diff.added, diff.changed);
}
/** /**
* A Map<K, V> with added utility. * A Map<K, V> with added utility.
*/ */

View file

@ -14,14 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
/* Simple utils for formatting style values
*/
// converts a pixel value to rem.
export function toRem(pixelValue: number): string {
return pixelValue / 10 + "rem";
}
export function toPx(pixelValue: number): string { export function toPx(pixelValue: number): string {
return pixelValue + "px"; return pixelValue + "px";
} }

View file

@ -1,31 +0,0 @@
/*
Copyright 2021 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import { textForLocation } from "../../../../src/components/views/location/shareLocation";
describe("LocationButton", () => {
describe("textForLocation", () => {
it("with no description, simply dumps URI and date", () => {
expect(textForLocation("geo:43.2,54.6", 12345, null)).toBe(
"Location geo:43.2,54.6 at 1970-01-01T00:00:12.345Z");
});
it("with a description, includes that in the text", () => {
expect(textForLocation("geo:12,43,3;u=2", 54321, "Me!")).toBe(
'Location "Me!" geo:12,43,3;u=2 at 1970-01-01T00:00:54.321Z');
});
});
});

View file

@ -14,8 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import { MatrixClient, MatrixEvent, Room } from "matrix-js-sdk/src/matrix"; import { MatrixEvent, Room } from "matrix-js-sdk/src/matrix";
import { Thread } from "matrix-js-sdk/src/models/thread";
import { mkMessage, MessageEventProps } from "./test-utils"; import { mkMessage, MessageEventProps } from "./test-utils";
@ -89,8 +88,3 @@ export const makeThreadEvents = ({
return { rootEvent, events }; return { rootEvent, events };
}; };
export const makeThread = (client: MatrixClient, room: Room, props: MakeThreadEventsProps): Thread => {
const { rootEvent, events } = makeThreadEvents(props);
return new Thread(rootEvent.getId(), rootEvent, { initialEvents: events, room, client });
};

View file

@ -14,20 +14,9 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import { iterableDiff, iterableUnion, iterableIntersection } from "../../src/utils/iterables"; import { iterableDiff, iterableIntersection } from "../../src/utils/iterables";
describe('iterables', () => { describe('iterables', () => {
describe('iterableUnion', () => {
it('should return the union array', () => {
const a = [1, 2, 3];
const b = [1, 2, 4]; // note diff
const result = iterableUnion(a, b);
expect(result).toBeDefined();
expect(result).toHaveLength(4);
expect(result).toEqual([1, 2, 3, 4]);
});
});
describe('iterableIntersection', () => { describe('iterableIntersection', () => {
it('should return the intersection', () => { it('should return the intersection', () => {
const a = [1, 2, 3]; const a = [1, 2, 3];

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import { EnhancedMap, mapDiff, mapKeyChanges } from "../../src/utils/maps"; import { EnhancedMap, mapDiff } from "../../src/utils/maps";
describe('maps', () => { describe('maps', () => {
describe('mapDiff', () => { describe('mapDiff', () => {
@ -116,68 +116,6 @@ describe('maps', () => {
}); });
}); });
describe('mapKeyChanges', () => {
it('should indicate no changes for unchanged pointers', () => {
const a = new Map([[1, 1], [2, 2], [3, 3]]);
const result = mapKeyChanges(a, a);
expect(result).toBeDefined();
expect(result).toHaveLength(0);
});
it('should indicate no changes for unchanged maps with different pointers', () => {
const a = new Map([[1, 1], [2, 2], [3, 3]]);
const b = new Map([[1, 1], [2, 2], [3, 3]]);
const result = mapKeyChanges(a, b);
expect(result).toBeDefined();
expect(result).toHaveLength(0);
});
it('should indicate changes for added properties', () => {
const a = new Map([[1, 1], [2, 2], [3, 3]]);
const b = new Map([[1, 1], [2, 2], [3, 3], [4, 4]]);
const result = mapKeyChanges(a, b);
expect(result).toBeDefined();
expect(result).toHaveLength(1);
expect(result).toEqual([4]);
});
it('should indicate changes for removed properties', () => {
const a = new Map([[1, 1], [2, 2], [3, 3], [4, 4]]);
const b = new Map([[1, 1], [2, 2], [3, 3]]);
const result = mapKeyChanges(a, b);
expect(result).toBeDefined();
expect(result).toHaveLength(1);
expect(result).toEqual([4]);
});
it('should indicate changes for changed properties', () => {
const a = new Map([[1, 1], [2, 2], [3, 3], [4, 4]]);
const b = new Map([[1, 1], [2, 2], [3, 3], [4, 55]]);
const result = mapKeyChanges(a, b);
expect(result).toBeDefined();
expect(result).toHaveLength(1);
expect(result).toEqual([4]);
});
it('should indicate changes for properties with different pointers', () => {
const a = new Map([[1, {}]]); // {} always creates a new object
const b = new Map([[1, {}]]);
const result = mapKeyChanges(a, b);
expect(result).toBeDefined();
expect(result).toHaveLength(1);
expect(result).toEqual([1]);
});
it('should indicate changes for changed, added, and removed properties', () => {
const a = new Map([[1, 1], [2, 2], [3, 3]]);
const b = new Map([[1, 1], [2, 8], [4, 4]]); // note change
const result = mapKeyChanges(a, b);
expect(result).toBeDefined();
expect(result).toHaveLength(3);
expect(result).toEqual([3, 4, 2]); // order irrelevant, but the test cares
});
});
describe('EnhancedMap', () => { describe('EnhancedMap', () => {
// Most of these tests will make sure it implements the Map<K, V> class // Most of these tests will make sure it implements the Map<K, V> class