import React from 'react' ; import { assert } from 'chai' ; import { shallow } from 'enzyme' ; import td from 'testdouble' ; import { Checkbox } from '../../../packages/checkbox/index' ; import { MDCCheckboxAdapter } from '@material/checkbox/adapter' ; import { coerceForTesting } from '../helpers/types' ; suite ( 'Checkbox' ) ; const getAdapter = ( instance ) : MDCCheckboxAdapter => { return instance . foundation . adapter_ ; } ; test ( 'creates foundation' , ( ) => { const wrapper = shallow < Checkbox > ( < Checkbox />); assert . exists ( wrapper . instance ( ) . foundation ) ; } ) ; test ( 'has mdc-checkbox class' , ( ) => { const wrapper = shallow ( < Checkbox />); assert . exists ( wrapper . find ( '.mdc-checkbox' ) ) ; } ) ; test ( 'renders native control' , ( ) => { const wrapper = shallow ( < Checkbox />); assert . exists ( wrapper . find ( '.mdc-checkbox__native-control' ) ) ; } ) ; test ( 'classNames adds classes' , ( ) => { const wrapper = shallow ( < Checkbox className = 'test-class-name' / > ) ; assert . isTrue ( wrapper . hasClass ( 'test-class-name' ) ) ; } ) ; test ( 'has disabled class when props.disabled is true' , ( ) => { const wrapper = shallow ( < Checkbox disabled / > ) ; assert . isTrue ( wrapper . find ( '.mdc-checkbox' ) . hasClass ( 'mdc-checkbox--disabled' ) ) ; } ) ; test ( 'has disabled class when foundation calls setDisabled is true' , ( ) => { const wrapper = shallow < Checkbox > ( < Checkbox />); getAdapter ( wrapper . instance ( ) ) . setNativeControlDisabled ( true ) ; wrapper . update ( ) ; assert . isTrue ( wrapper . find ( '.mdc-checkbox' ) . hasClass ( 'mdc-checkbox--disabled' ) ) ; } ) ; test ( 'native control props.disabled is true when props.disabled is true' , ( ) => { const wrapper = shallow ( < Checkbox disabled / > ) ; const nativeControl = wrapper . childAt ( 0 ) ; assert . isTrue ( nativeControl . props ( ) . disabled ) ; } ) ; test ( 'native control props.disabled when foundation calls setDisabled is true' , ( ) => { const wrapper = shallow < Checkbox > ( < Checkbox />); getAdapter ( wrapper . instance ( ) ) . setNativeControlDisabled ( true ) ; wrapper . update ( ) ; const nativeControl = wrapper . childAt ( 0 ) ; assert . isTrue ( nativeControl . props ( ) . disabled ) ; } ) ; test ( 'native control props.checked is true when props.checked is true' , ( ) => { const wrapper = shallow ( < Checkbox checked / > ) ; const nativeControl = wrapper . childAt ( 0 ) ; assert . isTrue ( nativeControl . props ( ) . checked ) ; } ) ; test ( '#foundation.handleChange gets called when prop.checked updates' , ( ) => { const wrapper = shallow < Checkbox > ( < Checkbox />); wrapper . instance ( ) . foundation . handleChange = td . func < ( ) => null > ( ) ; wrapper . setProps ( { checked : true } ) ; td . verify ( wrapper . instance ( ) . foundation . handleChange ( ) , { times : 1 } ) ; } ) ; test ( '#foundation.handleChange gets called when prop.indeterminate updates' , ( ) => { const wrapper = shallow < Checkbox > ( < Checkbox />); wrapper . instance ( ) . foundation . handleChange = td . func < ( ) => null > ( ) ; wrapper . setProps ( { indeterminate : true } ) ; td . verify ( wrapper . instance ( ) . foundation . handleChange ( ) , { times : 1 } ) ; } ) ; test ( '#foundation.setDisabled gets called when prop.disabled updates' , ( ) => { const wrapper = shallow < Checkbox > ( < Checkbox />); wrapper . instance ( ) . foundation . setDisabled = td . func < ( disabled : boolean ) => null > ( ) ; wrapper . setProps ( { disabled : true } ) ; td . verify ( wrapper . instance ( ) . foundation . setDisabled ( true ) , { times : 1 } ) ; } ) ; test ( '#componentWillUnmount destroys foundation' , ( ) => { const wrapper = shallow < Checkbox > ( < Checkbox />); const foundation = wrapper . instance ( ) . foundation ; foundation . destroy = td . func < ( ) => void > ( ) ; wrapper . unmount ( ) ; td . verify ( foundation . destroy ( ) , { times : 1 } ) ; } ) ; test ( '#adapter.addClass adds class to state.classList' , ( ) => { const wrapper = shallow < Checkbox > ( < Checkbox />); getAdapter ( wrapper . instance ( ) ) . addClass ( 'test-class-name' ) ; assert . isTrue ( wrapper . state ( ) . classList . has ( 'test-class-name' ) ) ; } ) ; test ( '#adapter.removeClass removes class from state.classList' , ( ) => { const wrapper = shallow < Checkbox > ( < Checkbox />); wrapper . setState ( { classList : new Set ( [ 'test-class-name' ] ) } ) ; getAdapter ( wrapper . instance ( ) ) . removeClass ( 'test-class-name' ) ; assert . isFalse ( wrapper . state ( ) . classList . has ( 'test-class-name' ) ) ; } ) ; test ( '#adapter.isChecked returns state.checked if true' , ( ) => { const wrapper = shallow < Checkbox > ( < Checkbox />); wrapper . setState ( { checked : true } ) ; assert . isTrue ( getAdapter ( wrapper . instance ( ) ) . isChecked ( ) ) ; } ) ; test ( '#adapter.isChecked returns state.checked if false' , ( ) => { const wrapper = shallow < Checkbox > ( < Checkbox />); wrapper . setState ( { checked : false } ) ; assert . isFalse ( getAdapter ( wrapper . instance ( ) ) . isChecked ( ) ) ; } ) ; test ( '#adapter.isIndeterminate returns state.indeterminate if true' , ( ) => { const wrapper = shallow < Checkbox > ( < Checkbox />); wrapper . setState ( { indeterminate : true } ) ; assert . isTrue ( getAdapter ( wrapper . instance ( ) ) . isIndeterminate ( ) ) ; } ) ; test ( '#adapter.isIndeterminate returns state.indeterminate if false' , ( ) => { const wrapper = shallow < Checkbox > ( < Checkbox />); wrapper . setState ( { indeterminate : false } ) ; assert . isFalse ( getAdapter ( wrapper . instance ( ) ) . isIndeterminate ( ) ) ; } ) ; test ( '#adapter.setNativeControlAttr sets aria-checked state' , ( ) => { const wrapper = shallow < Checkbox > ( < Checkbox />); getAdapter ( wrapper . instance ( ) ) . setNativeControlAttr ( 'aria-checked' , 'true' ) ; assert . equal ( wrapper . state ( ) [ 'aria-checked' ] , 'true' ) ; } ) ; test ( '#adapter.removeNativeControlAttr sets aria-checked state as false' , ( ) => { const wrapper = shallow < Checkbox > ( < Checkbox />); wrapper . setState ( { 'aria-checked' : 'true' } ) ; getAdapter ( wrapper . instance ( ) ) . removeNativeControlAttr ( 'aria-checked' ) ; assert . isFalse ( wrapper . state ( ) [ 'aria-checked' ] ) ; } ) ; test ( 'passes nativeControlId to NativeControl through props' , ( ) => { const wrapper = shallow ( < Checkbox nativeControlId = 'test-id' / > ) ; assert . equal ( wrapper . childAt ( 0 ) . props ( ) . id , 'test-id' ) ; } ) ; test ( 'passes name to NativeControl through props' , ( ) => { const wrapper = shallow ( < Checkbox name = 'test-name' / > ) ; assert . equal ( wrapper . childAt ( 0 ) . props ( ) . name , 'test-name' ) ; } ) ; test ( 'calls foundation.handleChange in native control props.onChange' , ( ) => { const wrapper = shallow < Checkbox > ( < Checkbox />); const nativeControl = wrapper . childAt ( 0 ) ; const mockEvt = { target : { checked : true , indeterminate : false , } , } ; wrapper . instance ( ) . foundation . handleChange = td . func < ( ) => void > ( ) ; nativeControl . simulate ( 'change' , mockEvt ) ; td . verify ( wrapper . instance ( ) . foundation . handleChange ( ) , { times : 1 } ) ; } ) ; test ( 'calls props.onChange in native control props.onChange' , ( ) => { const onChange = coerceForTesting < ( evt : React . ChangeEvent < HTMLInputElement > ) => void > ( td . func ( ) ) ; const wrapper = shallow ( < Checkbox onChange = { onChange } / > ) ; const nativeControl = wrapper . childAt ( 0 ) ; const mockEvt = coerceForTesting < React . ChangeEvent < HTMLInputElement > > ( { target : { checked : true , indeterminate : false , } , } ) ; nativeControl . simulate ( 'change' , mockEvt ) ; td . verify ( onChange ( mockEvt ) , { times : 1 } ) ; } ) ;