Skip to content

Commit

Permalink
Add tests for replaceCommaSeparatedValue
Browse files Browse the repository at this point in the history
  • Loading branch information
malwilley committed Sep 20, 2024
1 parent 014de92 commit ccae954
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {getEscapedKey} from 'sentry/components/compactSelect/utils';
import {useSearchQueryBuilder} from 'sentry/components/searchQueryBuilder/context';
import {SearchQueryBuilderCombobox} from 'sentry/components/searchQueryBuilder/tokens/combobox';
import {FunctionDescription} from 'sentry/components/searchQueryBuilder/tokens/filter/functionDescription';
import {replaceCommaSeparatedValue} from 'sentry/components/searchQueryBuilder/tokens/filter/utils';
import {replaceCommaSeparatedValue} from 'sentry/components/searchQueryBuilder/tokens/filter/replaceCommaSeparatedValue';
import type {AggregateFilter} from 'sentry/components/searchSyntax/parser';
import {t} from 'sentry/locale';
import {FieldKind, FieldValueType} from 'sentry/utils/fields';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@

text_in_list
= item1:text_in_value
items:(spaces comma spaces (!comma text_in_value)?)* {
items:item* {
return tc.tokenValueTextList(item1, items);
}

item = s1:spaces c:comma s2:spaces value:(!comma text_in_value)? {
return [s1, c, s2, value ?? [undefined, tc.tokenValueText('', false)]];
}

text_in_value
= quoted_value / in_value / empty_value

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ describe('parseMultiSelectValue', function () {
expect(result!.items).toHaveLength(3);

expect(result?.items[0].value?.value).toEqual('a');
expect(result?.items[1].value).toBe(null);
expect(result?.items[1].value?.value).toBe('');
expect(result?.items[2].value?.value).toEqual('b');
});

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import {replaceCommaSeparatedValue} from 'sentry/components/searchQueryBuilder/tokens/filter/replaceCommaSeparatedValue';

describe('replaceCommaSeparatedValue', function () {
it('replaces a value without commas', function () {
expect(replaceCommaSeparatedValue('foo', 3, 'bar')).toBe('bar');
});

it('replaces an empty value at end', function () {
expect(replaceCommaSeparatedValue('foo,', 4, 'bar')).toBe('foo,bar');
});

it('replaces an empty value at start', function () {
expect(replaceCommaSeparatedValue(',foo', 0, 'bar')).toBe('bar,foo');
});

it('replaces an empty value in middle', function () {
expect(replaceCommaSeparatedValue('foo,,baz', 4, 'bar')).toBe('foo,bar,baz');
});

it('replaces an non-empty value at end', function () {
expect(replaceCommaSeparatedValue('foo,abc', 4, 'bar')).toBe('foo,bar');
});

it('replaces an non-empty value at start', function () {
expect(replaceCommaSeparatedValue('abc,foo', 0, 'bar')).toBe('bar,foo');
});

it('replaces an non-empty value in middle', function () {
expect(replaceCommaSeparatedValue('foo,abc,baz', 4, 'bar')).toBe('foo,bar,baz');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import {parseMultiSelectFilterValue} from 'sentry/components/searchQueryBuilder/tokens/filter/parsers/string/parser';

/**
* Replaces the focused parameter (at cursorPosition) with the new value.
* If cursorPosition is null, will default to the end of the string.
*
* Example:
* replaceCommaSeparatedValue('foo,bar,baz', 5, 'new') => 'foo,new,baz'
*/
export function replaceCommaSeparatedValue(
value: string,
cursorPosition: number | null,
replacement: string
) {
const parsed = parseMultiSelectFilterValue(value);

if (!parsed) {
return value;
}

if (cursorPosition === null) {
cursorPosition = value.length;
}

const matchingIndex = parsed.items.findIndex(
item =>
item.value &&
item.value?.location.start.offset <= cursorPosition &&
item.value?.location.end.offset >= cursorPosition
);

if (matchingIndex === -1) {
return replacement;
}

return [
...parsed.items.slice(0, matchingIndex).map(item => item.value?.text ?? ''),
replacement,
...parsed.items.slice(matchingIndex + 1).map(item => item.value?.text ?? ''),
].join(',');
}
41 changes: 0 additions & 41 deletions static/app/components/searchQueryBuilder/tokens/filter/utils.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import {parseMultiSelectFilterValue} from 'sentry/components/searchQueryBuilder/tokens/filter/parsers/string/parser';
import {
type AggregateFilter,
allOperators,
Expand Down Expand Up @@ -92,46 +91,6 @@ export function formatFilterValue(token: TokenResult<Token.FILTER>['value']): st
}
}

/**
* Replaces the focused parameter (at cursorPosition) with the new value.
* If cursorPosition is null, will default to the end of the string.
*
* Example:
* replaceCommaSeparatedValue('foo,bar,baz', 5, 'new') => 'foo,new,baz'
*/
export function replaceCommaSeparatedValue(
value: string,
cursorPosition: number | null,
replacement: string
) {
const parsed = parseMultiSelectFilterValue(value);

if (!parsed) {
return value;
}

if (cursorPosition === null) {
cursorPosition = value.length;
}

const matchingIndex = parsed.items.findIndex(
item =>
item.value &&
item.value?.location.start.offset <= cursorPosition &&
item.value?.location.end.offset >= cursorPosition
);

if (matchingIndex === -1) {
return replacement;
}

return [
...parsed.items.slice(0, matchingIndex).map(item => item.value?.text ?? ''),
replacement,
...parsed.items.slice(matchingIndex + 1).map(item => item.value?.text ?? ''),
].join(',');
}

/**
* Gets the value type for a given token.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ import {
SearchQueryBuilderCombobox,
} from 'sentry/components/searchQueryBuilder/tokens/combobox';
import {parseMultiSelectFilterValue} from 'sentry/components/searchQueryBuilder/tokens/filter/parsers/string/parser';
import {replaceCommaSeparatedValue} from 'sentry/components/searchQueryBuilder/tokens/filter/replaceCommaSeparatedValue';
import SpecificDatePicker from 'sentry/components/searchQueryBuilder/tokens/filter/specificDatePicker';
import {
escapeTagValue,
formatFilterValue,
getFilterValueType,
replaceCommaSeparatedValue,
unescapeTagValue,
} from 'sentry/components/searchQueryBuilder/tokens/filter/utils';
import {ValueListBox} from 'sentry/components/searchQueryBuilder/tokens/filter/valueListBox';
Expand Down

0 comments on commit ccae954

Please sign in to comment.