@@ -21,153 +21,191 @@ describe("animate", () => {
2121 describe ( "canvasPath" , ( ) => {
2222 describe ( "transition" , ( ) => {
2323 describe ( "keyframe" , ( ) => {
24- // TODO test for errors in the nth keyframe.
2524 it ( "should accept minimal generated keyframe" , ( ) => {
2625 const animation = canvasPath ( ) ;
2726 const keyframe = genKeyframe ( ) ;
2827
2928 expect ( ( ) => animation . transition ( keyframe ) ) . not . toThrow ( ) ;
3029 } ) ;
3130
31+ it ( "should indicate the rejected frame index" , ( ) => {
32+ const animation = canvasPath ( ) ;
33+ const keyframes = [ genKeyframe ( ) , null as any , genKeyframe ( ) ] ;
34+
35+ expect ( ( ) => animation . transition ( ...keyframes ) ) . toThrow ( / k e y f r a m e s .* 1 / g) ;
36+ } ) ;
37+
3238 interface TestCase {
33- test : string ;
39+ name : string ;
3440 edit : ( keyframe : CanvasKeyframe ) => void ;
3541 error ?: RegExp ;
3642 }
3743
3844 const testCases : Array < TestCase > = [
3945 {
40- test : "should accept valid duration" ,
46+ name : "should accept valid duration" ,
4147 edit : ( keyframe ) => ( keyframe . duration = 100 ) ,
4248 } ,
4349 {
44- test : "should accept zero duration" ,
50+ name : "should accept zero duration" ,
4551 edit : ( keyframe ) => ( keyframe . duration = 0 ) ,
4652 } ,
4753 {
48- test : "should reject undefined duration" ,
54+ name : "should reject undefined duration" ,
4955 edit : ( keyframe ) => delete keyframe . duration ,
5056 error : / d u r a t i o n .* n u m b e r .* u n d e f i n e d / g,
5157 } ,
5258 {
53- test : "should reject negative duration" ,
59+ name : "should reject negative duration" ,
5460 edit : ( keyframe ) => ( keyframe . duration = - 10 ) ,
5561 error : / d u r a t i o n .* i n v a l i d / g,
5662 } ,
5763 {
58- test : "should reject broken duration" ,
64+ name : "should reject broken duration" ,
5965 edit : ( keyframe ) => ( keyframe . duration = NaN ) ,
6066 error : / d u r a t i o n .* n u m b e r .* N a N / g,
6167 } ,
6268 {
63- test : "should reject invalid duration" ,
69+ name : "should reject invalid duration" ,
6470 edit : ( keyframe ) => ( keyframe . duration = "123" as any ) ,
6571 error : / d u r a t i o n .* n u m b e r .* s t r i n g / g,
6672 } ,
6773 {
68- test : "should accept valid delay" ,
74+ name : "should accept valid delay" ,
6975 edit : ( keyframe ) => ( keyframe . delay = 200 ) ,
7076 } ,
7177 {
72- test : "should accept zero delay" ,
78+ name : "should accept zero delay" ,
7379 edit : ( keyframe ) => ( keyframe . delay = 0 ) ,
7480 } ,
7581 {
76- test : "should accept undefined delay" ,
82+ name : "should accept undefined delay" ,
7783 edit : ( keyframe ) => delete keyframe . delay ,
7884 } ,
7985 {
80- test : "should reject negative delay" ,
86+ name : "should reject negative delay" ,
8187 edit : ( keyframe ) => ( keyframe . delay = - 10 ) ,
8288 error : / d e l a y .* i n v a l i d / g,
8389 } ,
8490 {
85- test : "should reject broken delay" ,
91+ name : "should reject broken delay" ,
8692 edit : ( keyframe ) => ( keyframe . delay = NaN ) ,
8793 error : / d e l a y .* n u m b e r .* N a N / g,
8894 } ,
8995 {
90- test : "should reject invalid delay" ,
96+ name : "should reject invalid delay" ,
9197 edit : ( keyframe ) => ( keyframe . delay = "123" as any ) ,
9298 error : / d e l a y .* n u m b e r .* s t r i n g / g,
9399 } ,
94100 {
95- test : "should accept known timingFunction" ,
101+ name : "should accept known timingFunction" ,
96102 edit : ( keyframe ) => ( keyframe . timingFunction = "ease" ) ,
97103 } ,
98104 {
99- test : "should accept undefined timingFunction" ,
105+ name : "should accept undefined timingFunction" ,
100106 edit : ( keyframe ) => delete keyframe . timingFunction ,
101107 } ,
102108 {
103- test : "should reject invalid timingFunction" ,
109+ name : "should reject invalid timingFunction" ,
104110 edit : ( keyframe ) => ( keyframe . timingFunction = ( ( ) => 0 ) as any ) ,
105111 error : / t i m i n g F u n c t i o n .* s t r i n g .* f u n c t i o n / g,
106112 } ,
107113 {
108- test : "should reject unknown timingFunction" ,
114+ name : "should reject unknown timingFunction" ,
109115 edit : ( keyframe ) => ( keyframe . timingFunction = "unknown" as any ) ,
110116 error : / t i m i n g F u n c t i o n .* n o t r e c o g n i z e d .* u n k n o w n / g,
111117 } ,
112118 {
113- test : "should accept valid callback" ,
119+ name : "should accept valid callback" ,
114120 edit : ( keyframe ) => ( keyframe . callback = ( ) => console . log ( "test" ) ) ,
115121 } ,
116122 {
117- test : "should accept undefined callback" ,
123+ name : "should accept undefined callback" ,
118124 edit : ( keyframe ) => delete keyframe . callback ,
119125 } ,
120126 {
121- test : "should reject invalid callback" ,
127+ name : "should reject invalid callback" ,
122128 edit : ( keyframe ) => ( keyframe . callback = { } as any ) ,
123129 error : / c a l l b a c k .* f u n c t i o n .* o b j e c t / g,
124130 } ,
125131 // TODO complete blobOptions type tests, should be the same as non-animated.
126132 {
127- test : "should reject undefined blobOptions" ,
133+ name : "should reject undefined blobOptions" ,
128134 edit : ( keyframe ) => delete keyframe . blobOptions ,
129135 error : / b l o b O p t i o n s .* o b j e c t .* u n d e f i n e d / g,
130136 } ,
131137 {
132- test : "should accept empty canvasOptions" ,
138+ name : "should accept empty canvasOptions" ,
133139 edit : ( keyframe ) => ( keyframe . canvasOptions = { } ) ,
134140 } ,
135141 {
136- test : "should accept undefined canvasOptions" ,
142+ name : "should accept undefined canvasOptions" ,
137143 edit : ( keyframe ) => delete keyframe . canvasOptions ,
138144 } ,
139145 {
140- test : "should accept undefined canvasOptions offsetX" ,
146+ name : "should reject invalid canvasOptions" ,
147+ edit : ( keyframe ) => keyframe . canvasOptions = null as any ,
148+ error : / c a n v a s O p t i o n s .* o b j e c t .* n u l l / g
149+ } ,
150+ {
151+ name : "should accept undefined canvasOptions offsetX" ,
141152 edit : ( keyframe ) => delete keyframe . canvasOptions ?. offsetX ,
142153 } ,
143154 {
144- test : "should reject broken canvasOptions offsetX" ,
155+ name : "should reject broken canvasOptions offsetX" ,
145156 edit : ( keyframe ) => ( keyframe . canvasOptions = { offsetX : NaN } ) ,
146157 error : / c a n v a s O p t i o n s .* o f f s e t X .* n u m b e r .* N a N / g,
147158 } ,
148159 {
149- test : "should accept undefined canvasOptions offsetY" ,
160+ name : "should accept undefined canvasOptions offsetY" ,
150161 edit : ( keyframe ) => delete keyframe . canvasOptions ?. offsetY ,
151162 } ,
152163 {
153- test : "should reject broken canvasOptions offsetY" ,
164+ name : "should reject broken canvasOptions offsetY" ,
154165 edit : ( keyframe ) => ( keyframe . canvasOptions = { offsetY : NaN } ) ,
155166 error : / c a n v a s O p t i o n s .* o f f s e t Y .* n u m b e r .* N a N / g,
156167 } ,
157168 ] ;
158169
159- for ( const testCase of testCases ) {
160- it ( testCase . test , ( ) => {
161- const animation = canvasPath ( ) ;
162- const keyframe = genKeyframe ( ) ;
163- testCase . edit ( keyframe ) ;
164- if ( testCase . error ) {
165- expect ( ( ) => animation . transition ( keyframe ) ) . toThrow ( testCase . error ) ;
166- } else {
167- expect ( ( ) => animation . transition ( keyframe ) ) . not . toThrow ( ) ;
168- }
169- } ) ;
170- }
170+ // Run all test cases with a configurable amount of keyframes
171+ // and index of the keyframe being edited for the tests.
172+ const runSuite = ( keyframeCount : number , editIndex : number ) => {
173+ for ( const testCase of testCases ) {
174+ it ( testCase . name , ( ) => {
175+ // Create blank animation.
176+ const animation = canvasPath ( ) ;
177+
178+ // Create keyframes to call transition with.
179+ const keyframes : CanvasKeyframe [ ] = [ ] ;
180+ for ( let i = 0 ; i < keyframeCount ; i ++ ) {
181+ keyframes . push ( genKeyframe ( ) ) ;
182+ }
183+
184+ // Modify selected keyframe.
185+ testCase . edit ( keyframes [ editIndex ] ) ;
186+
187+ if ( testCase . error ) {
188+ // Copy regexp because they are stateful.
189+ const pattern = new RegExp ( testCase . error ) ;
190+ expect ( ( ) => animation . transition ( ...keyframes ) ) . toThrow ( pattern ) ;
191+ } else {
192+ expect ( ( ) => animation . transition ( ...keyframes ) ) . not . toThrow ( ) ;
193+ }
194+ } ) ;
195+ }
196+ } ;
197+
198+ // Run all cases when given a single test frame and asserting on it.
199+ describe ( "first" , ( ) => runSuite ( 1 , 0 ) ) ;
200+
201+ // Run all cases when given more than one frame, asserting on last one.
202+ const lastLength = 2 + Math . floor ( 4 * Math . random ( ) ) ;
203+ describe ( "last" , ( ) => runSuite ( lastLength , lastLength - 1 ) ) ;
204+
205+ // Run all cases when given more than one frame, asserting on a random one.
206+ const nthLength = 2 + Math . floor ( 16 * Math . random ( ) ) ;
207+ const nthIndex = Math . floor ( nthLength * Math . random ( ) ) ;
208+ describe ( "nth" , ( ) => runSuite ( nthLength , nthIndex ) ) ;
171209 } ) ;
172210 } ) ;
173211 } ) ;
0 commit comments