| 
									
										
										
										
											2016-06-23 09:47:54 -07:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @license | 
					
						
							|  |  |  |  * Copyright Google Inc. All Rights Reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Use of this source code is governed by an MIT-style license that can be | 
					
						
							|  |  |  |  * found in the LICENSE file at https://angular.io/license
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-27 17:12:25 -07:00
										 |  |  | import {AnimationMetadata, animate, group, keyframes, sequence, style, transition, trigger} from '@angular/core'; | 
					
						
							|  |  |  | import {beforeEach, describe, inject, it} from '@angular/core/testing/testing_internal'; | 
					
						
							| 
									
										
										
										
											2016-07-22 09:20:51 -07:00
										 |  |  | import {expect} from '@angular/platform-browser/testing/matchers'; | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-27 17:12:25 -07:00
										 |  |  | import {AnimationEntryAst, AnimationGroupAst, AnimationKeyframeAst, AnimationSequenceAst, AnimationStepAst, AnimationStylesAst} from '../../src/animation/animation_ast'; | 
					
						
							| 
									
										
										
										
											2016-09-23 16:37:04 -04:00
										 |  |  | import {AnimationParser} from '../../src/animation/animation_parser'; | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  | import {CompileMetadataResolver} from '../../src/metadata_resolver'; | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  | import {ElementSchemaRegistry} from '../../src/schema/element_schema_registry'; | 
					
						
							| 
									
										
										
										
											2016-08-30 18:07:40 -07:00
										 |  |  | import {FILL_STYLE_FLAG, flattenStyles} from '../private_import_core'; | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | export function main() { | 
					
						
							|  |  |  |   describe('parseAnimationEntry', () => { | 
					
						
							|  |  |  |     var combineStyles = (styles: AnimationStylesAst): {[key: string]: string | number} => { | 
					
						
							|  |  |  |       var flatStyles: {[key: string]: string | number} = {}; | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |       styles.styles.forEach( | 
					
						
							| 
									
										
										
										
											2016-10-03 16:46:05 -07:00
										 |  |  |           entry => Object.keys(entry).forEach(prop => { flatStyles[prop] = entry[prop]; })); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  |       return flatStyles; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-04 15:57:37 -07:00
										 |  |  |     var collectKeyframeStyles = | 
					
						
							|  |  |  |         (keyframe: AnimationKeyframeAst): {[key: string]: string | number} => | 
					
						
							|  |  |  |             combineStyles(keyframe.styles); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-07 17:36:08 -07:00
										 |  |  |     var collectStepStyles = (step: AnimationStepAst): {[key: string]: string | number}[] => { | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  |       var keyframes = step.keyframes; | 
					
						
							| 
									
										
										
										
											2016-10-07 17:36:08 -07:00
										 |  |  |       var styles: {[key: string]: string | number}[] = []; | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  |       if (step.startingStyles.styles.length > 0) { | 
					
						
							|  |  |  |         styles.push(combineStyles(step.startingStyles)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       keyframes.forEach(keyframe => styles.push(collectKeyframeStyles(keyframe))); | 
					
						
							|  |  |  |       return styles; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-07 17:36:08 -07:00
										 |  |  |     var resolver: CompileMetadataResolver; | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |     var schema: ElementSchemaRegistry; | 
					
						
							|  |  |  |     beforeEach(inject( | 
					
						
							|  |  |  |         [CompileMetadataResolver, ElementSchemaRegistry], | 
					
						
							|  |  |  |         (res: CompileMetadataResolver, sch: ElementSchemaRegistry) => { | 
					
						
							|  |  |  |           resolver = res; | 
					
						
							|  |  |  |           schema = sch; | 
					
						
							|  |  |  |         })); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     var parseAnimation = (data: AnimationMetadata[]) => { | 
					
						
							| 
									
										
										
										
											2016-09-23 16:37:04 -04:00
										 |  |  |       const entry = trigger('myAnimation', [transition('state1 => state2', sequence(data))]); | 
					
						
							|  |  |  |       const compiledAnimationEntry = resolver.getAnimationEntryMetadata(entry); | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |       const parser = new AnimationParser(schema); | 
					
						
							| 
									
										
										
										
											2016-09-23 16:37:04 -04:00
										 |  |  |       return parser.parseEntry(compiledAnimationEntry); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |     var getAnimationAstFromEntryAst = | 
					
						
							| 
									
										
										
										
											2016-07-21 17:12:00 -07:00
										 |  |  |         (ast: AnimationEntryAst) => { return ast.stateTransitions[0].animation; }; | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-04 15:57:37 -07:00
										 |  |  |     var parseAnimationAst = (data: AnimationMetadata[]) => | 
					
						
							|  |  |  |         getAnimationAstFromEntryAst(parseAnimation(data).ast); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     var parseAnimationAndGetErrors = (data: AnimationMetadata[]) => parseAnimation(data).errors; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should merge repeated style steps into a single style ast step entry', () => { | 
					
						
							|  |  |  |       var ast = parseAnimationAst([ | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |         style({'color': 'black'}), style({'background': 'red'}), style({'opacity': '0'}), | 
					
						
							|  |  |  |         animate(1000, style({'color': 'white', 'background': 'black', 'opacity': '1'})) | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  |       ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(ast.steps.length).toEqual(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var step = <AnimationStepAst>ast.steps[0]; | 
					
						
							|  |  |  |       expect(step.startingStyles.styles[0]) | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |           .toEqual({'color': 'black', 'background': 'red', 'opacity': '0'}); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       expect(step.keyframes[0].styles.styles[0]) | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |           .toEqual({'color': 'black', 'background': 'red', 'opacity': '0'}); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       expect(step.keyframes[1].styles.styles[0]) | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |           .toEqual({'color': 'white', 'background': 'black', 'opacity': '1'}); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should animate only the styles requested within an animation step', () => { | 
					
						
							|  |  |  |       var ast = parseAnimationAst([ | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |         style({'color': 'black', 'background': 'blue'}), | 
					
						
							|  |  |  |         animate(1000, style({'background': 'orange'})) | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  |       ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(ast.steps.length).toEqual(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var animateStep = <AnimationStepAst>ast.steps[0]; | 
					
						
							|  |  |  |       var fromKeyframe = animateStep.keyframes[0].styles.styles[0]; | 
					
						
							|  |  |  |       var toKeyframe = animateStep.keyframes[1].styles.styles[0]; | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |       expect(fromKeyframe).toEqual({'background': 'blue'}); | 
					
						
							|  |  |  |       expect(toKeyframe).toEqual({'background': 'orange'}); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should populate the starting and duration times propertly', () => { | 
					
						
							|  |  |  |       var ast = parseAnimationAst([ | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |         style({'color': 'black', 'opacity': '1'}), | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |         animate(1000, style({'color': 'red'})), | 
					
						
							|  |  |  |         animate(4000, style({'color': 'yellow'})), | 
					
						
							|  |  |  |         sequence( | 
					
						
							|  |  |  |             [animate(1000, style({'color': 'blue'})), animate(1000, style({'color': 'grey'}))]), | 
					
						
							|  |  |  |         group([animate(500, style({'color': 'pink'})), animate(1000, style({'opacity': '0.5'}))]), | 
					
						
							|  |  |  |         animate(300, style({'color': 'black'})), | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  |       ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(ast.steps.length).toEqual(5); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var step1 = <AnimationStepAst>ast.steps[0]; | 
					
						
							|  |  |  |       expect(step1.playTime).toEqual(1000); | 
					
						
							|  |  |  |       expect(step1.startTime).toEqual(0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var step2 = <AnimationStepAst>ast.steps[1]; | 
					
						
							|  |  |  |       expect(step2.playTime).toEqual(4000); | 
					
						
							|  |  |  |       expect(step2.startTime).toEqual(1000); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var seq = <AnimationSequenceAst>ast.steps[2]; | 
					
						
							|  |  |  |       expect(seq.playTime).toEqual(2000); | 
					
						
							|  |  |  |       expect(seq.startTime).toEqual(5000); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var step4 = <AnimationStepAst>seq.steps[0]; | 
					
						
							|  |  |  |       expect(step4.playTime).toEqual(1000); | 
					
						
							|  |  |  |       expect(step4.startTime).toEqual(5000); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var step5 = <AnimationStepAst>seq.steps[1]; | 
					
						
							|  |  |  |       expect(step5.playTime).toEqual(1000); | 
					
						
							|  |  |  |       expect(step5.startTime).toEqual(6000); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var grp = <AnimationGroupAst>ast.steps[3]; | 
					
						
							|  |  |  |       expect(grp.playTime).toEqual(1000); | 
					
						
							|  |  |  |       expect(grp.startTime).toEqual(7000); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var step6 = <AnimationStepAst>grp.steps[0]; | 
					
						
							|  |  |  |       expect(step6.playTime).toEqual(500); | 
					
						
							|  |  |  |       expect(step6.startTime).toEqual(7000); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var step7 = <AnimationStepAst>grp.steps[1]; | 
					
						
							|  |  |  |       expect(step7.playTime).toEqual(1000); | 
					
						
							|  |  |  |       expect(step7.startTime).toEqual(7000); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var step8 = <AnimationStepAst>ast.steps[4]; | 
					
						
							|  |  |  |       expect(step8.playTime).toEqual(300); | 
					
						
							|  |  |  |       expect(step8.startTime).toEqual(8000); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should apply the correct animate() styles when parallel animations are active and use the same properties', | 
					
						
							|  |  |  |        () => { | 
					
						
							|  |  |  |          var details = parseAnimation([ | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |            style({'opacity': '0', 'color': 'red'}), group([ | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  |              sequence([ | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |                animate(2000, style({'color': 'black'})), | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |                animate(2000, style({'opacity': '0.5'})), | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  |              ]), | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |              sequence([ | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |                animate(2000, style({'opacity': '0.8'})), | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |                animate(2000, style({'color': 'blue'})) | 
					
						
							|  |  |  |              ]) | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  |            ]) | 
					
						
							|  |  |  |          ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          var errors = details.errors; | 
					
						
							|  |  |  |          expect(errors.length).toEqual(0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          var ast = <AnimationSequenceAst>getAnimationAstFromEntryAst(details.ast); | 
					
						
							|  |  |  |          var g1 = <AnimationGroupAst>ast.steps[1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          var sq1 = <AnimationSequenceAst>g1.steps[0]; | 
					
						
							|  |  |  |          var sq2 = <AnimationSequenceAst>g1.steps[1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          var sq1a1 = <AnimationStepAst>sq1.steps[0]; | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |          expect(collectStepStyles(sq1a1)).toEqual([{'color': 'red'}, {'color': 'black'}]); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |          var sq1a2 = <AnimationStepAst>sq1.steps[1]; | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |          expect(collectStepStyles(sq1a2)).toEqual([{'opacity': '0.8'}, {'opacity': '0.5'}]); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |          var sq2a1 = <AnimationStepAst>sq2.steps[0]; | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |          expect(collectStepStyles(sq2a1)).toEqual([{'opacity': '0'}, {'opacity': '0.8'}]); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |          var sq2a2 = <AnimationStepAst>sq2.steps[1]; | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |          expect(collectStepStyles(sq2a2)).toEqual([{'color': 'black'}, {'color': 'blue'}]); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  |        }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should throw errors when animations animate a CSS property at the same time', () => { | 
					
						
							|  |  |  |       var animation1 = parseAnimation([ | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |         style({'opacity': '0'}), | 
					
						
							|  |  |  |         group([animate(1000, style({'opacity': '1'})), animate(2000, style({'opacity': '0.5'}))]) | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  |       ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var errors1 = animation1.errors; | 
					
						
							|  |  |  |       expect(errors1.length).toEqual(1); | 
					
						
							|  |  |  |       expect(errors1[0].msg) | 
					
						
							|  |  |  |           .toContainError( | 
					
						
							|  |  |  |               'The animated CSS property "opacity" unexpectedly changes between steps "0ms" and "2000ms" at "1000ms"'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var animation2 = parseAnimation([ | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |         style({'color': 'red'}), | 
					
						
							|  |  |  |         group( | 
					
						
							|  |  |  |             [animate(5000, style({'color': 'blue'})), animate(2500, style({'color': 'black'}))]) | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  |       ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       var errors2 = animation2.errors; | 
					
						
							|  |  |  |       expect(errors2.length).toEqual(1); | 
					
						
							|  |  |  |       expect(errors2[0].msg) | 
					
						
							|  |  |  |           .toContainError( | 
					
						
							|  |  |  |               'The animated CSS property "color" unexpectedly changes between steps "0ms" and "5000ms" at "2500ms"'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should return an error when an animation style contains an invalid timing value', () => { | 
					
						
							|  |  |  |       var errors = parseAnimationAndGetErrors( | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |           [style({'opacity': '0'}), animate('one second', style({'opacity': '1'}))]); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  |       expect(errors[0].msg).toContainError(`The provided timing value "one second" is invalid.`); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should collect and return any errors collected when parsing the metadata', () => { | 
					
						
							|  |  |  |       var errors = parseAnimationAndGetErrors([ | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |         style({'opacity': '0'}), animate('one second', style({'opacity': '1'})), | 
					
						
							|  |  |  |         style({'opacity': '0'}), animate('one second', null), style({'background': 'red'}) | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  |       ]); | 
					
						
							|  |  |  |       expect(errors.length).toBeGreaterThan(1); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should normalize a series of keyframe styles into a list of offset steps', () => { | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |       var ast = | 
					
						
							|  |  |  |           parseAnimationAst([animate(1000, keyframes([ | 
					
						
							|  |  |  |                                        style({'width': '0'}), style({'width': '25px'}), | 
					
						
							|  |  |  |                                        style({'width': '50px'}), style({'width': '75px'}) | 
					
						
							|  |  |  |                                      ]))]); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       var step = <AnimationStepAst>ast.steps[0]; | 
					
						
							|  |  |  |       expect(step.keyframes.length).toEqual(4); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(step.keyframes[0].offset).toEqual(0); | 
					
						
							| 
									
										
										
										
											2016-06-22 14:53:02 -07:00
										 |  |  |       expect(step.keyframes[1].offset).toMatch(/^0\.33/); | 
					
						
							|  |  |  |       expect(step.keyframes[2].offset).toMatch(/^0\.66/); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  |       expect(step.keyframes[3].offset).toEqual(1); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should use an existing collection of offset steps if provided', () => { | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |       var ast = parseAnimationAst([animate( | 
					
						
							|  |  |  |           1000, keyframes([ | 
					
						
							|  |  |  |             style({'height': '0', 'offset': 0}), style({'height': '25px', 'offset': 0.6}), | 
					
						
							|  |  |  |             style({'height': '50px', 'offset': 0.7}), style({'height': '75px', 'offset': 1}) | 
					
						
							|  |  |  |           ]))]); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       var step = <AnimationStepAst>ast.steps[0]; | 
					
						
							|  |  |  |       expect(step.keyframes.length).toEqual(4); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(step.keyframes[0].offset).toEqual(0); | 
					
						
							|  |  |  |       expect(step.keyframes[1].offset).toEqual(0.6); | 
					
						
							|  |  |  |       expect(step.keyframes[2].offset).toEqual(0.7); | 
					
						
							|  |  |  |       expect(step.keyframes[3].offset).toEqual(1); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should sort the provided collection of steps that contain offsets', () => { | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |       var ast = parseAnimationAst([animate( | 
					
						
							|  |  |  |           1000, keyframes([ | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |             style({'opacity': '0', 'offset': 0.9}), style({'opacity': '0.25', 'offset': 0}), | 
					
						
							|  |  |  |             style({'opacity': '0.50', 'offset': 1}), | 
					
						
							|  |  |  |             style({'opacity': '0.75', 'offset': 0.91}) | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |           ]))]); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       var step = <AnimationStepAst>ast.steps[0]; | 
					
						
							|  |  |  |       expect(step.keyframes.length).toEqual(4); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(step.keyframes[0].offset).toEqual(0); | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |       expect(step.keyframes[0].styles.styles[0]['opacity']).toEqual('0.25'); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       expect(step.keyframes[1].offset).toEqual(0.9); | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |       expect(step.keyframes[1].styles.styles[0]['opacity']).toEqual('0'); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       expect(step.keyframes[2].offset).toEqual(0.91); | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |       expect(step.keyframes[2].styles.styles[0]['opacity']).toEqual('0.75'); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       expect(step.keyframes[3].offset).toEqual(1); | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |       expect(step.keyframes[3].styles.styles[0]['opacity']).toEqual('0.50'); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should throw an error if a partial amount of keyframes contain an offset', () => { | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |       var errors = parseAnimationAndGetErrors( | 
					
						
							|  |  |  |           [animate(1000, keyframes([ | 
					
						
							|  |  |  |                      style({'z-index': 0, 'offset': 0}), style({'z-index': 1}), | 
					
						
							|  |  |  |                      style({'z-index': 2, 'offset': 1}) | 
					
						
							|  |  |  |                    ]))]); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       expect(errors.length).toEqual(1); | 
					
						
							|  |  |  |       var error = errors[0]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-22 14:53:02 -07:00
										 |  |  |       expect(error.msg).toMatch(/Not all style\(\) entries contain an offset/); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |     it('should use an existing style used earlier in the animation sequence if not defined in the first keyframe', | 
					
						
							|  |  |  |        () => { | 
					
						
							|  |  |  |          var ast = parseAnimationAst([animate( | 
					
						
							|  |  |  |              1000, | 
					
						
							|  |  |  |              keyframes( | 
					
						
							|  |  |  |                  [style({'color': 'red'}), style({'background': 'blue', 'color': 'white'})]))]); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |          var keyframesStep = <AnimationStepAst>ast.steps[0]; | 
					
						
							|  |  |  |          var kf1 = keyframesStep.keyframes[0]; | 
					
						
							|  |  |  |          var kf2 = keyframesStep.keyframes[1]; | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |          expect(flattenStyles(kf1.styles.styles)) | 
					
						
							|  |  |  |              .toEqual({'color': 'red', 'background': FILL_STYLE_FLAG}); | 
					
						
							|  |  |  |        }); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     it('should copy over any missing styles to the final keyframe if not already defined', () => { | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |       var ast = parseAnimationAst([animate( | 
					
						
							|  |  |  |           1000, keyframes([ | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |             style({'color': 'white', 'borderColor': 'white'}), | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |             style({'color': 'red', 'background': 'blue'}), style({'background': 'blue'}) | 
					
						
							|  |  |  |           ]))]); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       var keyframesStep = <AnimationStepAst>ast.steps[0]; | 
					
						
							|  |  |  |       var kf1 = keyframesStep.keyframes[0]; | 
					
						
							|  |  |  |       var kf2 = keyframesStep.keyframes[1]; | 
					
						
							|  |  |  |       var kf3 = keyframesStep.keyframes[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |       expect(flattenStyles(kf3.styles.styles)) | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |           .toEqual({'background': 'blue', 'color': 'red', 'borderColor': 'white'}); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |     it('should create an initial keyframe if not detected and place all keyframes styles there', | 
					
						
							|  |  |  |        () => { | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |          var ast = parseAnimationAst([animate( | 
					
						
							|  |  |  |              1000, keyframes([ | 
					
						
							|  |  |  |                style({'color': 'white', 'background': 'black', 'offset': 0.5}), | 
					
						
							|  |  |  |                style( | 
					
						
							|  |  |  |                    {'color': 'orange', 'background': 'red', 'fontSize': '100px', 'offset': 1}) | 
					
						
							|  |  |  |              ]))]); | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |          var keyframesStep = <AnimationStepAst>ast.steps[0]; | 
					
						
							|  |  |  |          expect(keyframesStep.keyframes.length).toEqual(3); | 
					
						
							|  |  |  |          var kf1 = keyframesStep.keyframes[0]; | 
					
						
							|  |  |  |          var kf2 = keyframesStep.keyframes[1]; | 
					
						
							|  |  |  |          var kf3 = keyframesStep.keyframes[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          expect(kf1.offset).toEqual(0); | 
					
						
							|  |  |  |          expect(flattenStyles(kf1.styles.styles)).toEqual({ | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |            'fontSize': FILL_STYLE_FLAG, | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |            'background': FILL_STYLE_FLAG, | 
					
						
							|  |  |  |            'color': FILL_STYLE_FLAG | 
					
						
							|  |  |  |          }); | 
					
						
							|  |  |  |        }); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |     it('should create an destination keyframe if not detected and place all keyframes styles there', | 
					
						
							|  |  |  |        () => { | 
					
						
							|  |  |  |          var ast = parseAnimationAst([animate(1000, keyframes([ | 
					
						
							|  |  |  |                                                 style({ | 
					
						
							|  |  |  |                                                   'color': 'white', | 
					
						
							|  |  |  |                                                   'background': 'black', | 
					
						
							|  |  |  |                                                   'transform': 'rotate(360deg)', | 
					
						
							|  |  |  |                                                   'offset': 0 | 
					
						
							|  |  |  |                                                 }), | 
					
						
							|  |  |  |                                                 style({ | 
					
						
							|  |  |  |                                                   'color': 'orange', | 
					
						
							|  |  |  |                                                   'background': 'red', | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |                                                   'fontSize': '100px', | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |                                                   'offset': 0.5 | 
					
						
							|  |  |  |                                                 }) | 
					
						
							|  |  |  |                                               ]))]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          var keyframesStep = <AnimationStepAst>ast.steps[0]; | 
					
						
							|  |  |  |          expect(keyframesStep.keyframes.length).toEqual(3); | 
					
						
							|  |  |  |          var kf1 = keyframesStep.keyframes[0]; | 
					
						
							|  |  |  |          var kf2 = keyframesStep.keyframes[1]; | 
					
						
							|  |  |  |          var kf3 = keyframesStep.keyframes[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          expect(kf3.offset).toEqual(1); | 
					
						
							|  |  |  |          expect(flattenStyles(kf3.styles.styles)).toEqual({ | 
					
						
							|  |  |  |            'color': 'orange', | 
					
						
							|  |  |  |            'background': 'red', | 
					
						
							|  |  |  |            'transform': 'rotate(360deg)', | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |            'fontSize': '100px' | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |          }); | 
					
						
							|  |  |  |        }); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     describe('easing / duration / delay', () => { | 
					
						
							|  |  |  |       it('should parse simple string-based values', () => { | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |         var ast = parseAnimationAst([animate('1s .5s ease-out', style({'opacity': '1'}))]); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         var step = <AnimationStepAst>ast.steps[0]; | 
					
						
							|  |  |  |         expect(step.duration).toEqual(1000); | 
					
						
							|  |  |  |         expect(step.delay).toEqual(500); | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |         expect(step.easing).toEqual('ease-out'); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should parse a numeric duration value', () => { | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |         var ast = parseAnimationAst([animate(666, style({'opacity': '1'}))]); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         var step = <AnimationStepAst>ast.steps[0]; | 
					
						
							|  |  |  |         expect(step.duration).toEqual(666); | 
					
						
							|  |  |  |         expect(step.delay).toEqual(0); | 
					
						
							|  |  |  |         expect(step.easing).toBeFalsy(); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should parse an easing value without a delay', () => { | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |         var ast = parseAnimationAst([animate('5s linear', style({'opacity': '1'}))]); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         var step = <AnimationStepAst>ast.steps[0]; | 
					
						
							|  |  |  |         expect(step.duration).toEqual(5000); | 
					
						
							|  |  |  |         expect(step.delay).toEqual(0); | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |         expect(step.easing).toEqual('linear'); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should parse a complex easing value', () => { | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |         var ast = | 
					
						
							| 
									
										
										
										
											2016-11-08 15:45:30 -08:00
										 |  |  |             parseAnimationAst([animate('30ms cubic-bezier(0, 0,0, .69)', style({'opacity': '1'}))]); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         var step = <AnimationStepAst>ast.steps[0]; | 
					
						
							|  |  |  |         expect(step.duration).toEqual(30); | 
					
						
							|  |  |  |         expect(step.delay).toEqual(0); | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |         expect(step.easing).toEqual('cubic-bezier(0, 0,0, .69)'); | 
					
						
							| 
									
										
										
										
											2016-05-25 12:46:22 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | } |