Skip to content

Commit

Permalink
feat: add contains ignore case in go to row
Browse files Browse the repository at this point in the history
  • Loading branch information
Ethan Alvizo authored and ethanalvizo committed May 11, 2023
1 parent 02215b6 commit 4baa67e
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 9 deletions.
2 changes: 2 additions & 0 deletions packages/filters/src/Type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ export class Type {

static readonly notContains = 'notContains';

static readonly containsIgnoreCase = 'containsIgnoreCase';

static readonly startsWith = 'startsWith';

static readonly endsWith = 'endsWith';
Expand Down
167 changes: 167 additions & 0 deletions packages/iris-grid/src/GotoRow.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import dh from '@deephaven/jsapi-shim';
import {
Type as FilterType,
TypeValue as FilterTypeValue,
} from '@deephaven/filters';
import { TableUtils } from '@deephaven/jsapi-utils';
import GotoRow from './GotoRow';
import IrisGridTestUtils from './IrisGridTestUtils';

function makeGotoRow({
gotoRow = '',
gotoRowError = '',
gotoValueError = '',
onGotoRowSubmit = jest.fn(),
model = new IrisGridTestUtils(dh).makeModel(),
onGotoRowNumberChanged = jest.fn(),
onClose = jest.fn(),
isShown = true,
onEntering = jest.fn(),
onEntered = jest.fn(),
onExiting = jest.fn(),
onExited = jest.fn(),
gotoValueSelectedColumnName = '',
gotoValue = '',
gotoValueFilter = FilterType.eq,
onGotoValueSelectedColumnNameChanged = jest.fn(),
onGotoValueSelectedFilterChanged = jest.fn(),
onGotoValueChanged = jest.fn(),
onGotoValueSubmit = jest.fn(),
} = {}) {
return render(
<GotoRow
dh={dh}
gotoRow={gotoRow}
gotoRowError={gotoRowError}
gotoValueError={gotoValueError}
onGotoRowSubmit={onGotoRowSubmit}
model={model}
onGotoRowNumberChanged={onGotoRowNumberChanged}
onClose={onClose}
isShown={isShown}
onEntering={onEntering}
onEntered={onEntered}
onExiting={onExiting}
onExited={onExited}
gotoValueSelectedColumnName={gotoValueSelectedColumnName}
gotoValue={gotoValue}
gotoValueFilter={gotoValueFilter as FilterTypeValue}
onGotoValueSelectedColumnNameChanged={
onGotoValueSelectedColumnNameChanged
}
onGotoValueSelectedFilterChanged={onGotoValueSelectedFilterChanged}
onGotoValueChanged={onGotoValueChanged}
onGotoValueSubmit={onGotoValueSubmit}
/>
);
}

beforeEach(() => {
jest.useFakeTimers();
});

afterEach(() => {
jest.useRealTimers();
});

it('mounts and unmounts properly', () => {
makeGotoRow();
});

describe('Go to row', () => {
it('calls onGotoRowSubmit on Enter key press', async () => {
const user = userEvent.setup({ delay: null });
const onGotoRowSubmitMock = jest.fn();
const component = makeGotoRow({ onGotoRowSubmit: onGotoRowSubmitMock });

const inputElement = screen.getByRole('spinbutton');
await user.type(inputElement, '{Enter}');

expect(onGotoRowSubmitMock).toHaveBeenCalledTimes(1);

component.unmount();
});

it('does not call onGotoRowSubmit on non-Enter key press', async () => {
const user = userEvent.setup({ delay: null });
const onGotoRowSubmitMock = jest.fn();
const component = makeGotoRow({ onGotoRowSubmit: onGotoRowSubmitMock });

const inputElement = screen.getByRole('spinbutton');
await user.type(inputElement, 'a1`');

expect(onGotoRowSubmitMock).not.toHaveBeenCalled();

component.unmount();
});

it('calls onGotoRowNumberChanged on number key press', async () => {
const user = userEvent.setup({ delay: null });
const onGotoRowNumberChangedMock = jest.fn();
const component = makeGotoRow({
onGotoRowNumberChanged: onGotoRowNumberChangedMock,
});

const inputElement = screen.getByRole('spinbutton');
await user.type(inputElement, '1');

expect(onGotoRowNumberChangedMock).toHaveBeenCalledTimes(1);

component.unmount();
});
});

describe('Go to value', () => {
it('calls onGotoValueInputChanged when input value changes', async () => {
const user = userEvent.setup({ delay: null });
const onGotoValueInputChangedMock = jest.fn();
const component = makeGotoRow({
onGotoValueChanged: onGotoValueInputChangedMock,
});

const inputElement = screen.getByPlaceholderText('value');
await user.type(inputElement, 'a');

expect(onGotoValueInputChangedMock).toHaveBeenCalledTimes(1);

component.unmount();
});

it('calls onGotoValueSelectedFilterChanged when select value changes', async () => {
const user = userEvent.setup({ delay: null });
const onGotoValueSelectedFilterChangedMock = jest.fn();

jest
.spyOn(TableUtils, 'getNormalizedType')
.mockImplementation(() => TableUtils.dataType.STRING);

const component = makeGotoRow({
onGotoValueSelectedFilterChanged: onGotoValueSelectedFilterChangedMock,
});

const inputElement = screen.getByTestId('filter-type-select');
await user.selectOptions(inputElement, [FilterType.contains]);

expect(onGotoValueSelectedFilterChangedMock).toHaveBeenCalledTimes(1);

component.unmount();
});

it('calls onGotoValueSelectedColumnNameChanged when select value changes', async () => {
const user = userEvent.setup({ delay: null });
const onGotoValueSelectedColumnNameChangedMock = jest.fn();
const component = makeGotoRow({
onGotoValueSelectedColumnNameChanged: onGotoValueSelectedColumnNameChangedMock,
});

const inputElement = screen.getByTestId('column-name-select');
await user.selectOptions(inputElement, ['1']);

expect(onGotoValueSelectedColumnNameChangedMock).toHaveBeenCalledTimes(1);

component.unmount();
});
});
15 changes: 11 additions & 4 deletions packages/iris-grid/src/GotoRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,6 @@ function GotoRow({
({ columns } = model.table);
}

const res = 'Row number';

const { rowCount } = model;

const handleGotoValueNumberKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {
Expand Down Expand Up @@ -193,6 +191,7 @@ function GotoRow({
);
}}
value={gotoValueFilter}
data-testid="filter-type-select"
>
<option key={FilterType.eq} value={FilterType.eq}>
Equals
Expand All @@ -204,7 +203,13 @@ function GotoRow({
key={FilterType.eqIgnoreCase}
value={FilterType.eqIgnoreCase}
>
EqIgnoreCase
Equals (ignore case)
</option>
<option
key={FilterType.containsIgnoreCase}
value={FilterType.containsIgnoreCase}
>
Contains (ignore case)
</option>
</select>
</div>
Expand Down Expand Up @@ -283,6 +288,7 @@ function GotoRow({
<div className="goto-row-input">
<input
ref={gotoRowInputRef}
data-testid="goto-row-input"
type="number"
onKeyDown={e => {
if (e.key === 'Enter') {
Expand All @@ -294,7 +300,7 @@ function GotoRow({
className={classNames('form-control', {
'is-invalid': gotoRowError !== '',
})}
placeholder={res}
placeholder="Row number"
onChange={event => {
onGotoRowNumberChanged(event);
}}
Expand Down Expand Up @@ -331,6 +337,7 @@ function GotoRow({
onGotoValueSelectedColumnNameChanged(columnName);
}}
value={gotoValueSelectedColumnName}
data-testid="column-name-select"
>
{columns.map(column => (
<option key={column.name} value={column.name}>
Expand Down
12 changes: 7 additions & 5 deletions packages/iris-grid/src/IrisGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3339,10 +3339,12 @@ export class IrisGrid extends Component<IrisGridProps, IrisGridState> {
searchFromRow = 0;
}

const isContains = gotoValueSelectedFilter === FilterType.contains;
const isEquals =
gotoValueSelectedFilter === FilterType.eq ||
gotoValueSelectedFilter === FilterType.eqIgnoreCase;
const isContains =
gotoValueSelectedFilter === FilterType.contains ||
gotoValueSelectedFilter === FilterType.containsIgnoreCase;
const isIgnoreCase =
gotoValueSelectedFilter === FilterType.eqIgnoreCase ||
gotoValueSelectedFilter === FilterType.containsIgnoreCase;

try {
const { formatter } = model;
Expand All @@ -3358,7 +3360,7 @@ export class IrisGrid extends Component<IrisGridProps, IrisGridState> {
selectedColumn,
dh.ValueType.STRING,
inputString,
isEquals,
isIgnoreCase,
isContains,
isBackwards ?? false
);
Expand Down

0 comments on commit 4baa67e

Please sign in to comment.