@@ -66,6 +66,112 @@ describe("Utility functions", () => {
66
66
expect ( isNumeric ( "0xAF" ) ) . to . be . false ;
67
67
} ) ;
68
68
} ) ;
69
+
70
+ describe ( "tween()" , function ( ) {
71
+ const { tween, wait} = utils ;
72
+ const duration = 600 ;
73
+ this . timeout ( duration * 2 ) ;
74
+ this . slow ( duration * 4 ) ;
75
+
76
+ it ( "interpolates property values over time" , async ( ) => {
77
+ const target = { prop : 0 } ;
78
+ const tweenValue = tween ( target , "prop" , 100 , { duration} ) ;
79
+ await wait ( duration / 3 ) . then ( ( ) => expect ( target . prop ) . to . be . within ( 10 , 50 ) ) ;
80
+ await wait ( duration / 2 ) . then ( ( ) => expect ( target . prop ) . to . be . within ( 50 , 100 ) ) ;
81
+ await tweenValue . then ( ( ) => expect ( target . prop ) . to . equal ( 100 ) ) ;
82
+ } ) ;
83
+
84
+ it ( "begins tweening from the existing value" , async ( ) => {
85
+ const target = { prop : 90 } ;
86
+ const tweenValue = tween ( target , "prop" , 100 , { duration} ) ;
87
+ await wait ( duration / 3 ) . then ( ( ) => expect ( target . prop ) . to . be . within ( 90 , 100 ) ) ;
88
+ await tweenValue . then ( ( ) => expect ( target . prop ) . to . equal ( 100 ) ) ;
89
+ } ) ;
90
+
91
+ it ( "invokes callback functions for each frame" , async ( ) => {
92
+ let callCount = 0 ;
93
+ const fps = 5 ;
94
+ const target = { prop : 0 } ;
95
+ const previous = { value : - 1 , progress : - 1 } ;
96
+ const callback = ( value , progress ) => {
97
+ expect ( value ) . to . be . above ( previous . value ) ;
98
+ expect ( progress ) . to . be . above ( previous . progress ) . and . within ( 0 , 1 ) ;
99
+ previous . value = value ;
100
+ previous . progress = progress ;
101
+ ++ callCount ;
102
+ } ;
103
+ await tween ( target , "prop" , 10 , { duration, callback, fps} ) ;
104
+ expect ( callCount ) . to . be . at . least ( duration / 60 / fps ) ;
105
+ expect ( previous . progress ) . to . equal ( 1 ) ;
106
+ } ) ;
107
+
108
+ it ( "supports custom easing curves" , async ( ) => {
109
+ const target = { foo : 0 , bar : 0 } ;
110
+ const tweenA = tween ( target , "foo" , 100 , { duration, curve : [ [ 0 , 0 ] , [ 1 , 0 ] , [ 1 , 0 ] , [ 1 , 1 ] ] } ) ;
111
+ const tweenB = tween ( target , "bar" , 100 , { duration, curve : [ [ 0 , 0 ] , [ 0 , 1 ] , [ 0 , 1 ] , [ 1 , 1 ] ] } ) ;
112
+ await wait ( duration / 4 ) ;
113
+ expect ( target . foo ) . to . be . below ( 5 ) ;
114
+ expect ( target . bar ) . to . be . above ( 35 ) ;
115
+ await wait ( duration / 2 ) ;
116
+ expect ( target . foo ) . to . be . below ( 50 ) ;
117
+ expect ( target . bar ) . to . be . above ( 85 ) ;
118
+ await tweenA . then ( ( ) => expect ( target . foo ) . to . equal ( 100 ) ) ;
119
+ await tweenB . then ( ( ) => expect ( target . bar ) . to . equal ( 100 ) ) ;
120
+ } ) ;
121
+
122
+ it ( "supports early cancellation of playback" , async ( ) => {
123
+ const valuesWhenStopped = { A : 0 , B : 0 } ;
124
+ const target = { foo : 0 , bar : 0 } ;
125
+ const tweenA = tween ( target , "foo" , 10 , { duration} ) ;
126
+ const tweenB = tween ( target , "bar" , 10 , { duration} ) ;
127
+ await wait ( duration / 4 ) . then ( ( ) => expect ( target . foo ) . to . be . above ( 0 ) )
128
+ await wait ( duration / 2 ) . then ( ( ) => tweenA . stop ( ) ) ;
129
+ valuesWhenStopped . A = target . foo ;
130
+ valuesWhenStopped . B = target . bar ;
131
+ expect ( valuesWhenStopped . A ) . to . be . above ( 0 ) . and . below ( 10 ) ;
132
+ expect ( valuesWhenStopped . B ) . to . be . above ( 0 ) . and . below ( 10 ) ;
133
+ await wait ( duration / 1.5 ) ;
134
+ expect ( target . foo ) . to . equal ( valuesWhenStopped . A ) ;
135
+ expect ( target . bar ) . to . be . above ( valuesWhenStopped . B ) . and . to . equal ( 10 ) ;
136
+ } ) ;
137
+
138
+ it ( "defines presets for common easing functions" , ( ) => {
139
+ expect ( tween . LINEAR ) . to . be . an ( "array" ) ;
140
+ expect ( tween . EASE ) . to . be . an ( "array" ) ;
141
+ expect ( tween . EASE_IN ) . to . be . an ( "array" ) ;
142
+ expect ( tween . EASE_IN_OUT ) . to . be . an ( "array" ) ;
143
+ expect ( tween . EASE_OUT ) . to . be . an ( "array" ) ;
144
+ } ) ;
145
+
146
+ it ( "lets durations be specified" , async ( ) => {
147
+ const target = { foo : 0 , bar : 0 } ;
148
+ const result = [ ] ;
149
+ const tweenA = tween ( target , "foo" , 5 , { duration : 500 } ) . then ( ( ) => result . push ( "A" ) ) ;
150
+ const tweenB = tween ( target , "bar" , 5 , { duration : 250 } ) . then ( ( ) => result . push ( "B" ) ) ;
151
+ await Promise . all ( [ tweenA , tweenB ] ) ;
152
+ expect ( result ) . to . eql ( [ "B" , "A" ] ) ;
153
+ } ) ;
154
+
155
+ it ( "lets frame rates be specified" , async ( ) => {
156
+ const counts = { A : 0 , B : 0 } ;
157
+ const target = { foo : 0 , bar : 0 } ;
158
+ const tweenA = tween ( target , "foo" , 5 , { duration, fps : 50 , callback : ( ) => ++ counts . A } ) ;
159
+ const tweenB = tween ( target , "bar" , 5 , { duration, fps : 25 , callback : ( ) => ++ counts . B } ) ;
160
+ await Promise . all ( [ tweenA , tweenB ] ) ;
161
+ expect ( counts . A ) . to . be . above ( counts . B ) ;
162
+ expect ( target . foo ) . to . equal ( target . bar ) ;
163
+ } ) ;
164
+
165
+ it ( "lets interpolated values be overridden by a filter" , async ( ) => {
166
+ const target = { prop : 0 } ;
167
+ const filter = ( value , progress ) => {
168
+ expect ( progress ) . to . be . within ( 0 , 1 ) ;
169
+ return `Size: ${ value } cm × ${ value / 2 } cm` ;
170
+ } ;
171
+ await tween ( target , "prop" , 30 , { duration, filter} ) ;
172
+ expect ( target . prop ) . to . equal ( "Size: 30cm × 15cm" ) ;
173
+ } ) ;
174
+ } ) ;
69
175
} ) ;
70
176
71
177
describe ( "Regular expressions" , ( ) => {
0 commit comments