# Testing

All components must have unit tests.

Please aim to create functional components and write tests using React Testing Library (use `*.spec.rt.js` file names to have them included)

Example:

    import React from 'react';
    import { shallow } from 'enzyme';
    import TouchableOpacity from '../../TouchableOpacity';

    describe('<TrackComponent />', () => {
        let wrapper;
        let nameElement;

        const name = 'Translucent';
        const onPress = jest.fn();

        const defaultProps = {
            name,
            onPress
        };

        const render = (props = {}) => {
            wrapper = shallow(<TrackComponent { ...defaultProps } { ...props } />);
            nameElement = wrapper.find({ testID: 'name' });
            touchableElement = wrapper.find(TouchableOpacity);
        }

        beforeEach(render);
        afterEach(jest.resetAllMocks);

        test('renders', () =>
            expect(wrapper).toMatchSnapshot());

        describe('<Text testID="name" />', () =>
            test('contains value from name prop', () =>
                expect(nameElement.text()).toContain(name)));

        describe('<TouchableOpacity />', () =>
            describe('is pressed', () => {
                beforeEach(() => touchableElement.props().onPress());
                test('calls onPress prop', () =>
                    expect(onPress).toHaveBeenCalled());
            }));

    });

## `render` function

Each component test should define a `render` function with the following method signature:

    const render = (props = {}) => {

Where the parameter `props` represents overrides to the `defaultProps` passed in for rendering the
component default/base case. This should occur by spreading the `props` after `defaultProps`:

    wrapper = shallow(<TrackComponent { ...defaultProps } { ...props } />);

`render` should initialize the component wrapper, as well as any additional elements of
the component which will also be under test.

Rendering overrides should occur by calling the `render` function with overridden arguments in a
`beforeEach` block of a `describe`, for example:

    beforeEach(() => render({ name: 'Hold Your Hand' });

## Snapshots

At least one snapshot of a component in a base/default state should exist, for example:

    test('renders', () =>
        expect(wrapper).toMatchSnapshot());

This will produce an output in the `__tests__/__snapshot__` folder of the component.

## `test` and `describe`

In general, `describe` blocks should be used to define the conditions which set up the testing scenario.
`test` blocks should be used to specify, generally, at least one assertion (unless this is
prohibitively difficult). For example, a function:

    const square = a => a*a;

Could be tested as:

    describe('square', () => {
        let number;

        describe('called with a negative number', () => {
            beforeEach(() => {
                number = -1;
            });

            test('returns a positive number', () =>
                expect(square(number) > 0).toEqual(true));
        });

        describe('called with zero', () => {
            beforeEach(() => {
                number = 0;
            });

            test('returns zero', () =>
                expect(square(number)).toEqual(0));
        });

        describe('called with a positive number', () => {
            beforeEach(() => {
                number = 1;
            });

            test('returns a positive number', () =>
                expect(square(number) > 0).toEqual(true));
        });

    });

Where:

  * The `describe` blocks specify the conditions under test.
  * The `test` blocks specify a single, exact expectation.
