Skip to content

Commit

Permalink
Tests
Browse files Browse the repository at this point in the history
  • Loading branch information
adhamu committed Mar 18, 2022
1 parent 025c2f7 commit 1b19aac
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 61 deletions.
21 changes: 11 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,16 +119,17 @@ export default MyComponent

## Props

| Prop | Description | Type | Default | Required? |
| ------------- | ----------------------------------------------------------------------------- | ----------------- | ----------- | --------- |
| `suggestions` | A collection of HTML elements or React components used for search suggestions | React.ReactNode[] | | Y |
| `id` | ID for entire component | string | `undefined` | N |
| `className` | Optional class name to style component | string | `''` | N |
| `name` | Input name | string | `'q'` | N |
| `placeholder` | Input placeholder | string | `'Search'` | N |
| `autoFocus` | Input autoFocus | boolean | `false` | N |
| `onChange` | Input onChange handler | function | `undefined` | N |
| `withStyles` | Basic styling for the component | boolean | `false` | N |
| Prop | Description | Type | Default | Required? |
| ------------------- | -------------------------------------------------------------------------------------- | ----------------- | ----------- | --------- |
| `suggestions` | A collection of HTML elements or React components used for search suggestions | React.ReactNode[] | | Y |
| `id` | ID for entire component | string | `undefined` | N |
| `className` | Optional class name to style component | string | `''` | N |
| `name` | Input name | string | `'q'` | N |
| `placeholder` | Input placeholder | string | `'Search'` | N |
| `autoFocus` | Input autoFocus | boolean | `false` | N |
| `onChange` | Input onChange handler | function | `undefined` | N |
| `withStyles` | Basic styling for the component | boolean | `false` | N |
| `highlightKeywords` | Highlight letters that match search term by wrapping a `<mark>` tag around suggestions | boolean | `false` | N |

## Styling

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@adhamu/react-search-suggestions",
"version": "2.1.3",
"version": "2.2.0",
"description": "A React input component with pluggable search suggestions.",
"keywords": [
"react",
Expand Down
19 changes: 17 additions & 2 deletions src/__tests__/SearchSuggestions.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'

import SearchSuggestions from '../SearchSuggestions'
import * as getElementText from '../elementText'
import * as elementText from '../elementText'

const suggestions = ['reddit', 'facebook', 'twitter'].map(word => (
<a key={word} href={`https://${word}.com`}>
Expand All @@ -13,7 +13,8 @@ const suggestions = ['reddit', 'facebook', 'twitter'].map(word => (
))

describe('SearchSuggestions', () => {
const mockGetElementText = jest.spyOn(getElementText, 'getElementText')
const mockGetElementText = jest.spyOn(elementText, 'getElementText')
const mockWrapElementText = jest.spyOn(elementText, 'wrapElementText')

beforeEach(jest.clearAllMocks)

Expand Down Expand Up @@ -65,6 +66,12 @@ describe('SearchSuggestions', () => {
it('does not show suggestions if no input has been entered', () => {
expect(screen.queryByRole('list')).not.toBeInTheDocument()
})

it('does not wrap search suggestions', () => {
userEvent.type(screen.getByRole('searchbox'), 't')

expect(mockWrapElementText).not.toHaveBeenCalled()
})
})

describe('renders correctly with custom options', () => {
Expand Down Expand Up @@ -111,6 +118,14 @@ describe('SearchSuggestions', () => {
// eslint-disable-next-line testing-library/no-node-access
expect(container.firstChild).toHaveClass('react-search')
})

it('calls wrapElementText when highlightKeywords provided', () => {
render(<SearchSuggestions suggestions={suggestions} highlightKeywords />)

userEvent.type(screen.getByRole('searchbox'), 't')

expect(mockWrapElementText).toHaveBeenCalledTimes(2)
})
})

it('fires an onChange event if provided', () => {
Expand Down
111 changes: 77 additions & 34 deletions src/__tests__/elementText.test.tsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,89 @@
import React from 'react'

import { getElementText } from '../elementText'
import { render } from '@testing-library/react'

describe('getElementText', () => {
const Test = ({ children }: { children?: React.ReactNode }) => (
<div>{children}</div>
)
import { getElementText, wrapElementText } from '../elementText'

it('handles strings', () => {
expect(getElementText('This is a test')).toBe('This is a test')
})
describe('elementText', () => {
describe('getElementText', () => {
const Test = ({ children }: { children?: React.ReactNode }) => (
<div>{children}</div>
)

it('handles numbers', () => {
expect(getElementText(100)).toBe(100)
})
it('handles strings', () => {
expect(getElementText('This is a test')).toBe('This is a test')
})

it('handles nested markup', () => {
expect(
getElementText(
<ul>
<li>Option 1</li>
<li>Option 2</li>
<li>Option 3</li>
<li>Option 4</li>
</ul>
)
).toBe('Option 1 Option 2 Option 3 Option 4')
it('handles numbers', () => {
expect(getElementText(100)).toBe(100)
})

it('handles nested markup', () => {
expect(
getElementText(
<ul>
<li>Option 1</li>
<li>Option 2</li>
<li>Option 3</li>
<li>Option 4</li>
</ul>
)
).toBe('Option 1 Option 2 Option 3 Option 4')
})

it('handles React elements', () => {
expect(
getElementText(
<Test>
<span>Level 1</span>
<span>Level 2</span>
<span>Level 3</span>
</Test>
)
).toBe('Level 1 Level 2 Level 3')
})

it('returns undefined if no text found', () => {
expect(getElementText(<Test />)).toBeUndefined()
})
})

it('handles React elements', () => {
expect(
getElementText(
<Test>
<span>Level 1</span>
<span>Level 2</span>
<span>Level 3</span>
</Test>
describe('wrapElementText', () => {
it('can handle strings', () => {
const Result = () => <>{wrapElementText(<div>Level One</div>, 'one')}</>

const { container } = render(<Result />)

expect(container.innerHTML).toBe('<div>Level <mark>One</mark></div>')
})

it('can handle elements with children', () => {
const Result = () => (
<>
{wrapElementText(
<div>
<ul>
<li>
<a href="https://twitter.com">Twitter</a>
</li>
<li>
<a href="https://facebook.com">Facebook</a>
</li>
<li>
<a href="https://reddit.com">Reddit</a>
</li>
</ul>
</div>,
'twit'
)}
</>
)
).toBe('Level 1 Level 2 Level 3')
})

it('returns undefined if no text found', () => {
expect(getElementText(<Test />)).toBeUndefined()
const { container } = render(<Result />)

expect(container.innerHTML).toBe(
'<div><ul><li><a href="https://twitter.com"><mark>Twit</mark>ter</a></li><li><a href="https://facebook.com">Facebook</a></li><li><a href="https://reddit.com">Reddit</a></li></ul></div>'
)
})
})
})
16 changes: 2 additions & 14 deletions src/example/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,8 @@ const suggestions = [
'pressure',
'cooperate',
].map(word => (
<a
key={word}
onKeyDown={e => {
if (e.key === 'Enter') {
console.log(word)
}
}}
onClick={() => {
console.log(word)
}}
>
<div>
<div>{word}</div>
</div>
<a key={word} href={`https://www.google.co.uk/search?q=${word}`}>
{word}
</a>
))

Expand Down

0 comments on commit 1b19aac

Please sign in to comment.