/
vshmidt
/
streamlit
Обзор
Документация
Войти
/
vshmidt
/
streamlit
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
develop
frontend/lib/src/components/widgets/DataFrame/columns/SelectboxColumn.test.ts
335 строк
10 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 { GridCellKind } from "@glideapps/glide-data-grid" import { DropdownCellType } from "@glideapps/glide-data-grid-cells" import { Bool, Field, Int8 } from "apache-arrow" import { ArrowType, DataFrameCellType } from "~lib/dataframes/arrowTypeUtils" import SelectboxColumn, { prepareOptions, SelectboxColumnParams, } from "./SelectboxColumn" import { BaseColumnProps, isErrorCell, isMissingValueCell } from "./utils" const MOCK_CATEGORICAL_TYPE: ArrowType = { type: DataFrameCellType.DATA, arrowField: new Field("selectbox_column", new Int8(), true), pandasType: { field_name: "selectbox_column", name: "selectbox_column", pandas_type: "int8", numpy_type: "int8", metadata: null, }, } const MOCK_BOOLEAN_ARROW_TYPE: ArrowType = { type: DataFrameCellType.DATA, arrowField: new Field("selectbox_column", new Bool(), true), pandasType: { field_name: "selectbox_column", name: "selectbox_column", pandas_type: "bool", numpy_type: "bool", metadata: null, }, } const SELECTBOX_COLUMN_TEMPLATE: Partial<BaseColumnProps> = { id: "1", name: "selectbox_column", title: "Selectbox column", indexNumber: 0, isEditable: true, isHidden: false, isIndex: false, isPinned: false, isStretched: false, } function getSelectboxColumn( arrowType: ArrowType, params?: SelectboxColumnParams, column_props_overwrites?: Partial<BaseColumnProps> ): ReturnType<typeof SelectboxColumn> { return SelectboxColumn({ ...SELECTBOX_COLUMN_TEMPLATE, ...column_props_overwrites, arrowType, columnTypeOptions: params, } as BaseColumnProps) } describe("SelectboxColumn", () => { it("creates a valid column instance with string values", () => { const mockColumn = getSelectboxColumn(MOCK_CATEGORICAL_TYPE, { options: ["foo", "bar"], }) expect(mockColumn.kind).toEqual("selectbox") expect(mockColumn.title).toEqual(SELECTBOX_COLUMN_TEMPLATE.title) expect(mockColumn.id).toEqual(SELECTBOX_COLUMN_TEMPLATE.id) expect(mockColumn.sortMode).toEqual("default") const mockCell = mockColumn.getCell("foo") expect(mockCell.kind).toEqual(GridCellKind.Custom) expect(mockColumn.getCellValue(mockCell)).toEqual("foo") expect((mockCell as DropdownCellType).data.allowedValues).toEqual([ null, { value: "foo", label: "foo" }, { value: "bar", label: "bar" }, ]) }) it("creates a valid column instance number values", () => { const mockColumn = getSelectboxColumn(MOCK_CATEGORICAL_TYPE, { options: [1, 2, 3], }) expect(mockColumn.kind).toEqual("selectbox") expect(mockColumn.title).toEqual(SELECTBOX_COLUMN_TEMPLATE.title) expect(mockColumn.id).toEqual(SELECTBOX_COLUMN_TEMPLATE.id) expect(mockColumn.sortMode).toEqual("default") const mockCell = mockColumn.getCell(1) expect(mockCell.kind).toEqual(GridCellKind.Custom) expect(mockColumn.getCellValue(mockCell)).toEqual(1) expect((mockCell as DropdownCellType).data.allowedValues).toEqual([ null, { value: "1", label: "1" }, { value: "2", label: "2" }, { value: "3", label: "3" }, ]) }) it("creates a valid column instance from boolean type", () => { const mockColumn = getSelectboxColumn(MOCK_BOOLEAN_ARROW_TYPE) expect(mockColumn.kind).toEqual("selectbox") expect(mockColumn.title).toEqual(SELECTBOX_COLUMN_TEMPLATE.title) const mockCell = mockColumn.getCell(true) expect(mockCell.kind).toEqual(GridCellKind.Custom) expect(mockColumn.getCellValue(mockCell)).toEqual(true) expect((mockCell as DropdownCellType).data.allowedValues).toEqual([ null, { value: "true", label: "true" }, { value: "false", label: "false" }, ]) }) it("creates a required column that does not add the empty value", () => { const mockColumn = getSelectboxColumn( MOCK_CATEGORICAL_TYPE, { options: ["foo", "bar"], }, { isRequired: true } ) const mockCell = mockColumn.getCell("foo") expect((mockCell as DropdownCellType).data.allowedValues).toEqual([ { value: "foo", label: "foo" }, { value: "bar", label: "bar" }, ]) const errorCell = mockColumn.getCell(null, true) expect(isErrorCell(errorCell)).toEqual(true) }) it("uses faded style for pinned columns", () => { const mockColumn = getSelectboxColumn( MOCK_CATEGORICAL_TYPE, { options: ["foo", "bar"], }, { isPinned: true, } ) const mockCell = mockColumn.getCell("foo") expect(mockCell.style).toEqual("faded") }) it("creates error cell if value is not in options", () => { const mockColumn = getSelectboxColumn(MOCK_CATEGORICAL_TYPE, { options: ["foo", "bar"], }) const mockCell = mockColumn.getCell("baz", true) expect(isErrorCell(mockCell)).toEqual(true) }) it.each([[null], [undefined], [""]])( "%p is interpreted as missing value", // eslint-disable-next-line @typescript-eslint/no-explicit-any -- TODO: Replace 'any' with a more specific type. (input: any) => { const mockColumn = getSelectboxColumn(MOCK_CATEGORICAL_TYPE, { options: ["foo", "bar"], }) const mockCell = mockColumn.getCell(input) expect(mockColumn.getCellValue(mockCell)).toEqual(null) expect(isMissingValueCell(mockCell)).toEqual(true) } ) it("supports SelectOption objects with custom labels", () => { const mockColumn = getSelectboxColumn(MOCK_CATEGORICAL_TYPE, { options: [ { value: "us", label: "United States" }, { value: "de", label: "Germany" }, ], }) const mockCell = mockColumn.getCell("us") expect((mockCell as DropdownCellType).data.allowedValues).toEqual([ null, { value: "us", label: "United States" }, { value: "de", label: "Germany" }, ]) expect(mockColumn.getCellValue(mockCell)).toEqual("us") }) it("defaults SelectOption label to value when not provided", () => { const mockColumn = getSelectboxColumn(MOCK_CATEGORICAL_TYPE, { options: [{ value: "X" }, { value: "Y" }], }) const mockCell = mockColumn.getCell("X") expect((mockCell as DropdownCellType).data.allowedValues).toEqual([ null, { value: "X", label: "X" }, { value: "Y", label: "Y" }, ]) expect(mockColumn.getCellValue(mockCell)).toEqual("X") }) it("supports numeric SelectOption values and returns numbers", () => { const mockColumn = getSelectboxColumn(MOCK_CATEGORICAL_TYPE, { options: [ { value: 1, label: "One" }, { value: 2, label: "Two" }, ], }) const mockCell = mockColumn.getCell(1) expect((mockCell as DropdownCellType).data.allowedValues).toEqual([ null, { value: "1", label: "One" }, { value: "2", label: "Two" }, ]) expect(mockColumn.getCellValue(mockCell)).toEqual(1) }) it("supports boolean SelectOption values and returns booleans", () => { const mockColumn = getSelectboxColumn(MOCK_BOOLEAN_ARROW_TYPE, { options: [ { value: true, label: "Yes" }, { value: false, label: "No" }, ], }) const mockCell = mockColumn.getCell(true) expect((mockCell as DropdownCellType).data.allowedValues).toEqual([ null, { value: "true", label: "Yes" }, { value: "false", label: "No" }, ]) expect(mockColumn.getCellValue(mockCell)).toEqual(true) }) it("validates against object options as well", () => { const mockColumn = getSelectboxColumn(MOCK_CATEGORICAL_TYPE, { options: [ { value: 1, label: "One" }, { value: 2, label: "Two" }, ], }) const errorCell = mockColumn.getCell("3", true) expect(isErrorCell(errorCell)).toEqual(true) }) }) describe("prepareOptions", () => { it.each([ [ ["foo", "bar"], [ { value: "foo", label: "foo" }, { value: "bar", label: "bar" }, ], ], [ [1, 2], [ { value: "1", label: "1" }, { value: "2", label: "2" }, ], ], [ [true, false], [ { value: "true", label: "true" }, { value: "false", label: "false" }, ], ], [ [ { value: "us", label: "United States" }, { value: "de", label: "Germany" }, ], [ { value: "us", label: "United States" }, { value: "de", label: "Germany" }, ], ], [ [{ value: "X" }, { value: "Y" }], [ { value: "X", label: "X" }, { value: "Y", label: "Y" }, ], ], [ // Filters out empty string and null entries ["", "A", null, "B"] as unknown as ( | string | number | boolean | { value: string; label?: string } )[], [ { value: "A", label: "A" }, { value: "B", label: "B" }, ], ], [ // Trims whitespace around values [" foo ", "bar "], [ { value: "foo", label: "foo" }, { value: "bar", label: "bar" }, ], ], // Nullish options return an empty array [null as unknown as unknown[], []], [undefined as unknown as unknown[], []], ])("normalizes %j into %j", (input, expected) => { // eslint-disable-next-line @typescript-eslint/no-explicit-any -- casting for test inputs only expect(prepareOptions(input as any)).toEqual(expected) }) })