@@ -8,7 +8,7 @@ describe('timepicker directive', function () {
8
8
$rootScope = _$rootScope_ ;
9
9
$rootScope . time = newTime ( 14 , 40 ) ;
10
10
11
- element = $compile ( '<timepicker ng-model="time"></timepicker>' ) ( $rootScope ) ;
11
+ element = $compile ( '<timepicker ng-model="$parent. time"></timepicker>' ) ( $rootScope ) ;
12
12
$rootScope . $digest ( ) ;
13
13
} ) ) ;
14
14
@@ -82,6 +82,15 @@ describe('timepicker directive', function () {
82
82
expect ( getModelState ( ) ) . toEqual ( [ 14 , 40 ] ) ;
83
83
} ) ;
84
84
85
+ it ( 'has `selected` current time when model is initially cleared' , function ( ) {
86
+ $rootScope . time = null ;
87
+ element = $compile ( '<timepicker ng-model="$parent.time"></timepicker>' ) ( $rootScope ) ;
88
+ $rootScope . $digest ( ) ;
89
+
90
+ expect ( $rootScope . time ) . toBe ( null ) ;
91
+ expect ( getTimeState ( ) ) . not . toEqual ( [ '' , '' , '' ] ) ;
92
+ } ) ;
93
+
85
94
it ( 'changes inputs when model changes value' , function ( ) {
86
95
$rootScope . time = newTime ( 11 , 50 ) ;
87
96
$rootScope . $digest ( ) ;
@@ -235,7 +244,7 @@ describe('timepicker directive', function () {
235
244
} ) ;
236
245
237
246
it ( 'changes only the time part when minutes change' , function ( ) {
238
- element = $compile ( '<timepicker ng-model="time" minute-step="15"></timepicker>' ) ( $rootScope ) ;
247
+ element = $compile ( '<timepicker ng-model="$parent. time" minute-step="15"></timepicker>' ) ( $rootScope ) ;
239
248
$rootScope . time = newTime ( 0 , 0 ) ;
240
249
$rootScope . $digest ( ) ;
241
250
@@ -367,7 +376,7 @@ describe('timepicker directive', function () {
367
376
$rootScope . hstep = 2 ;
368
377
$rootScope . mstep = 30 ;
369
378
$rootScope . time = newTime ( 14 , 0 ) ;
370
- element = $compile ( '<timepicker ng-model="time" hour-step="hstep" minute-step="mstep"></timepicker>' ) ( $rootScope ) ;
379
+ element = $compile ( '<timepicker ng-model="$parent. time" hour-step="hstep" minute-step="mstep"></timepicker>' ) ( $rootScope ) ;
371
380
$rootScope . $digest ( ) ;
372
381
} ) ;
373
382
@@ -530,7 +539,7 @@ describe('timepicker directive', function () {
530
539
beforeEach ( function ( ) {
531
540
$rootScope . meridian = false ;
532
541
$rootScope . time = newTime ( 14 , 10 ) ;
533
- element = $compile ( '<timepicker ng-model="time" show-meridian="meridian"></timepicker>' ) ( $rootScope ) ;
542
+ element = $compile ( '<timepicker ng-model="$parent. time" show-meridian="meridian"></timepicker>' ) ( $rootScope ) ;
534
543
$rootScope . $digest ( ) ;
535
544
} ) ;
536
545
@@ -559,6 +568,14 @@ describe('timepicker directive', function () {
559
568
expect ( getModelState ( ) ) . toEqual ( [ 14 , 10 ] ) ;
560
569
expect ( getMeridianTd ( ) . css ( 'display' ) ) . toBe ( 'none' ) ;
561
570
} ) ;
571
+
572
+ it ( 'handles correctly initially empty model on parent element' , function ( ) {
573
+ $rootScope . time = null ;
574
+ element = $compile ( '<span ng-model="time"><timepicker show-meridian="meridian"></timepicker></span>' ) ( $rootScope ) ;
575
+ $rootScope . $digest ( ) ;
576
+
577
+ expect ( $rootScope . time ) . toBe ( null ) ;
578
+ } ) ;
562
579
} ) ;
563
580
564
581
describe ( 'setting timepickerConfig steps' , function ( ) {
@@ -568,7 +585,7 @@ describe('timepicker directive', function () {
568
585
timepickerConfig . hourStep = 2 ;
569
586
timepickerConfig . minuteStep = 10 ;
570
587
timepickerConfig . showMeridian = false ;
571
- element = $compile ( '<timepicker ng-model="time"></timepicker>' ) ( $rootScope ) ;
588
+ element = $compile ( '<timepicker ng-model="$parent. time"></timepicker>' ) ( $rootScope ) ;
572
589
$rootScope . $digest ( ) ;
573
590
} ) ) ;
574
591
afterEach ( inject ( function ( timepickerConfig ) {
@@ -614,7 +631,7 @@ describe('timepicker directive', function () {
614
631
angular . extend ( originalConfig , timepickerConfig ) ;
615
632
timepickerConfig . meridians = [ 'π.μ.' , 'μ.μ.' ] ;
616
633
timepickerConfig . showMeridian = true ;
617
- element = $compile ( '<timepicker ng-model="time"></timepicker>' ) ( $rootScope ) ;
634
+ element = $compile ( '<timepicker ng-model="$parent. time"></timepicker>' ) ( $rootScope ) ;
618
635
$rootScope . $digest ( ) ;
619
636
} ) ) ;
620
637
afterEach ( inject ( function ( timepickerConfig ) {
@@ -637,10 +654,9 @@ describe('timepicker directive', function () {
637
654
} ) ;
638
655
639
656
describe ( 'user input validation' , function ( ) {
640
-
641
657
var changeInputValueTo ;
642
658
643
- beforeEach ( inject ( function ( _$compile_ , _$rootScope_ , $sniffer ) {
659
+ beforeEach ( inject ( function ( $sniffer ) {
644
660
changeInputValueTo = function ( inputEl , value ) {
645
661
inputEl . val ( value ) ;
646
662
inputEl . trigger ( $sniffer . hasEvent ( 'input' ) ? 'input' : 'change' ) ;
@@ -661,7 +677,7 @@ describe('timepicker directive', function () {
661
677
expect ( getModelState ( ) ) . toEqual ( [ 14 , 40 ] ) ;
662
678
} ) ;
663
679
664
- it ( 'updates hours & pads on input blur' , function ( ) {
680
+ it ( 'updates hours & pads on input change & pads on blur' , function ( ) {
665
681
var el = getHoursInputEl ( ) ;
666
682
667
683
changeInputValueTo ( el , 5 ) ;
@@ -673,7 +689,7 @@ describe('timepicker directive', function () {
673
689
expect ( getModelState ( ) ) . toEqual ( [ 17 , 40 ] ) ;
674
690
} ) ;
675
691
676
- it ( 'updates minutes & pads on input blur' , function ( ) {
692
+ it ( 'updates minutes & pads on input change & pads on blur' , function ( ) {
677
693
var el = getMinutesInputEl ( ) ;
678
694
679
695
changeInputValueTo ( el , 9 ) ;
@@ -691,13 +707,15 @@ describe('timepicker directive', function () {
691
707
changeInputValueTo ( el , 'pizza' ) ;
692
708
expect ( $rootScope . time ) . toBe ( null ) ;
693
709
expect ( el . parent ( ) . hasClass ( 'error' ) ) . toBe ( true ) ;
710
+ expect ( element . hasClass ( 'ng-invalid-time' ) ) . toBe ( true ) ;
694
711
695
712
changeInputValueTo ( el , 8 ) ;
696
713
el . blur ( ) ;
697
714
$rootScope . $digest ( ) ;
698
715
expect ( getTimeState ( ) ) . toEqual ( [ '08' , '40' , 'PM' ] ) ;
699
716
expect ( getModelState ( ) ) . toEqual ( [ 20 , 40 ] ) ;
700
717
expect ( el . parent ( ) . hasClass ( 'error' ) ) . toBe ( false ) ;
718
+ expect ( element . hasClass ( 'ng-invalid-time' ) ) . toBe ( false ) ;
701
719
} ) ;
702
720
703
721
it ( 'clears model when input minutes is invalid & alerts the UI' , function ( ) {
@@ -706,28 +724,130 @@ describe('timepicker directive', function () {
706
724
changeInputValueTo ( el , 'pizza' ) ;
707
725
expect ( $rootScope . time ) . toBe ( null ) ;
708
726
expect ( el . parent ( ) . hasClass ( 'error' ) ) . toBe ( true ) ;
727
+ expect ( element . hasClass ( 'ng-invalid-time' ) ) . toBe ( true ) ;
709
728
710
729
changeInputValueTo ( el , 22 ) ;
711
730
expect ( getTimeState ( ) ) . toEqual ( [ '02' , '22' , 'PM' ] ) ;
712
731
expect ( getModelState ( ) ) . toEqual ( [ 14 , 22 ] ) ;
713
732
expect ( el . parent ( ) . hasClass ( 'error' ) ) . toBe ( false ) ;
733
+ expect ( element . hasClass ( 'ng-invalid-time' ) ) . toBe ( false ) ;
714
734
} ) ;
715
735
716
736
it ( 'handles 12/24H mode change' , function ( ) {
717
737
$rootScope . meridian = true ;
718
- element = $compile ( '<timepicker ng-model="time" show-meridian="meridian"></timepicker>' ) ( $rootScope ) ;
738
+ element = $compile ( '<timepicker ng-model="$parent. time" show-meridian="meridian"></timepicker>' ) ( $rootScope ) ;
719
739
$rootScope . $digest ( ) ;
720
740
721
741
var el = getHoursInputEl ( ) ;
722
742
723
743
changeInputValueTo ( el , '16' ) ;
724
744
expect ( $rootScope . time ) . toBe ( null ) ;
725
745
expect ( el . parent ( ) . hasClass ( 'error' ) ) . toBe ( true ) ;
746
+ expect ( element . hasClass ( 'ng-invalid-time' ) ) . toBe ( true ) ;
726
747
727
748
$rootScope . meridian = false ;
728
749
$rootScope . $digest ( ) ;
729
750
expect ( getTimeState ( true ) ) . toEqual ( [ '16' , '40' ] ) ;
730
751
expect ( getModelState ( ) ) . toEqual ( [ 16 , 40 ] ) ;
752
+ expect ( element . hasClass ( 'ng-invalid-time' ) ) . toBe ( false ) ;
753
+ } ) ;
754
+ } ) ;
755
+
756
+ describe ( 'when model is not a Date' , function ( ) {
757
+ beforeEach ( inject ( function ( ) {
758
+ eelement = $compile ( '<timepicker ng-model="$parent.time"></timepicker>' ) ( $rootScope ) ;
759
+ } ) ) ;
760
+
761
+ it ( 'should not be invalid when the model is null' , function ( ) {
762
+ $rootScope . time = null ;
763
+ $rootScope . $digest ( ) ;
764
+ expect ( element . hasClass ( 'ng-invalid-time' ) ) . toBe ( false ) ;
765
+ } ) ;
766
+
767
+ it ( 'should not be invalid when the model is undefined' , function ( ) {
768
+ $rootScope . time = undefined ;
769
+ $rootScope . $digest ( ) ;
770
+ expect ( element . hasClass ( 'ng-invalid-time' ) ) . toBe ( false ) ;
771
+ } ) ;
772
+
773
+ it ( 'should not be invalid when the model is a valid string date representation' , function ( ) {
774
+ $rootScope . time = 'September 30, 2010 15:30:00' ;
775
+ $rootScope . $digest ( ) ;
776
+ expect ( element . hasClass ( 'ng-invalid-time' ) ) . toBe ( false ) ;
777
+ expect ( getTimeState ( ) ) . toEqual ( [ '03' , '30' , 'PM' ] ) ;
778
+ } ) ;
779
+
780
+ it ( 'should be invalid when the model is not a valid string date representation' , function ( ) {
781
+ $rootScope . time = 'pizza' ;
782
+ $rootScope . $digest ( ) ;
783
+ expect ( element . hasClass ( 'ng-invalid-time' ) ) . toBe ( true ) ;
784
+ } ) ;
785
+
786
+ it ( 'should return valid when the model becomes valid' , function ( ) {
787
+ $rootScope . time = 'pizza' ;
788
+ $rootScope . $digest ( ) ;
789
+ expect ( element . hasClass ( 'ng-invalid-time' ) ) . toBe ( true ) ;
790
+
791
+ $rootScope . time = new Date ( ) ;
792
+ $rootScope . $digest ( ) ;
793
+ expect ( element . hasClass ( 'ng-invalid-time' ) ) . toBe ( false ) ;
794
+ } ) ;
795
+
796
+ it ( 'should return valid when the model is cleared' , function ( ) {
797
+ $rootScope . time = 'pizza' ;
798
+ $rootScope . $digest ( ) ;
799
+ expect ( element . hasClass ( 'ng-invalid-time' ) ) . toBe ( true ) ;
800
+
801
+ $rootScope . time = null ;
802
+ $rootScope . $digest ( ) ;
803
+ expect ( element . hasClass ( 'ng-invalid-time' ) ) . toBe ( false ) ;
804
+ } ) ;
805
+ } ) ;
806
+
807
+ describe ( 'use with `ng-required` directive' , function ( ) {
808
+ beforeEach ( inject ( function ( ) {
809
+ $rootScope . time = null ;
810
+ element = $compile ( '<timepicker ng-model="$parent.time" ng-required="true"></timepicker>' ) ( $rootScope ) ;
811
+ $rootScope . $digest ( ) ;
812
+ } ) ) ;
813
+
814
+ it ( 'should be invalid initially' , function ( ) {
815
+ expect ( element . hasClass ( 'ng-invalid' ) ) . toBe ( true ) ;
816
+ } ) ;
817
+
818
+ it ( 'should be valid if model has been specified' , function ( ) {
819
+ $rootScope . time = new Date ( ) ;
820
+ $rootScope . $digest ( ) ;
821
+ expect ( element . hasClass ( 'ng-invalid' ) ) . toBe ( false ) ;
822
+ } ) ;
823
+ } ) ;
824
+
825
+ describe ( 'use with `ng-change` directive' , function ( ) {
826
+ beforeEach ( inject ( function ( ) {
827
+ $rootScope . changeHandler = jasmine . createSpy ( 'changeHandler' ) ;
828
+ $rootScope . time = new Date ( ) ;
829
+ element = $compile ( '<timepicker ng-model="$parent.time" ng-change="$parent.changeHandler()"></timepicker>' ) ( $rootScope ) ;
830
+ $rootScope . $digest ( ) ;
831
+ } ) ) ;
832
+
833
+ it ( 'should not be called initially' , function ( ) {
834
+ expect ( $rootScope . changeHandler ) . not . toHaveBeenCalled ( ) ;
835
+ } ) ;
836
+
837
+ it ( 'should be called when hours / minutes buttons clicked' , function ( ) {
838
+ var btn1 = getHoursButton ( true ) ;
839
+ var btn2 = getMinutesButton ( false ) ;
840
+
841
+ doClick ( btn1 , 2 ) ;
842
+ doClick ( btn2 , 3 ) ;
843
+ $rootScope . $digest ( ) ;
844
+ expect ( $rootScope . changeHandler . callCount ) . toBe ( 5 ) ;
845
+ } ) ;
846
+
847
+ it ( 'should not be called when model changes programatically' , function ( ) {
848
+ $rootScope . time = new Date ( ) ;
849
+ $rootScope . $digest ( ) ;
850
+ expect ( $rootScope . changeHandler ) . not . toHaveBeenCalled ( ) ;
731
851
} ) ;
732
852
} ) ;
733
853
0 commit comments