/
vshmidt
/
streamlit
Обзор
Документация
Войти
/
vshmidt
/
streamlit
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
develop
frontend/lib/src/components/widgets/DataFrame/hooks/useTooltips.test.ts
228 строк
6 KB
Ken McGrady
Update copyright header to 2026 (#13491)
02 янв 2026, 16:21
Не верифицирован
02 янв 2026, 16:21
374540a
Код
Авторство
О чём код?
/** * Copyright (c) Streamlit Inc. (2018-2022) Snowflake Inc. (2022-2026) * * 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 { GridMouseEventArgs } from "@glideapps/glide-data-grid" import { act, renderHook } from "@testing-library/react" import { Field, Int64, Utf8 } from "apache-arrow" import { BaseColumn, NumberColumn, TextColumn, } from "~lib/components/widgets/DataFrame/columns" import { DataFrameCellType } from "~lib/dataframes/arrowTypeUtils" import useTooltips, { DEBOUNCE_TIME_MS, REQUIRED_CELL_TOOLTIP, } from "./useTooltips" const TOOLTIP_CONTENT = "This is a **number** column." const MOCK_COLUMNS: BaseColumn[] = [ NumberColumn({ id: "column_1", name: "column_1", title: "column_1", indexNumber: 0, arrowType: { type: DataFrameCellType.DATA, arrowField: new Field("column_1", new Int64(), true), pandasType: { field_name: "column_1", name: "column_1", pandas_type: "int64", numpy_type: "int64", metadata: null, }, }, isEditable: true, isRequired: true, isHidden: false, isIndex: false, isPinned: false, isStretched: false, help: TOOLTIP_CONTENT, }), TextColumn({ id: "column_2", name: "column_2", title: "column_2", indexNumber: 1, arrowType: { type: DataFrameCellType.DATA, arrowField: new Field("column_2", new Utf8(), true), pandasType: { field_name: "column_2", name: "column_2", pandas_type: "unicode", numpy_type: "object", metadata: null, }, }, isEditable: true, isRequired: false, isHidden: false, isIndex: false, isPinned: false, isStretched: false, }), ] const getCellContentMock = vi .fn() .mockImplementation(([col]: readonly [number]) => { const column = MOCK_COLUMNS[col] if (column.kind === "number") { return { ...column.getCell(123), tooltip: "Cell tooltip 1" } } return { ...column.getCell("foo"), tooltip: "Cell tooltip 2" } }) const getEmptyCellContentMock = vi .fn() .mockImplementation(([col]: readonly [number]) => { const column = MOCK_COLUMNS[col] return column.getCell(null) }) describe("useTooltips hook", () => { beforeEach(() => { vi.clearAllMocks() vi.useFakeTimers() }) afterEach(() => { vi.runOnlyPendingTimers() vi.useRealTimers() }) it("renders a tooltip on hovering the header column with a tooltip", () => { const { result } = renderHook(() => { return useTooltips(MOCK_COLUMNS, getCellContentMock) }) act(() => { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion result.current.onItemHovered!({ kind: "header", location: [0, -1], bounds: { x: 0, y: 0, width: 100, height: 30 }, } as object as GridMouseEventArgs) vi.advanceTimersByTime(DEBOUNCE_TIME_MS) }) expect(result.current.tooltip).toMatchObject({ content: TOOLTIP_CONTENT, left: 50, top: 0, }) }) it("renders a tooltip on hovering a cell with a tooltip", () => { const { result } = renderHook(() => { return useTooltips(MOCK_COLUMNS, getCellContentMock) }) act(() => { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion result.current.onItemHovered!({ kind: "cell", location: [0, 1], bounds: { x: 0, y: 30, width: 100, height: 30 }, } as object as GridMouseEventArgs) vi.advanceTimersByTime(DEBOUNCE_TIME_MS) }) expect(result.current.tooltip).toMatchObject({ content: "Cell tooltip 1", left: 50, top: 30, }) }) it("renders a tooltip on hovering a required cell", () => { const { result } = renderHook(() => { return useTooltips(MOCK_COLUMNS, getEmptyCellContentMock) }) act(() => { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion result.current.onItemHovered!({ kind: "cell", location: [0, 1], bounds: { x: 0, y: 30, width: 100, height: 30 }, } as object as GridMouseEventArgs) vi.advanceTimersByTime(DEBOUNCE_TIME_MS) }) expect(result.current.tooltip).toMatchObject({ content: REQUIRED_CELL_TOOLTIP, left: 50, top: 30, }) }) it("clears the tooltip when calling the clearTooltip function", () => { const { result } = renderHook(() => { return useTooltips(MOCK_COLUMNS, getCellContentMock) }) act(() => { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion result.current.onItemHovered!({ kind: "header", location: [0, 0], bounds: { x: 0, y: 0, width: 100, height: 30 }, } as object as GridMouseEventArgs) vi.advanceTimersByTime(DEBOUNCE_TIME_MS) }) expect(result.current.tooltip).toMatchObject({ content: TOOLTIP_CONTENT, left: 50, top: 0, }) act(() => { result.current.clearTooltip() }) expect(result.current.tooltip).toBeUndefined() }) it("does not render a tooltip when hovering a cell in an ignored row", () => { const { result } = renderHook(() => { return useTooltips(MOCK_COLUMNS, getCellContentMock, [1]) }) act(() => { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion result.current.onItemHovered!({ kind: "cell", location: [0, 1], // This is row index 1, which is ignored bounds: { x: 0, y: 30, width: 100, height: 30 }, } as object as GridMouseEventArgs) vi.advanceTimersByTime(DEBOUNCE_TIME_MS) }) expect(result.current.tooltip).toBeUndefined() }) })