Skip to content

Commit

Permalink
feat: add toHaveAccessibilityValue matcher
Browse files Browse the repository at this point in the history
  • Loading branch information
tarunrajput authored and mdjastrzebski committed Oct 23, 2023
1 parent 328466d commit 90b2038
Show file tree
Hide file tree
Showing 5 changed files with 192 additions and 0 deletions.
149 changes: 149 additions & 0 deletions src/matchers/__tests__/to-have-accessibility-value.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import * as React from 'react';
import { View } from 'react-native';
import { render, screen } from '../..';
import '../extend-expect';

function renderViewsWithAccessibilityValue() {
return render(
<>
<View testID="min" accessibilityValue={{ min: 0 }} />
<View testID="max" accessibilityValue={{ max: 100 }} />
<View testID="now" accessibilityValue={{ now: 65 }} />
<View testID="min-max" accessibilityValue={{ min: 0, max: 100 }} />
<View
testID="min-max-now"
accessibilityValue={{ min: 0, max: 100, now: 65 }}
/>
<View
testID="min-max-now-text"
accessibilityValue={{ text: 'test', min: 0, max: 100, now: 65 }}
/>
<View
testID="text"
accessibilityValue={{ text: 'accessibility value' }}
/>
</>
);
}

test('toHaveAccessibilityValue() on matching accessibility value', () => {
renderViewsWithAccessibilityValue();

const min = screen.getByTestId('min');
const max = screen.getByTestId('max');
const now = screen.getByTestId('now');
const text = screen.getByTestId('text');
const minMax = screen.getByTestId('min-max');
const minMaxNow = screen.getByTestId('min-max-now');
const minMaxNowText = screen.getByTestId('min-max-now-text');

expect(min).toHaveAccessibilityValue({ min: 0 });
expect(max).toHaveAccessibilityValue({ max: 100 });
expect(now).toHaveAccessibilityValue({ now: 65 });
expect(minMax).toHaveAccessibilityValue({ min: 0, max: 100 });
expect(minMaxNowText).toHaveAccessibilityValue({
min: 0,
max: 100,
now: 65,
text: 'test',
});
expect(minMaxNow).toHaveAccessibilityValue({ min: 0, max: 100, now: 65 });
expect(text).toHaveAccessibilityValue({ text: 'accessibility value' });
expect(text).toHaveAccessibilityValue({ text: /accessibility/i });

expect(() => expect(min).not.toHaveAccessibilityValue({ min: 0 }))
.toThrowErrorMatchingInlineSnapshot(`
"expect(element).not.toHaveAccessibilityValue({"min": 0})
Expected the element not to have accessibility value:
{"min": 0}
Received element with accessibility value:
{"max": undefined, "min": 0, "now": undefined, "text": undefined}"
`);

expect(() => expect(text).toHaveAccessibilityValue({ text: 'value' }))
.toThrowErrorMatchingInlineSnapshot(`
"expect(element).toHaveAccessibilityValue({"text": "value"})
Expected the element to have accessibility value:
{"text": "value"}
Received element with accessibility value:
{"max": undefined, "min": undefined, "now": undefined, "text": "accessibility value"}"
`);

expect(() => expect(text).toHaveAccessibilityValue({ text: /test/i }))
.toThrowErrorMatchingInlineSnapshot(`
"expect(element).toHaveAccessibilityValue({"text": /test/i})
Expected the element to have accessibility value:
{"text": /test/i}
Received element with accessibility value:
{"max": undefined, "min": undefined, "now": undefined, "text": "accessibility value"}"
`);
});

test('toHaveAccessibilityValue() on non-matching accessibility value', () => {
renderViewsWithAccessibilityValue();

const min = screen.getByTestId('min');
const max = screen.getByTestId('max');
const now = screen.getByTestId('now');
const text = screen.getByTestId('text');
const minMax = screen.getByTestId('min-max');
const minMaxNow = screen.getByTestId('min-max-now');
const minMaxNowText = screen.getByTestId('min-max-now-text');

expect(min).not.toHaveAccessibilityValue({ min: 100 });
expect(max).not.toHaveAccessibilityValue({ max: 0 });
expect(now).not.toHaveAccessibilityValue({ now: 0 });
expect(text).not.toHaveAccessibilityValue({ text: 'accessibility' });
expect(minMax).not.toHaveAccessibilityValue({ min: 100, max: 0 });
expect(minMaxNow).not.toHaveAccessibilityValue({ min: 100, max: 0, now: 0 });
expect(minMaxNowText).not.toHaveAccessibilityValue({
min: 100,
max: 0,
now: 0,
text: 'accessibility',
});

expect(() => expect(min).toHaveAccessibilityValue({ min: 100 }))
.toThrowErrorMatchingInlineSnapshot(`
"expect(element).toHaveAccessibilityValue({"min": 100})
Expected the element to have accessibility value:
{"min": 100}
Received element with accessibility value:
{"max": undefined, "min": 0, "now": undefined, "text": undefined}"
`);
});

