Skip to content

Commit

Permalink
Added mockable isInstanceOf util (#79-2)
Browse files Browse the repository at this point in the history
  • Loading branch information
bmingles committed Oct 2, 2024
1 parent c25b03f commit 5ed895e
Show file tree
Hide file tree
Showing 8 changed files with 35 additions and 7 deletions.
3 changes: 2 additions & 1 deletion src/controllers/ExtensionController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
assertDefined,
getEditorForUri,
getTempDir,
isInstanceOf,
isSupportedLanguageId,
Logger,
OutputChannelWithHistory,
Expand Down Expand Up @@ -543,7 +544,7 @@ export class ExtensionController implements Disposable {
const connectionState =
await this._connectionController.getOrCreateConnection(uri);

if (connectionState instanceof DhService) {
if (isInstanceOf(connectionState, DhService)) {
await connectionState?.runEditorCode(editor, selectionOnly === true);
}
};
Expand Down
4 changes: 2 additions & 2 deletions src/providers/ServerConnectionTreeProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type {
ConnectionState,
ServerConnectionNode,
} from '../types';
import { sortByStringProp } from '../util';
import { isInstanceOf, sortByStringProp } from '../util';
import { DhService } from '../services';

/**
Expand All @@ -30,7 +30,7 @@ export class ServerConnectionTreeProvider extends TreeDataProviderBase<ServerCon
}

const [consoleType] =
connectionOrUri instanceof DhService && connectionOrUri.isInitialized
isInstanceOf(connectionOrUri, DhService) && connectionOrUri.isInitialized
? await connectionOrUri.getConsoleTypes()
: [];

Expand Down
9 changes: 7 additions & 2 deletions src/services/ServerManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ import type {
ConnectionState,
ServerState,
} from '../types';
import { getInitialServerStates, isDisposable, Logger } from '../util';
import {
getInitialServerStates,
isDisposable,
isInstanceOf,
Logger,
} from '../util';
import { URLMap } from './URLMap';
import { URIMap } from './URIMap';
import DhService from './DhService';
Expand Down Expand Up @@ -276,7 +281,7 @@ export class ServerManager implements IServerManager {
const uri = editor.document.uri;

const isConsoleTypeSupported =
connectionState instanceof DhService &&
isInstanceOf(connectionState, DhService) &&
(await connectionState.supportsConsoleType(
editor.document.languageId as ConsoleType
));
Expand Down
1 change: 1 addition & 0 deletions src/util/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './assertUtil';
export * from './dataUtils';
export * from './isInstanceOf';
export * from './isDisposable';
export * from './Logger';
export * from './OutputChannelWithHistory';
Expand Down
15 changes: 15 additions & 0 deletions src/util/isInstanceOf.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* Type guard wrapper of `instanceof` operator. This is purely so we can mock
* instanceof checks in unit tests since `instanceof` is already a type guard.
* @param value The value to check
* @param type The type to check against
* @returns `true` if `value` is an instance of `type`
*/
export function isInstanceOf<T>(
value: unknown,
// Possible we'll need to include non-abstract constructor type, but this seems
// to work for both abstract and non-abstract constructors.
type: abstract new (...args: any[]) => T
): value is T {
return value instanceof type;
}
3 changes: 2 additions & 1 deletion src/util/serverUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type {
import { PIP_SERVER_STATUS_DIRECTORY, SERVER_LANGUAGE_SET } from '../common';
import { getTempDir } from './tmpUtils';
import { DhService } from '../services';
import { isInstanceOf } from './isInstanceOf';

/**
* Get initial server states based on server configs.
Expand Down Expand Up @@ -113,7 +114,7 @@ export async function* iterateConnectionsForConsoleType(
): AsyncGenerator<ConnectionState, void, unknown> {
for (const connection of connections) {
const isConsoleTypeSupported =
connection instanceof DhService &&
isInstanceOf(connection, DhService) &&
(await connection.supportsConsoleType(consoleType));

if (isConsoleTypeSupported) {
Expand Down
4 changes: 4 additions & 0 deletions src/util/treeViewUtils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ import type {
VariableDefintion,
VariableType,
} from '../types';
import { isInstanceOf } from './isInstanceOf';

// See __mocks__/vscode.ts for the mock implementation
vi.mock('vscode');
vi.mock('../util/isInstanceOf.ts');

const variableTypes: readonly VariableType[] = [
'deephaven.plot.express.DeephavenFigure',
Expand Down Expand Up @@ -54,6 +56,8 @@ describe('getPanelConnectionTreeItem', () => {
getConsoleTypes,
} as IDhService;

vi.mocked(isInstanceOf).mockReturnValue(true);

const actual = await getPanelConnectionTreeItem(connection);
expect(actual).toMatchSnapshot();
}
Expand Down
3 changes: 2 additions & 1 deletion src/util/treeViewUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
type ServerTreeItemContextValue,
} from '../common';
import { DhService } from '../services';
import { isInstanceOf } from './isInstanceOf';

/**
* Get a tree item vscode.ThemeIcon for a variable type.
Expand Down Expand Up @@ -54,7 +55,7 @@ export async function getPanelConnectionTreeItem(
connection: ConnectionState
): Promise<vscode.TreeItem> {
const [consoleType] =
connection instanceof DhService && connection.isInitialized
isInstanceOf(connection, DhService) && connection.isInitialized
? await connection.getConsoleTypes()
: [];

Expand Down

0 comments on commit 5ed895e

Please sign in to comment.