mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2026-06-19 17:58:34 +00:00
test: introduce and set up unit tests in the UI (#486)
This commit is contained in:
174
src/utils/__tests__/copy.spec.ts
Normal file
174
src/utils/__tests__/copy.spec.ts
Normal file
@@ -0,0 +1,174 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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 { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
||||
import copy from "../copy";
|
||||
import { ElNotification } from "element-plus";
|
||||
|
||||
// Mock Element Plus
|
||||
vi.mock("element-plus", () => ({
|
||||
ElNotification: vi.fn(),
|
||||
}));
|
||||
|
||||
// Mock navigator.clipboard
|
||||
const mockClipboard = {
|
||||
writeText: vi.fn(),
|
||||
};
|
||||
|
||||
describe("copy utility function", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
|
||||
// Mock navigator.clipboard
|
||||
Object.defineProperty(navigator, "clipboard", {
|
||||
value: mockClipboard,
|
||||
writable: true,
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it("should copy text successfully and show success notification", async () => {
|
||||
const testText = "test text to copy";
|
||||
mockClipboard.writeText.mockResolvedValue(undefined);
|
||||
|
||||
copy(testText);
|
||||
|
||||
// Wait for promise to resolve
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
|
||||
expect(mockClipboard.writeText).toHaveBeenCalledWith(testText);
|
||||
expect(ElNotification).toHaveBeenCalledWith({
|
||||
title: "Success",
|
||||
message: "Copied",
|
||||
type: "success",
|
||||
});
|
||||
});
|
||||
|
||||
it("should handle clipboard error and show error notification", async () => {
|
||||
const testText = "test text to copy";
|
||||
const errorMessage = "Clipboard permission denied";
|
||||
mockClipboard.writeText.mockRejectedValue(errorMessage);
|
||||
|
||||
copy(testText);
|
||||
|
||||
// Wait for promise to reject
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
|
||||
expect(mockClipboard.writeText).toHaveBeenCalledWith(testText);
|
||||
expect(ElNotification).toHaveBeenCalledWith({
|
||||
title: "Error",
|
||||
message: errorMessage,
|
||||
type: "warning",
|
||||
});
|
||||
});
|
||||
|
||||
it("should handle empty string", async () => {
|
||||
const testText = "";
|
||||
mockClipboard.writeText.mockResolvedValue(undefined);
|
||||
|
||||
copy(testText);
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
|
||||
expect(mockClipboard.writeText).toHaveBeenCalledWith("");
|
||||
expect(ElNotification).toHaveBeenCalledWith({
|
||||
title: "Success",
|
||||
message: "Copied",
|
||||
type: "success",
|
||||
});
|
||||
});
|
||||
|
||||
it("should handle long text", async () => {
|
||||
const testText = "a".repeat(1000);
|
||||
mockClipboard.writeText.mockResolvedValue(undefined);
|
||||
|
||||
copy(testText);
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
|
||||
expect(mockClipboard.writeText).toHaveBeenCalledWith(testText);
|
||||
expect(ElNotification).toHaveBeenCalledWith({
|
||||
title: "Success",
|
||||
message: "Copied",
|
||||
type: "success",
|
||||
});
|
||||
});
|
||||
|
||||
it("should handle special characters", async () => {
|
||||
const testText = "!@#$%^&*()_+-=[]{}|;:,.<>?";
|
||||
mockClipboard.writeText.mockResolvedValue(undefined);
|
||||
|
||||
copy(testText);
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
|
||||
expect(mockClipboard.writeText).toHaveBeenCalledWith(testText);
|
||||
expect(ElNotification).toHaveBeenCalledWith({
|
||||
title: "Success",
|
||||
message: "Copied",
|
||||
type: "success",
|
||||
});
|
||||
});
|
||||
|
||||
it("should handle unicode characters", async () => {
|
||||
const testText = "🚀🌟🎉中文测试";
|
||||
mockClipboard.writeText.mockResolvedValue(undefined);
|
||||
|
||||
copy(testText);
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
|
||||
expect(mockClipboard.writeText).toHaveBeenCalledWith(testText);
|
||||
expect(ElNotification).toHaveBeenCalledWith({
|
||||
title: "Success",
|
||||
message: "Copied",
|
||||
type: "success",
|
||||
});
|
||||
});
|
||||
|
||||
it("should handle multiple rapid calls", async () => {
|
||||
const testText = "test text";
|
||||
mockClipboard.writeText.mockResolvedValue(undefined);
|
||||
|
||||
copy(testText);
|
||||
copy(testText);
|
||||
copy(testText);
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||
|
||||
expect(mockClipboard.writeText).toHaveBeenCalledTimes(3);
|
||||
expect(ElNotification).toHaveBeenCalledTimes(3);
|
||||
});
|
||||
|
||||
it("should handle clipboard not available", async () => {
|
||||
const testText = "test text";
|
||||
|
||||
// Remove clipboard from navigator
|
||||
Object.defineProperty(navigator, "clipboard", {
|
||||
value: undefined,
|
||||
writable: true,
|
||||
});
|
||||
|
||||
// Should not throw error
|
||||
expect(() => {
|
||||
copy(testText);
|
||||
}).not.toThrow();
|
||||
});
|
||||
});
|
||||
121
src/utils/__tests__/dateFormat.spec.ts
Normal file
121
src/utils/__tests__/dateFormat.spec.ts
Normal file
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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 { describe, it, expect } from "vitest";
|
||||
import dateFormatStep, { dateFormatTime, dateFormat } from "../dateFormat";
|
||||
|
||||
describe("dateFormat utility functions", () => {
|
||||
describe("dateFormatStep", () => {
|
||||
// Use a fixed timezone to avoid timezone issues in tests
|
||||
const testDate = new Date("2023-12-25T15:30:45.123");
|
||||
|
||||
it("should format MONTH step correctly", () => {
|
||||
expect(dateFormatStep(testDate, "MONTH")).toBe("2023-12-25");
|
||||
expect(dateFormatStep(testDate, "MONTH", true)).toBe("2023-12");
|
||||
});
|
||||
|
||||
it("should format DAY step correctly", () => {
|
||||
expect(dateFormatStep(testDate, "DAY")).toBe("2023-12-25");
|
||||
});
|
||||
|
||||
it("should format HOUR step correctly", () => {
|
||||
expect(dateFormatStep(testDate, "HOUR")).toBe("2023-12-25 15");
|
||||
});
|
||||
|
||||
it("should format MINUTE step correctly", () => {
|
||||
expect(dateFormatStep(testDate, "MINUTE")).toBe("2023-12-25 1530");
|
||||
});
|
||||
|
||||
it("should format SECOND step correctly", () => {
|
||||
expect(dateFormatStep(testDate, "SECOND")).toBe("2023-12-25 153045");
|
||||
});
|
||||
|
||||
it("should handle single digit values correctly", () => {
|
||||
const singleDigitDate = new Date("2023-01-05T09:05:03.123");
|
||||
expect(dateFormatStep(singleDigitDate, "MONTH")).toBe("2023-01-05");
|
||||
expect(dateFormatStep(singleDigitDate, "HOUR")).toBe("2023-01-05 09");
|
||||
expect(dateFormatStep(singleDigitDate, "MINUTE")).toBe("2023-01-05 0905");
|
||||
expect(dateFormatStep(singleDigitDate, "SECOND")).toBe("2023-01-05 090503");
|
||||
});
|
||||
|
||||
it("should return empty string for unknown step", () => {
|
||||
expect(dateFormatStep(testDate, "UNKNOWN")).toBe("");
|
||||
});
|
||||
});
|
||||
|
||||
describe("dateFormatTime", () => {
|
||||
const testDate = new Date("2023-12-25T15:30:45.123");
|
||||
|
||||
it("should format MONTH step correctly", () => {
|
||||
expect(dateFormatTime(testDate, "MONTH")).toBe("2023-12");
|
||||
});
|
||||
|
||||
it("should format DAY step correctly", () => {
|
||||
expect(dateFormatTime(testDate, "DAY")).toBe("12-25");
|
||||
});
|
||||
|
||||
it("should format HOUR step correctly", () => {
|
||||
expect(dateFormatTime(testDate, "HOUR")).toBe("12-25 15");
|
||||
});
|
||||
|
||||
it("should format MINUTE step correctly", () => {
|
||||
expect(dateFormatTime(testDate, "MINUTE")).toBe("15:30\n12-25");
|
||||
});
|
||||
|
||||
it("should handle single digit values correctly", () => {
|
||||
const singleDigitDate = new Date("2023-01-05T09:05:03.123");
|
||||
expect(dateFormatTime(singleDigitDate, "MONTH")).toBe("2023-01");
|
||||
expect(dateFormatTime(singleDigitDate, "DAY")).toBe("01-05");
|
||||
expect(dateFormatTime(singleDigitDate, "HOUR")).toBe("01-05 09");
|
||||
expect(dateFormatTime(singleDigitDate, "MINUTE")).toBe("09:05\n01-05");
|
||||
});
|
||||
|
||||
it("should return empty string for unknown step", () => {
|
||||
expect(dateFormatTime(testDate, "UNKNOWN")).toBe("");
|
||||
});
|
||||
});
|
||||
|
||||
describe("dateFormat", () => {
|
||||
it("should format timestamp with default pattern", () => {
|
||||
const timestamp = 1703521845123;
|
||||
// Use a regex pattern to match the expected format regardless of timezone
|
||||
expect(dateFormat(timestamp)).toMatch(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/);
|
||||
});
|
||||
|
||||
it("should format timestamp with custom pattern", () => {
|
||||
const timestamp = 1703521845123;
|
||||
const date = new Date(timestamp);
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(date.getDate()).padStart(2, "0");
|
||||
|
||||
expect(dateFormat(timestamp, "YYYY/MM/DD")).toBe(`${year}/${month}/${day}`);
|
||||
expect(dateFormat(timestamp, "MM-DD-YYYY")).toBe(`${month}-${day}-${year}`);
|
||||
// Use a regex pattern for time-based formats that might vary by timezone
|
||||
expect(dateFormat(timestamp, "HH:mm")).toMatch(/^\d{2}:\d{2}$/);
|
||||
});
|
||||
|
||||
it("should handle different timestamp formats", () => {
|
||||
const timestamp1 = Date.now();
|
||||
const timestamp2 = new Date("2023-01-01").getTime();
|
||||
|
||||
expect(dateFormat(timestamp1)).toMatch(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/);
|
||||
// Use a regex pattern for time-based formats that might vary by timezone
|
||||
expect(dateFormat(timestamp2)).toMatch(/^2023-01-01 \d{2}:\d{2}:\d{2}$/);
|
||||
});
|
||||
});
|
||||
});
|
||||
108
src/utils/__tests__/debounce.spec.ts
Normal file
108
src/utils/__tests__/debounce.spec.ts
Normal file
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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 { describe, it, expect, vi, beforeEach } from "vitest";
|
||||
import { debounce } from "../debounce";
|
||||
|
||||
describe("debounce utility function", () => {
|
||||
beforeEach(() => {
|
||||
vi.useFakeTimers();
|
||||
});
|
||||
|
||||
it("should call the function only once after delay", () => {
|
||||
const callback = vi.fn();
|
||||
const debouncedFn = debounce(callback, 1000);
|
||||
|
||||
// Call multiple times
|
||||
debouncedFn();
|
||||
debouncedFn();
|
||||
debouncedFn();
|
||||
|
||||
// Function should not be called immediately
|
||||
expect(callback).not.toHaveBeenCalled();
|
||||
|
||||
// Fast forward time
|
||||
vi.advanceTimersByTime(1000);
|
||||
|
||||
// Function should be called only once
|
||||
expect(callback).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("should reset timer on subsequent calls", () => {
|
||||
const callback = vi.fn();
|
||||
const debouncedFn = debounce(callback, 1000);
|
||||
|
||||
// First call
|
||||
debouncedFn();
|
||||
|
||||
// Advance time but not enough to trigger
|
||||
vi.advanceTimersByTime(500);
|
||||
expect(callback).not.toHaveBeenCalled();
|
||||
|
||||
// Second call should reset timer
|
||||
debouncedFn();
|
||||
|
||||
// Advance time again
|
||||
vi.advanceTimersByTime(500);
|
||||
expect(callback).not.toHaveBeenCalled();
|
||||
|
||||
// Advance to trigger the function
|
||||
vi.advanceTimersByTime(500);
|
||||
expect(callback).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("should handle different delay durations", () => {
|
||||
const callback = vi.fn();
|
||||
const debouncedFn = debounce(callback, 500);
|
||||
|
||||
debouncedFn();
|
||||
|
||||
// Should not be called before delay
|
||||
vi.advanceTimersByTime(499);
|
||||
expect(callback).not.toHaveBeenCalled();
|
||||
|
||||
// Should be called after delay
|
||||
vi.advanceTimersByTime(1);
|
||||
expect(callback).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("should handle zero delay", () => {
|
||||
const callback = vi.fn();
|
||||
const debouncedFn = debounce(callback, 0);
|
||||
|
||||
debouncedFn();
|
||||
|
||||
// Should be called after a tick even with zero delay
|
||||
vi.advanceTimersByTime(0);
|
||||
expect(callback).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("should handle multiple rapid calls", () => {
|
||||
const callback = vi.fn();
|
||||
const debouncedFn = debounce(callback, 100);
|
||||
|
||||
// Rapid successive calls
|
||||
for (let i = 0; i < 10; i++) {
|
||||
debouncedFn();
|
||||
}
|
||||
|
||||
expect(callback).not.toHaveBeenCalled();
|
||||
|
||||
vi.advanceTimersByTime(100);
|
||||
expect(callback).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
257
src/utils/__tests__/is.spec.ts
Normal file
257
src/utils/__tests__/is.spec.ts
Normal file
@@ -0,0 +1,257 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You 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 { describe, it, expect } from "vitest";
|
||||
import {
|
||||
is,
|
||||
isDef,
|
||||
isUnDef,
|
||||
isObject,
|
||||
isDate,
|
||||
isNull,
|
||||
isNullOrUnDef,
|
||||
isNumber,
|
||||
isString,
|
||||
isFunction,
|
||||
isBoolean,
|
||||
isRegExp,
|
||||
isArray,
|
||||
isMap,
|
||||
isEmptyObject,
|
||||
} from "../is";
|
||||
|
||||
describe("is utility functions", () => {
|
||||
describe("is", () => {
|
||||
it("should return true for correct type checks", () => {
|
||||
expect(is("string", "String")).toBe(true);
|
||||
expect(is(123, "Number")).toBe(true);
|
||||
expect(is({}, "Object")).toBe(true);
|
||||
expect(is([], "Array")).toBe(true);
|
||||
expect(is(new Date(), "Date")).toBe(true);
|
||||
expect(is(/regex/, "RegExp")).toBe(true);
|
||||
expect(is(true, "Boolean")).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false for incorrect type checks", () => {
|
||||
expect(is("string", "Number")).toBe(false);
|
||||
expect(is(123, "String")).toBe(false);
|
||||
expect(is({}, "Array")).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("isDef", () => {
|
||||
it("should return true for defined values", () => {
|
||||
expect(isDef("string")).toBe(true);
|
||||
expect(isDef(0)).toBe(true);
|
||||
expect(isDef(false)).toBe(true);
|
||||
expect(isDef(null)).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false for undefined values", () => {
|
||||
expect(isDef(undefined)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("isUnDef", () => {
|
||||
it("should return true for undefined values", () => {
|
||||
expect(isUnDef(undefined)).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false for defined values", () => {
|
||||
expect(isUnDef("string")).toBe(false);
|
||||
expect(isUnDef(0)).toBe(false);
|
||||
expect(isUnDef(false)).toBe(false);
|
||||
expect(isUnDef(null)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("isObject", () => {
|
||||
it("should return true for objects", () => {
|
||||
expect(isObject({})).toBe(true);
|
||||
expect(isObject({ key: "value" })).toBe(true);
|
||||
expect(isObject(new Object())).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false for non-objects", () => {
|
||||
expect(isObject(null)).toBe(false);
|
||||
expect(isObject([])).toBe(false);
|
||||
expect(isObject("string")).toBe(false);
|
||||
expect(isObject(123)).toBe(false);
|
||||
expect(isObject(undefined)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("isDate", () => {
|
||||
it("should return true for Date objects", () => {
|
||||
expect(isDate(new Date())).toBe(true);
|
||||
expect(isDate(new Date("2023-01-01"))).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false for non-Date values", () => {
|
||||
expect(isDate("2023-01-01")).toBe(false);
|
||||
expect(isDate(123)).toBe(false);
|
||||
expect(isDate({})).toBe(false);
|
||||
expect(isDate(null)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("isNull", () => {
|
||||
it("should return true for null", () => {
|
||||
expect(isNull(null)).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false for non-null values", () => {
|
||||
expect(isNull(undefined)).toBe(false);
|
||||
expect(isNull("string")).toBe(false);
|
||||
expect(isNull(0)).toBe(false);
|
||||
expect(isNull({})).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("isNullOrUnDef", () => {
|
||||
it("should return true for null or undefined", () => {
|
||||
expect(isNullOrUnDef(null)).toBe(true);
|
||||
expect(isNullOrUnDef(undefined)).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false for other values", () => {
|
||||
expect(isNullOrUnDef("string")).toBe(false);
|
||||
expect(isNullOrUnDef(0)).toBe(false);
|
||||
expect(isNullOrUnDef({})).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("isNumber", () => {
|
||||
it("should return true for numbers", () => {
|
||||
expect(isNumber(123)).toBe(true);
|
||||
expect(isNumber(0)).toBe(true);
|
||||
expect(isNumber(-123)).toBe(true);
|
||||
expect(isNumber(3.14)).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false for non-numbers", () => {
|
||||
expect(isNumber("123")).toBe(false);
|
||||
expect(isNumber({})).toBe(false);
|
||||
expect(isNumber(null)).toBe(false);
|
||||
expect(isNumber(undefined)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("isString", () => {
|
||||
it("should return true for strings", () => {
|
||||
expect(isString("hello")).toBe(true);
|
||||
expect(isString("")).toBe(true);
|
||||
expect(isString(String("hello"))).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false for non-strings", () => {
|
||||
expect(isString(123)).toBe(false);
|
||||
expect(isString({})).toBe(false);
|
||||
expect(isString(null)).toBe(false);
|
||||
expect(isString(undefined)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("isFunction", () => {
|
||||
it("should return true for functions", () => {
|
||||
expect(isFunction(() => {})).toBe(true);
|
||||
expect(isFunction(function () {})).toBe(true);
|
||||
expect(isFunction(async () => {})).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false for non-functions", () => {
|
||||
expect(isFunction("string")).toBe(false);
|
||||
expect(isFunction(123)).toBe(false);
|
||||
expect(isFunction({})).toBe(false);
|
||||
expect(isFunction(null)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("isBoolean", () => {
|
||||
it("should return true for booleans", () => {
|
||||
expect(isBoolean(true)).toBe(true);
|
||||
expect(isBoolean(false)).toBe(true);
|
||||
expect(isBoolean(Boolean(true))).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false for non-booleans", () => {
|
||||
expect(isBoolean("true")).toBe(false);
|
||||
expect(isBoolean(1)).toBe(false);
|
||||
expect(isBoolean({})).toBe(false);
|
||||
expect(isBoolean(null)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("isRegExp", () => {
|
||||
it("should return true for regular expressions", () => {
|
||||
expect(isRegExp(/regex/)).toBe(true);
|
||||
expect(isRegExp(new RegExp("regex"))).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false for non-regex values", () => {
|
||||
expect(isRegExp("regex")).toBe(false);
|
||||
expect(isRegExp({})).toBe(false);
|
||||
expect(isRegExp(null)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("isArray", () => {
|
||||
it("should return true for arrays", () => {
|
||||
expect(isArray([])).toBe(true);
|
||||
expect(isArray([1, 2, 3])).toBe(true);
|
||||
expect(isArray(new Array())).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false for non-arrays", () => {
|
||||
expect(isArray({})).toBe(false);
|
||||
expect(isArray("string")).toBe(false);
|
||||
expect(isArray(123)).toBe(false);
|
||||
expect(isArray(null)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("isMap", () => {
|
||||
it("should return true for Map objects", () => {
|
||||
expect(isMap(new Map())).toBe(true);
|
||||
expect(isMap(new Map([["key", "value"]]))).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false for non-Map objects", () => {
|
||||
expect(isMap({})).toBe(false);
|
||||
expect(isMap([])).toBe(false);
|
||||
expect(isMap(null)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("isEmptyObject", () => {
|
||||
it("should return true for empty objects", () => {
|
||||
expect(isEmptyObject({})).toBe(true);
|
||||
});
|
||||
|
||||
it("should return false for non-empty objects", () => {
|
||||
expect(isEmptyObject({ key: "value" })).toBe(false);
|
||||
expect(isEmptyObject({ length: 0 })).toBe(false);
|
||||
});
|
||||
|
||||
it("should return false for non-objects", () => {
|
||||
expect(isEmptyObject([])).toBe(false);
|
||||
expect(isEmptyObject("string")).toBe(false);
|
||||
expect(isEmptyObject(123)).toBe(false);
|
||||
expect(isEmptyObject(null)).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -18,6 +18,10 @@
|
||||
import { ElNotification } from "element-plus";
|
||||
|
||||
export default (text: string): void => {
|
||||
if (!navigator.clipboard) {
|
||||
console.error("Clipboard is not supported");
|
||||
return;
|
||||
}
|
||||
navigator.clipboard
|
||||
.writeText(text)
|
||||
.then(() => {
|
||||
|
||||
@@ -40,10 +40,6 @@ export function isNull(val: unknown): val is null {
|
||||
return val === null;
|
||||
}
|
||||
|
||||
export function isNullAndUnDef(val: unknown): val is null | undefined {
|
||||
return isUnDef(val) && isNull(val);
|
||||
}
|
||||
|
||||
export function isNullOrUnDef(val: unknown): val is null | undefined {
|
||||
return isUnDef(val) || isNull(val);
|
||||
}
|
||||
@@ -52,10 +48,6 @@ export function isNumber(val: unknown): val is number {
|
||||
return is(val, "Number");
|
||||
}
|
||||
|
||||
export function isPromise<T = any>(val: unknown): val is Promise<T> {
|
||||
return is(val, "Promise") && isObject(val) && isFunction(val.then) && isFunction(val.catch);
|
||||
}
|
||||
|
||||
export function isString(val: unknown): val is string {
|
||||
return is(val, "String");
|
||||
}
|
||||
@@ -76,14 +68,6 @@ export function isArray(val: unknown): boolean {
|
||||
return Array.isArray(val);
|
||||
}
|
||||
|
||||
export function isWindow(val: unknown): val is Window {
|
||||
return typeof window !== "undefined" && is(val, "Window");
|
||||
}
|
||||
|
||||
export function isElement(val: unknown): val is Element {
|
||||
return isObject(val) && !!val.tagName;
|
||||
}
|
||||
|
||||
export function isMap(val: unknown): val is Map<any, any> {
|
||||
return is(val, "Map");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user