test('toHaveAccessibilityValue() when no accessibilityValue prop is provided', () => {
render(<View testID="view" />);

const view = screen.getByTestId('view');

expect(() => expect(view).toHaveAccessibilityValue({ min: 0 }))
.toThrowErrorMatchingInlineSnapshot(`
"expect(element).toHaveAccessibilityValue({"min": 0})
Expected the element to have accessibility value:
{"min": 0}
Received element with accessibility value:
undefined"
`);
});

test('toHaveAccessibilityValue() on partially matching accessibility value', () => {
renderViewsWithAccessibilityValue();

const minMax = screen.getByTestId('min-max');
const minMaxNow = screen.getByTestId('min-max-now');
const minMaxNowText = screen.getByTestId('min-max-now-text');

expect(minMax).toHaveAccessibilityValue({ min: 0 });
expect(minMax).toHaveAccessibilityValue({ max: 100 });
expect(minMaxNow).toHaveAccessibilityValue({ now: 65 });
expect(minMaxNow).toHaveAccessibilityValue({ min: 0, max: 100 });
expect(minMaxNowText).toHaveAccessibilityValue({ text: 'test' });
expect(minMaxNowText).toHaveAccessibilityValue({ text: /te/i });
});
2 changes: 2 additions & 0 deletions src/matchers/extend-expect.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { StyleProp } from 'react-native';
import type { ReactTestInstance } from 'react-test-renderer';
import type { TextMatch, TextMatchOptions } from '../matches';
import type { AccessibilityValueMatcher } from '../helpers/matchers/accessibilityValue';
import type { Style } from './to-have-style';

export interface JestNativeMatchers<R> {
Expand All @@ -20,6 +21,7 @@ export interface JestNativeMatchers<R> {
toHaveProp(name: string, expectedValue?: unknown): R;
toHaveStyle(style: StyleProp<Style>): R;
toHaveTextContent(expectedText: TextMatch, options?: TextMatchOptions): R;
toHaveAccessibilityValue(expectedValue: AccessibilityValueMatcher): R;
}

// Implicit Jest global `expect`.
Expand Down
2 changes: 2 additions & 0 deletions src/matchers/extend-expect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { toHaveDisplayValue } from './to-have-display-value';
import { toHaveProp } from './to-have-prop';
import { toHaveStyle } from './to-have-style';
import { toHaveTextContent } from './to-have-text-content';
import { toHaveAccessibilityValue } from './to-have-accessibility-value';

expect.extend({
toBeOnTheScreen,
Expand All @@ -33,4 +34,5 @@ expect.extend({
toHaveProp,
toHaveStyle,
toHaveTextContent,
toHaveAccessibilityValue,
});
1 change: 1 addition & 0 deletions src/matchers/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export { toBePartiallyChecked } from './to-be-partially-checked';
export { toBeSelected } from './to-be-selected';
export { toBeVisible } from './to-be-visible';
export { toContainElement } from './to-contain-element';
export { toHaveAccessibilityValue } from './to-have-accessibility-value';
export { toHaveDisplayValue } from './to-have-display-value';
export { toHaveProp } from './to-have-prop';
export { toHaveStyle } from './to-have-style';
Expand Down
38 changes: 38 additions & 0 deletions src/matchers/to-have-accessibility-value.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import type { ReactTestInstance } from 'react-test-renderer';
import { matcherHint, stringify } from 'jest-matcher-utils';
import { getAccessibilityValue } from '../helpers/accessiblity';
import {
AccessibilityValueMatcher,
matchAccessibilityValue,
} from '../helpers/matchers/accessibilityValue';
import { checkHostElement, formatMessage } from './utils';

export function toHaveAccessibilityValue(
this: jest.MatcherContext,
element: ReactTestInstance,
expectedValue: AccessibilityValueMatcher
) {
checkHostElement(element, toHaveAccessibilityValue, this);

const value = getAccessibilityValue(element);

return {
pass: matchAccessibilityValue(element, expectedValue),
message: () => {
const matcher = matcherHint(
`${this.isNot ? '.not' : ''}.toHaveAccessibilityValue`,
'element',
stringify(expectedValue)
);
return formatMessage(
matcher,
`Expected the element ${
this.isNot ? 'not to' : 'to'
} have accessibility value`,
stringify(expectedValue),
'Received element with accessibility value',
stringify(value)
);
},
};
}

0 comments on commit 90b2038

Please sign in to comment.