react-widgets
Version:
An à la carte set of polished, extensible, and accessible inputs built for React
269 lines (190 loc) • 8.98 kB
JSX
;
/*global it, describe, expect, sinon*/
require('../vendor/phantomjs-shim')
import { findDOMNode } from 'react-dom';
var React = require('react/addons');
var DateTimePicker = require('../src/DateTimePicker.jsx')
, TimeList = require('../src/TimeList.jsx')
, Calendar = require('../src/Calendar.jsx').ControlledComponent
, Globalize = require('globalize');
var TestUtils = React.addons.TestUtils
, render = TestUtils.renderIntoDocument
, findTag = TestUtils.findRenderedDOMComponentWithTag
, findClass = TestUtils.findRenderedDOMComponentWithClass
, findType = TestUtils.findRenderedComponentWithType
, findAllType = TestUtils.scryRenderedComponentsWithType
, trigger = TestUtils.Simulate;
describe('DateTimePicker', function(){
it('should set initial values', function(){
var date = new Date()
, instance = render(<DateTimePicker defaultValue={date} format="MM-dd-yyyy"/>)
, input = findClass(instance, 'rw-input');
expect( input.value).to.be(Globalize.format(date, 'MM-dd-yyyy'));
})
it('should start closed', function(done){
var instance = render(<DateTimePicker defaultValue={new Date()} />);
var popups = findAllType(instance, require('../src/Popup.jsx'));
expect(instance._values.open).to.not.be(true)
expect(findDOMNode(instance).className).to.not.match(/\brw-open\b/)
expect(findClass(instance, 'rw-input').getAttribute('aria-expanded')).to.be('false')
setTimeout(function(){
expect(popups.length).to.be(2)
popups.forEach( popup => expect(findDOMNode(popup).style.display).to.be('none'))
done()
})
})
it('should open when clicked', function(){
var onOpen = sinon.spy()
, instance = render(<DateTimePicker onToggle={onOpen} />);
trigger.click(findClass(instance, 'rw-btn-calendar'))
expect(onOpen.calledOnce).to.be(true)
trigger.click(findClass(instance, 'rw-btn-time'))
expect(onOpen.calledTwice).to.be(true)
})
it('should change when selecting a time or date', function(){
var change = sinon.spy()
, instance = render(<DateTimePicker onChange={change} open='calendar' onToggle={()=>{}} />)
, calendar = findType(instance, Calendar)
, timelist = findDOMNode(findType(instance, require('../src/List.jsx'))).children
calendar.change(new Date())
expect(change.calledOnce).to.be(true)
trigger.click(timelist[0])
expect(change.calledTwice).to.be(true)
})
it('should set id on list', function(){
var instance = render(<DateTimePicker />)
, list = findTag(instance, 'ul');
expect(list.hasAttribute('id')).to.be(true);
})
it('should not show time button when not selected', function(){
var spy
, instance = render(<DateTimePicker time={false} calendar={false} onToggle={spy = sinon.spy()}/>);
expect(() => findClass(instance, 'rw-btn-time')).to
.throwException(/Did not find exactly one match.+/)
expect(() => findClass(instance, 'rw-btn-calendar')).to
.throwException(/Did not find exactly one match.+/)
//make sure keyboard shortcuts don't work either
trigger.keyDown(findDOMNode(instance), { altKey: true })
expect(spy.callCount).to.be(0)
trigger.keyDown(findDOMNode(instance), { altKey: true })
expect(spy.callCount).to.be(0)
})
it('should trigger focus/blur events', function(done){
var blur = sinon.spy()
, focus = sinon.spy()
, instance = render(<DateTimePicker onBlur={blur} onFocus={focus}/>);
expect(focus.calledOnce).to.be(false)
expect(blur.calledOnce).to.be(false)
trigger.focus(findDOMNode(instance))
setTimeout(() => {
expect(focus.calledOnce).to.be(true)
trigger.blur(findDOMNode(instance))
setTimeout(() => {
expect(blur.calledOnce).to.be(true)
done()
})
})
})
it('should trigger key events', function(){
var kp = sinon.spy(), kd = sinon.spy(), ku = sinon.spy()
, instance = render(<DateTimePicker onKeyPress={kp} onKeyUp={ku} onKeyDown={kd}/>)
, input = findClass(instance, 'rw-input');
trigger.keyPress(input)
trigger.keyDown(input)
trigger.keyUp(input)
expect(kp.calledOnce).to.be(true)
expect(kd.calledOnce).to.be(true)
expect(ku.calledOnce).to.be(true)
})
it('should do nothing when disabled', function(done){
var instance = render(<DateTimePicker defaultValue={new Date()} disabled/>)
, input = findClass(instance, 'rw-input');
expect( input.hasAttribute('disabled')).to.be(true);
trigger.click(findClass(instance, 'rw-i-calendar'))
setTimeout(() => {
expect(instance._values.open).to.not.be(true)
done()
})
})
it('should do nothing when readonly', function(done){
var instance = render(<DateTimePicker defaultValue={new Date()} readOnly/>)
, input = findClass(instance, 'rw-input');
expect( input.hasAttribute('readonly')).to.be(true);
trigger.click(findClass(instance, 'rw-i-calendar'))
setTimeout(() => {
expect(instance._values.open).to.not.be(true)
done()
})
})
it('should call Select handler', function(){
var change = sinon.spy(), select = sinon.spy()
, instance = render(<DateTimePicker onChange={change} onSelect={select}/>)
, calendar = findType(instance, Calendar)
, timelist = findDOMNode(findType(instance, require('../src/List.jsx'))).children;
calendar.change(new Date())
expect(select.calledOnce).to.be(true)
expect(change.calledAfter(select)).to.be(true)
select.reset()
change.reset()
trigger.click(timelist[0])
expect(select.calledOnce).to.be(true)
expect(change.calledAfter(select)).to.be(true)
})
it('should change values on key down', function(){
var change = sinon.spy()
, instance = render(<DateTimePicker onChange={change} />)
, timelist = findDOMNode(findType(instance, require('../src/List.jsx'))).children;
trigger.keyDown(findDOMNode(instance), { key: 'ArrowDown', altKey: true })
expect(instance._values.open).to.be('calendar')
trigger.keyDown(findDOMNode(instance), { key: 'ArrowDown', altKey: true })
expect(instance._values.open).to.be('time')
trigger.keyDown(findDOMNode(instance), { key: 'Home'})
expect(timelist[0].className).to.match(/\brw-state-focus\b/)
trigger.keyDown(findDOMNode(instance), { key: 'End'})
expect(timelist[timelist.length - 1].className).to.match(/\brw-state-focus\b/)
trigger.keyDown(findDOMNode(instance), { key: 'ArrowUp' })
expect(timelist[timelist.length - 2].className).to.match(/\brw-state-focus\b/)
trigger.keyDown(findDOMNode(instance), { key: 'ArrowDown' })
expect(timelist[timelist.length - 1].className).to.match(/\brw-state-focus\b/)
})
describe('TimeList', function(){
it('should render max correctly', ()=>{
var date = new Date(2014, 0, 16, 9, 30)
, inst = render(<TimeList value={new Date(2014, 0, 16, 8)} max={date} preserveDate/>)
var time = inst.state.dates[inst.state.dates.length - 1]
expect(time.date.getHours()).to.eql(9)
expect(time.date.getMinutes()).to.eql(30)
expect(time.date.getSeconds()).to.eql(0)
inst = render(<TimeList value={new Date(2014, 0, 15, 8)} max={date} preserveDate/>)
time = inst.state.dates[inst.state.dates.length - 1]
expect(time.date.getHours()).to.eql(23)
expect(time.date.getMinutes()).to.eql(30)
expect(time.date.getSeconds()).to.eql(0)
})
it('should render min correctly', ()=>{
var date = new Date(2014, 0, 16, 9, 30)
, inst = render(<TimeList value={new Date(2014, 0, 16, 12)} min={date} preserveDate/>)
var time = inst.state.dates[0]
expect(time.date.getHours()).to.eql(9)
expect(time.date.getMinutes()).to.eql(30)
expect(time.date.getSeconds()).to.eql(0)
inst = render(<TimeList value={new Date(2014, 0, 18, 8)} min={date} preserveDate/>)
time = inst.state.dates[0]
expect(time.date.getHours()).to.eql(0)
expect(time.date.getMinutes()).to.eql(0)
expect(time.date.getSeconds()).to.eql(0)
})
it('should set the step property', ()=>{
var inst = render(<DateTimePicker step={60}/>);
var dates = findType(inst, TimeList).state.dates
expect(dates[0].date.getHours()).to.eql(0)
expect(dates[1].date.getHours()).to.eql(1)
expect(dates[2].date.getHours()).to.eql(2)
inst = render(<DateTimePicker step={120}/>)
dates = findType(inst, TimeList).state.dates
expect(dates[0].date.getHours()).to.eql(0)
expect(dates[1].date.getHours()).to.eql(2)
expect(dates[2].date.getHours()).to.eql(4)
})
})
})