Skip to content
Merged
2 changes: 1 addition & 1 deletion core/interfaces/i_autohideable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@ export interface IAutoHideable extends IComponent {

/** Returns true if the given object is autohideable. */
export function isAutoHideable(obj: any): obj is IAutoHideable {
return obj.autoHide !== undefined;
return obj && typeof obj.autoHide === 'function';
}
14 changes: 7 additions & 7 deletions core/interfaces/i_comment_icon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,17 @@ export interface ICommentIcon extends IIcon, IHasBubble, ISerializable {
}

/** Checks whether the given object is an ICommentIcon. */
export function isCommentIcon(obj: object): obj is ICommentIcon {
export function isCommentIcon(obj: any): obj is ICommentIcon {
return (
isIcon(obj) &&
hasBubble(obj) &&
isSerializable(obj) &&
(obj as any)['setText'] !== undefined &&
(obj as any)['getText'] !== undefined &&
(obj as any)['setBubbleSize'] !== undefined &&
(obj as any)['getBubbleSize'] !== undefined &&
(obj as any)['setBubbleLocation'] !== undefined &&
(obj as any)['getBubbleLocation'] !== undefined &&
typeof (obj as any).setText === 'function' &&
typeof (obj as any).getText === 'function' &&
typeof (obj as any).setBubbleSize === 'function' &&
typeof (obj as any).getBubbleSize === 'function' &&
typeof (obj as any).setBubbleLocation === 'function' &&
typeof (obj as any).getBubbleLocation === 'function' &&
obj.getType() === IconType.COMMENT
);
}
2 changes: 1 addition & 1 deletion core/interfaces/i_copyable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,5 @@ export type ICopyData = ICopyable.ICopyData;

/** @returns true if the given object is an ICopyable. */
export function isCopyable(obj: any): obj is ICopyable<ICopyData> {
return obj.toCopyData !== undefined;
return obj && typeof obj.toCopyData === 'function';
}
7 changes: 4 additions & 3 deletions core/interfaces/i_deletable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ export interface IDeletable {
/** Returns whether the given object is an IDeletable. */
export function isDeletable(obj: any): obj is IDeletable {
return (
obj['isDeletable'] !== undefined &&
obj['dispose'] !== undefined &&
obj['setDeleteStyle'] !== undefined
obj &&
typeof obj.isDeletable === 'function' &&
typeof obj.dispose === 'function' &&
typeof obj.setDeleteStyle === 'function'
);
}
13 changes: 7 additions & 6 deletions core/interfaces/i_draggable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,12 @@ export interface IDragStrategy {
/** Returns whether the given object is an IDraggable or not. */
export function isDraggable(obj: any): obj is IDraggable {
return (
obj.getRelativeToSurfaceXY !== undefined &&
obj.isMovable !== undefined &&
obj.startDrag !== undefined &&
obj.drag !== undefined &&
obj.endDrag !== undefined &&
obj.revertDrag !== undefined
obj &&
typeof obj.getRelativeToSurfaceXY === 'function' &&
typeof obj.isMovable === 'function' &&
typeof obj.startDrag === 'function' &&
typeof obj.drag === 'function' &&
typeof obj.endDrag === 'function' &&
typeof obj.revertDrag === 'function'
);
}
16 changes: 8 additions & 8 deletions core/interfaces/i_focusable_node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,16 +102,16 @@ export interface IFocusableNode {
* Determines whether the provided object fulfills the contract of
* IFocusableNode.
*
* @param object The object to test.
* @param obj The object to test.
* @returns Whether the provided object can be used as an IFocusableNode.
*/
export function isFocusableNode(object: any | null): object is IFocusableNode {
export function isFocusableNode(obj: any): obj is IFocusableNode {
return (
object &&
'getFocusableElement' in object &&
'getFocusableTree' in object &&
'onNodeFocus' in object &&
'onNodeBlur' in object &&
'canBeFocused' in object
obj &&
typeof obj.getFocusableElement === 'function' &&
typeof obj.getFocusableTree === 'function' &&
typeof obj.onNodeFocus === 'function' &&
typeof obj.onNodeBlur === 'function' &&
typeof obj.canBeFocused === 'function'
);
}
18 changes: 9 additions & 9 deletions core/interfaces/i_focusable_tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,17 +128,17 @@ export interface IFocusableTree {
* Determines whether the provided object fulfills the contract of
* IFocusableTree.
*
* @param object The object to test.
* @param obj The object to test.
* @returns Whether the provided object can be used as an IFocusableTree.
*/
export function isFocusableTree(object: any | null): object is IFocusableTree {
export function isFocusableTree(obj: any): obj is IFocusableTree {
return (
object &&
'getRootFocusableNode' in object &&
'getRestoredFocusableNode' in object &&
'getNestedTrees' in object &&
'lookUpFocusableNode' in object &&
'onTreeFocus' in object &&
'onTreeBlur' in object
obj &&
typeof obj.getRootFocusableNode === 'function' &&
typeof obj.getRestoredFocusableNode === 'function' &&
typeof obj.getNestedTrees === 'function' &&
typeof obj.lookUpFocusableNode === 'function' &&
typeof obj.onTreeFocus === 'function' &&
typeof obj.onTreeBlur === 'function'
);
}
4 changes: 3 additions & 1 deletion core/interfaces/i_has_bubble.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ export interface IHasBubble {
/** Type guard that checks whether the given object is a IHasBubble. */
export function hasBubble(obj: any): obj is IHasBubble {
return (
obj.bubbleIsVisible !== undefined && obj.setBubbleVisible !== undefined
typeof obj.bubbleIsVisible === 'function' &&
typeof obj.setBubbleVisible === 'function' &&
typeof obj.getBubble === 'function'
);
}
28 changes: 14 additions & 14 deletions core/interfaces/i_icon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,19 +98,19 @@ export interface IIcon extends IFocusableNode {
/** Type guard that checks whether the given object is an IIcon. */
export function isIcon(obj: any): obj is IIcon {
return (
obj.getType !== undefined &&
obj.initView !== undefined &&
obj.dispose !== undefined &&
obj.getWeight !== undefined &&
obj.getSize !== undefined &&
obj.applyColour !== undefined &&
obj.hideForInsertionMarker !== undefined &&
obj.updateEditable !== undefined &&
obj.updateCollapsed !== undefined &&
obj.isShownWhenCollapsed !== undefined &&
obj.setOffsetInBlock !== undefined &&
obj.onLocationChange !== undefined &&
obj.onClick !== undefined &&
isFocusableNode(obj)
isFocusableNode(obj) &&
typeof (obj as IIcon).getType === 'function' &&
typeof (obj as IIcon).initView === 'function' &&
typeof (obj as IIcon).dispose === 'function' &&
typeof (obj as IIcon).getWeight === 'function' &&
typeof (obj as IIcon).getSize === 'function' &&
typeof (obj as IIcon).applyColour === 'function' &&
typeof (obj as IIcon).hideForInsertionMarker === 'function' &&
typeof (obj as IIcon).updateEditable === 'function' &&
typeof (obj as IIcon).updateCollapsed === 'function' &&
typeof (obj as IIcon).isShownWhenCollapsed === 'function' &&
typeof (obj as IIcon).setOffsetInBlock === 'function' &&
typeof (obj as IIcon).onLocationChange === 'function' &&
typeof (obj as IIcon).onClick === 'function'
);
}
15 changes: 8 additions & 7 deletions core/interfaces/i_legacy_procedure_blocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ export interface LegacyProcedureDefBlock {

/** @internal */
export function isLegacyProcedureDefBlock(
block: object,
): block is LegacyProcedureDefBlock {
return (block as any).getProcedureDef !== undefined;
obj: any,
): obj is LegacyProcedureDefBlock {
return obj && typeof obj.getProcedureDef === 'function';
}

/** @internal */
Expand All @@ -41,10 +41,11 @@ export interface LegacyProcedureCallBlock {

/** @internal */
export function isLegacyProcedureCallBlock(
block: object,
): block is LegacyProcedureCallBlock {
obj: any,
): obj is LegacyProcedureCallBlock {
return (
(block as any).getProcedureCall !== undefined &&
(block as any).renameProcedure !== undefined
obj &&
typeof obj.getProcedureCall === 'function' &&
typeof obj.renameProcedure === 'function'
);
}
6 changes: 5 additions & 1 deletion core/interfaces/i_observable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,9 @@ export interface IObservable {
* @internal
*/
export function isObservable(obj: any): obj is IObservable {
return obj.startPublishing !== undefined && obj.stopPublishing !== undefined;
return (
obj &&
typeof obj.startPublishing === 'function' &&
typeof obj.stopPublishing === 'function'
);
}
2 changes: 1 addition & 1 deletion core/interfaces/i_paster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@ export interface IPaster<U extends ICopyData, T extends ICopyable<U>> {
export function isPaster(
obj: any,
): obj is IPaster<ICopyData, ICopyable<ICopyData>> {
return obj.paste !== undefined;
return obj && typeof obj.paste === 'function';
}
7 changes: 4 additions & 3 deletions core/interfaces/i_procedure_block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ export interface IProcedureBlock {
export function isProcedureBlock(
block: Block | IProcedureBlock,
): block is IProcedureBlock {
block = block as IProcedureBlock;
return (
(block as IProcedureBlock).getProcedureModel !== undefined &&
(block as IProcedureBlock).doProcedureUpdate !== undefined &&
(block as IProcedureBlock).isProcedureDef !== undefined
typeof block.getProcedureModel === 'function' &&
typeof block.doProcedureUpdate === 'function' &&
typeof block.isProcedureDef === 'function'
);
}
2 changes: 1 addition & 1 deletion core/interfaces/i_rendered_element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ export interface IRenderedElement {
* @returns True if the given object is an IRenderedElement.
*/
export function isRenderedElement(obj: any): obj is IRenderedElement {
return obj['getSvgRoot'] !== undefined;
return obj && typeof obj.getSvgRoot === 'function';
}
12 changes: 6 additions & 6 deletions core/interfaces/i_selectable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ export interface ISelectable extends IFocusableNode {
}

/** Checks whether the given object is an ISelectable. */
export function isSelectable(obj: object): obj is ISelectable {
export function isSelectable(obj: any): obj is ISelectable {
return (
typeof (obj as any).id === 'string' &&
(obj as any).workspace !== undefined &&
(obj as any).select !== undefined &&
(obj as any).unselect !== undefined &&
isFocusableNode(obj)
isFocusableNode(obj) &&
typeof (obj as ISelectable).id === 'string' &&
typeof (obj as ISelectable).workspace === 'object' &&
typeof (obj as ISelectable).select === 'function' &&
typeof (obj as ISelectable).unselect === 'function'
);
}
6 changes: 5 additions & 1 deletion core/interfaces/i_serializable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,9 @@ export interface ISerializable {

/** Type guard that checks whether the given object is a ISerializable. */
export function isSerializable(obj: any): obj is ISerializable {
return obj.saveState !== undefined && obj.loadState !== undefined;
return (
obj &&
typeof obj.saveState === 'function' &&
typeof obj.loadState === 'function'
);
}
19 changes: 10 additions & 9 deletions tests/mocha/block_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
import {ConnectionType} from '../../build/src/core/connection_type.js';
import {EventType} from '../../build/src/core/events/type.js';
import * as eventUtils from '../../build/src/core/events/utils.js';
import {IconType} from '../../build/src/core/icons/icon_types.js';
import {EndRowInput} from '../../build/src/core/inputs/end_row_input.js';
import {isCommentIcon} from '../../build/src/core/interfaces/i_comment_icon.js';
import {Size} from '../../build/src/core/utils/size.js';
import {assert} from '../../node_modules/chai/chai.js';
import {createRenderedBlock} from './test_helpers/block_definitions.js';
import {
Expand Down Expand Up @@ -1426,9 +1429,9 @@ suite('Blocks', function () {
});

suite('Constructing registered comment classes', function () {
class MockComment extends MockIcon {
class MockComment extends MockBubbleIcon {
getType() {
return Blockly.icons.IconType.COMMENT;
return IconType.COMMENT;
}

setText() {}
Expand All @@ -1440,26 +1443,24 @@ suite('Blocks', function () {
setBubbleSize() {}

getBubbleSize() {
return Blockly.utils.Size(0, 0);
return Size(0, 0);
}

setBubbleLocation() {}

getBubbleLocation() {}

bubbleIsVisible() {
return true;
}

setBubbleVisible() {}

saveState() {
return {};
}

loadState() {}
}

if (!isCommentIcon(new MockComment())) {
throw new TypeError('MockComment not an ICommentIcon');
}

setup(function () {
this.workspace = Blockly.inject('blocklyDiv', {});

Expand Down
35 changes: 34 additions & 1 deletion tests/mocha/test_helpers/icon_mocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,24 @@
* SPDX-License-Identifier: Apache-2.0
*/

export class MockIcon {
import {isFocusableNode} from '../../../build/src/core/interfaces/i_focusable_node.js';
import {hasBubble} from '../../../build/src/core/interfaces/i_has_bubble.js';
import {isIcon} from '../../../build/src/core/interfaces/i_icon.js';
import {isSerializable} from '../../../build/src/core/interfaces/i_serializable.js';

export class MockFocusable {
getFocusableElement() {}
getFocusableTree() {}
onNodeFocus() {}
onNodeBlur() {}
canBeFocused() {}
}

if (!isFocusableNode(new MockFocusable())) {
throw new TypeError('MockFocusable not an IFocuableNode');
}

export class MockIcon extends MockFocusable {
getType() {
return new Blockly.icons.IconType('mock icon');
}
Expand Down Expand Up @@ -52,6 +69,10 @@ export class MockIcon {
}
}

if (!isIcon(new MockIcon())) {
throw new TypeError('MockIcon not an IIcon');
}

export class MockSerializableIcon extends MockIcon {
constructor() {
super();
Expand All @@ -75,6 +96,10 @@ export class MockSerializableIcon extends MockIcon {
}
}

if (!isSerializable(new MockSerializableIcon())) {
throw new TypeError('MockSerializableIcon not an ISerializable');
}

export class MockBubbleIcon extends MockIcon {
constructor() {
super();
Expand All @@ -94,4 +119,12 @@ export class MockBubbleIcon extends MockIcon {
setBubbleVisible(visible) {
this.visible = visible;
}

getBubble() {
return null;
}
}

if (!hasBubble(new MockBubbleIcon())) {
throw new TypeError('MockBubbleIcon not an IHasBubble');
}