import 'mocha' import { assert } from 'chai' import * as React from 'react' import { mount, ReactWrapper } from 'enzyme' import * as sinon from 'sinon' import { codes as keycodes } from 'keycode' import * as numberSuffix from 'ordinal-number-suffix' import a11yTest from '../testutils/a11yTest' import Accordion, { AccordionItem } from '..' describe('', () => { let consoleSpy: sinon.SinonSpy beforeEach(() => { consoleSpy = sinon.spy(console, 'error') }) afterEach(() => { consoleSpy.restore() }) it('should render without errors', () => { assert.doesNotThrow(() => { mount( One content Two content ) }) }) describe('given a custom classPrefix', () => { let m: ReactWrapper before(() => { m = mount( One content ) }) it('should use the prefix', () => { const el = m.find('.Test') assert(el.length) }) it('should pass the prefix down to all children', () => { const item = m.find('.Test-item') assert(item.length) const title = m.find('.Test-item-title') assert(title.length) const content = m.find('.Test-item-content') assert(content.length) }) }) describe('given no children', () => { it('should warn', () => { try { // @ts-ignore mount() } catch (error) { // Ignore } assert.isTrue(consoleSpy.called) const call = consoleSpy.getCall(0) const warning = call.args[0] assert.include( warning, 'Accordion expects at least a single AccordionItem child' ) }) }) describe('given non-item children', () => { it('should warn', () => { try { mount(
) } catch (error) { // Ignore } assert.isTrue(consoleSpy.called) const call = consoleSpy.getCall(0) const warning = call.args[0] assert.include( warning, 'Accordion expects children to be of type AccordionItem' ) }) }) describe('when toggling an item', () => { describe('when the item is closed', () => { it("should set `state.selectedItemId` to the item's id", () => { const m = mount( hello ) const trigger = m.find('.Accordion-item-trigger') trigger.simulate('click') const node = trigger.getDOMNode() const triggerId = node.id const itemId = triggerId.replace('_title', '') assert.equal((m.state() as any).selectedItemId, itemId) }) }) describe('when the item is open', () => { it('should set `state.selectedItemid` to `null`', async () => { const m = mount( hello ) const trigger = m.find('.Accordion-item-trigger') // Open the item. trigger.simulate('click') // Next tick. await Promise.resolve() // Close the item. trigger.simulate('click') assert.equal((m.state() as any).selectedItemId, null) }) }) }) describe('keyboard events', () => { let m: ReactWrapper let triggers: ReactWrapper beforeEach(() => { m = mount( hello hello hello ) triggers = m.find('.Accordion-item-trigger') }) interface KeyboardTestCase { keyname: string startIndex: number endIndex: number } const tests: KeyboardTestCase[] = [ { keyname: 'up', startIndex: 0, endIndex: 2 }, { keyname: 'up', startIndex: 1, endIndex: 0 }, { keyname: 'down', startIndex: 0, endIndex: 1 }, { keyname: 'down', startIndex: 2, endIndex: 0 }, { keyname: 'home', startIndex: 1, endIndex: 0 }, { keyname: 'end', startIndex: 1, endIndex: 2 } ] tests.forEach(({ keyname, startIndex, endIndex }) => { const s = numberSuffix(startIndex) describe(`pressing "${keyname}" on the ${s} element`, () => { it('should focus the correct element', () => { const start = triggers.at(startIndex) const end = triggers.at(endIndex) const endNode = end.getDOMNode() const focusSpy = sinon.spy(endNode as HTMLButtonElement, 'focus') start.simulate('keydown', { which: keycodes[keyname] }) assert.isTrue(focusSpy.called, 'Did not focus expected element') }) }) }) }) a11yTest( One content Two content ) })