| 
									
										
										
										
											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-04-28 17:50:03 -07:00
										 |  |  | import {getDOM} from '../src/dom/dom_adapter'; | 
					
						
							|  |  |  | import {StringMapWrapper} from '../src/facade/collection'; | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  | import {global, isString} from '../src/facade/lang'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-03 15:49:09 -08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Jasmine matchers that check Angular specific conditions. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  | export interface NgMatchers extends jasmine.Matchers { | 
					
						
							| 
									
										
										
										
											2015-12-03 15:49:09 -08:00
										 |  |  |   /** | 
					
						
							|  |  |  |    * Expect the value to be a `Promise`. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * ## Example | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * {@example testing/ts/matchers.ts region='toBePromise'} | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  |   toBePromise(): boolean; | 
					
						
							| 
									
										
										
										
											2015-12-03 15:49:09 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Expect the value to be an instance of a class. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * ## Example | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * {@example testing/ts/matchers.ts region='toBeAnInstanceOf'} | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  |   toBeAnInstanceOf(expected: any): boolean; | 
					
						
							| 
									
										
										
										
											2015-12-03 15:49:09 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Expect the element to have exactly the given text. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * ## Example | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * {@example testing/ts/matchers.ts region='toHaveText'} | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  |   toHaveText(expected: any): boolean; | 
					
						
							| 
									
										
										
										
											2015-12-03 15:49:09 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Expect the element to have the given CSS class. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * ## Example | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * {@example testing/ts/matchers.ts region='toHaveCssClass'} | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  |   toHaveCssClass(expected: any): boolean; | 
					
						
							| 
									
										
										
										
											2015-12-03 15:49:09 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Expect the element to have the given CSS styles. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * ## Example | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * {@example testing/ts/matchers.ts region='toHaveCssStyle'} | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2015-11-17 12:37:39 -08:00
										 |  |  |   toHaveCssStyle(expected: any): boolean; | 
					
						
							| 
									
										
										
										
											2015-12-03 15:49:09 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Expect a class to implement the interface of the given class. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * ## Example | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * {@example testing/ts/matchers.ts region='toImplement'} | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  |   toImplement(expected: any): boolean; | 
					
						
							| 
									
										
										
										
											2015-12-03 15:49:09 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Expect an exception to contain the given error text. | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * ## Example | 
					
						
							|  |  |  |    * | 
					
						
							|  |  |  |    * {@example testing/ts/matchers.ts region='toContainError'} | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  |   toContainError(expected: any): boolean; | 
					
						
							| 
									
										
										
										
											2015-12-03 15:49:09 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   /** | 
					
						
							|  |  |  |    * Invert the matchers. | 
					
						
							|  |  |  |    */ | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  |   not: NgMatchers; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-01 10:28:57 -08:00
										 |  |  | var _global = <any>(typeof window === 'undefined' ? global : window); | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-03 15:49:09 -08:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Jasmine matching function with Angular matchers mixed in. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ## Example | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * {@example testing/ts/matchers.ts region='toHaveText'} | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  | export var expect: (actual: any) => NgMatchers = <any>_global.expect; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Some Map polyfills don't polyfill Map.toString correctly, which
 | 
					
						
							|  |  |  | // gives us bad error messages in tests.
 | 
					
						
							|  |  |  | // The only way to do this in Jasmine is to monkey patch a method
 | 
					
						
							|  |  |  | // to the object :-(
 | 
					
						
							| 
									
										
										
										
											2016-06-08 15:45:15 -07:00
										 |  |  | (Map as any /** TODO #???? */).prototype['jasmineToString'] = function() { | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  |   var m = this; | 
					
						
							|  |  |  |   if (!m) { | 
					
						
							|  |  |  |     return '' + m; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-06-08 15:45:15 -07:00
										 |  |  |   var res: any[] /** TODO #???? */ = []; | 
					
						
							|  |  |  |   m.forEach((v: any /** TODO #???? */, k: any /** TODO #???? */) => { res.push(`${k}:${v}`); }); | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  |   return `{ ${res.join(',')} }`; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | _global.beforeEach(function() { | 
					
						
							|  |  |  |   jasmine.addMatchers({ | 
					
						
							|  |  |  |     // Custom handler for Map as Jasmine does not support it yet
 | 
					
						
							|  |  |  |     toEqual: function(util, customEqualityTesters) { | 
					
						
							|  |  |  |       return { | 
					
						
							| 
									
										
										
										
											2016-06-08 15:45:15 -07:00
										 |  |  |         compare: function(actual: any /** TODO #???? */, expected: any /** TODO #???? */) { | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  |           return {pass: util.equals(actual, expected, [compareMap])}; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 15:45:15 -07:00
										 |  |  |       function compareMap(actual: any /** TODO #???? */, expected: any /** TODO #???? */) { | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  |         if (actual instanceof Map) { | 
					
						
							|  |  |  |           var pass = actual.size === expected.size; | 
					
						
							|  |  |  |           if (pass) { | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |             actual.forEach((v: any /** TODO #???? */, k: any /** TODO #???? */) => { | 
					
						
							|  |  |  |               pass = pass && util.equals(v, expected.get(k)); | 
					
						
							|  |  |  |             }); | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  |           } | 
					
						
							|  |  |  |           return pass; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           return undefined; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     toBePromise: function() { | 
					
						
							|  |  |  |       return { | 
					
						
							| 
									
										
										
										
											2016-06-08 15:45:15 -07:00
										 |  |  |         compare: function(actual: any /** TODO #???? */, expectedClass: any /** TODO #???? */) { | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  |           var pass = typeof actual === 'object' && typeof actual.then === 'function'; | 
					
						
							|  |  |  |           return {pass: pass, get message() { return 'Expected ' + actual + ' to be a promise'; }}; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     toBeAnInstanceOf: function() { | 
					
						
							|  |  |  |       return { | 
					
						
							| 
									
										
										
										
											2016-06-08 15:45:15 -07:00
										 |  |  |         compare: function(actual: any /** TODO #???? */, expectedClass: any /** TODO #???? */) { | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  |           var pass = typeof actual === 'object' && actual instanceof expectedClass; | 
					
						
							|  |  |  |           return { | 
					
						
							|  |  |  |             pass: pass, | 
					
						
							|  |  |  |             get message() { | 
					
						
							|  |  |  |               return 'Expected ' + actual + ' to be an instance of ' + expectedClass; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     toHaveText: function() { | 
					
						
							|  |  |  |       return { | 
					
						
							| 
									
										
										
										
											2016-06-08 15:45:15 -07:00
										 |  |  |         compare: function(actual: any /** TODO #???? */, expectedText: any /** TODO #???? */) { | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  |           var actualText = elementText(actual); | 
					
						
							|  |  |  |           return { | 
					
						
							|  |  |  |             pass: actualText == expectedText, | 
					
						
							|  |  |  |             get message() { return 'Expected ' + actualText + ' to be equal to ' + expectedText; } | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     toHaveCssClass: function() { | 
					
						
							|  |  |  |       return {compare: buildError(false), negativeCompare: buildError(true)}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 15:45:15 -07:00
										 |  |  |       function buildError(isNot: any /** TODO #???? */) { | 
					
						
							|  |  |  |         return function(actual: any /** TODO #???? */, className: any /** TODO #???? */) { | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  |           return { | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  |             pass: getDOM().hasClass(actual, className) == !isNot, | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  |             get message() { | 
					
						
							|  |  |  |               return `Expected ${actual.outerHTML} ${isNot ? 'not ' : ''}to contain the CSS class "${className}"`; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-17 12:37:39 -08:00
										 |  |  |     toHaveCssStyle: function() { | 
					
						
							|  |  |  |       return { | 
					
						
							| 
									
										
										
										
											2016-06-08 15:45:15 -07:00
										 |  |  |         compare: function(actual: any /** TODO #???? */, styles: any /** TODO #???? */) { | 
					
						
							|  |  |  |           var allPassed: any /** TODO #???? */; | 
					
						
							| 
									
										
										
										
											2015-11-17 12:37:39 -08:00
										 |  |  |           if (isString(styles)) { | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  |             allPassed = getDOM().hasStyle(actual, styles); | 
					
						
							| 
									
										
										
										
											2015-11-17 12:37:39 -08:00
										 |  |  |           } else { | 
					
						
							|  |  |  |             allPassed = !StringMapWrapper.isEmpty(styles); | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |             StringMapWrapper.forEach( | 
					
						
							|  |  |  |                 styles, (style: any /** TODO #???? */, prop: any /** TODO #???? */) => { | 
					
						
							|  |  |  |                   allPassed = allPassed && getDOM().hasStyle(actual, prop, style); | 
					
						
							|  |  |  |                 }); | 
					
						
							| 
									
										
										
										
											2015-11-17 12:37:39 -08:00
										 |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           return { | 
					
						
							|  |  |  |             pass: allPassed, | 
					
						
							|  |  |  |             get message() { | 
					
						
							|  |  |  |               var expectedValueStr = isString(styles) ? styles : JSON.stringify(styles); | 
					
						
							|  |  |  |               return `Expected ${actual.outerHTML} ${!allPassed ? ' ' : 'not '}to contain the
 | 
					
						
							|  |  |  |                       CSS ${isString(styles) ? 'property' : 'styles'} "${expectedValueStr}"`;
 | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  |     toContainError: function() { | 
					
						
							|  |  |  |       return { | 
					
						
							| 
									
										
										
										
											2016-06-08 15:45:15 -07:00
										 |  |  |         compare: function(actual: any /** TODO #???? */, expectedText: any /** TODO #???? */) { | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  |           var errorMessage = actual.toString(); | 
					
						
							|  |  |  |           return { | 
					
						
							|  |  |  |             pass: errorMessage.indexOf(expectedText) > -1, | 
					
						
							|  |  |  |             get message() { return 'Expected ' + errorMessage + ' to contain ' + expectedText; } | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     }, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     toImplement: function() { | 
					
						
							|  |  |  |       return { | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |         compare: function( | 
					
						
							|  |  |  |             actualObject: any /** TODO #???? */, expectedInterface: any /** TODO #???? */) { | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  |           var objProps = Object.keys(actualObject.constructor.prototype); | 
					
						
							|  |  |  |           var intProps = Object.keys(expectedInterface.prototype); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 15:45:15 -07:00
										 |  |  |           var missedMethods: any[] /** TODO #???? */ = []; | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  |           intProps.forEach((k) => { | 
					
						
							|  |  |  |             if (!actualObject.constructor.prototype[k]) missedMethods.push(k); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           return { | 
					
						
							|  |  |  |             pass: missedMethods.length == 0, | 
					
						
							|  |  |  |             get message() { | 
					
						
							|  |  |  |               return 'Expected ' + actualObject + ' to have the following methods: ' + | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |                   missedMethods.join(', '); | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  |             } | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-08 15:45:15 -07:00
										 |  |  | function elementText(n: any /** TODO #???? */): any /** TODO #???? */ { | 
					
						
							|  |  |  |   var hasNodes = (n: any /** TODO #???? */) => { | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  |     var children = getDOM().childNodes(n); | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  |     return children && children.length > 0; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (n instanceof Array) { | 
					
						
							| 
									
										
										
										
											2016-06-08 16:38:52 -07:00
										 |  |  |     return n.map(elementText).join(''); | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  |   if (getDOM().isCommentNode(n)) { | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  |     return ''; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  |   if (getDOM().isElementNode(n) && getDOM().tagName(n) == 'CONTENT') { | 
					
						
							|  |  |  |     return elementText(Array.prototype.slice.apply(getDOM().getDistributedNodes(n))); | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  |   if (getDOM().hasShadowRoot(n)) { | 
					
						
							|  |  |  |     return elementText(getDOM().childNodesAsList(getDOM().getShadowRoot(n))); | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (hasNodes(n)) { | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  |     return elementText(getDOM().childNodesAsList(n)); | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  |   return getDOM().getText(n); | 
					
						
							| 
									
										
										
										
											2015-10-08 15:33:17 -07:00
										 |  |  | } |