Update the license headers throughout the repository to reference Google LLC rather than Google Inc, for the required license headers. PR Close #37205
		
			
				
	
	
		
			205 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			205 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| /**
 | |
|  * @license
 | |
|  * Copyright Google LLC 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
 | |
|  */
 | |
| 
 | |
| import {isBrowser, isIE, zoneSymbol} from '../../lib/common/utils';
 | |
| import {ifEnvSupports, isSafari, isSupportSetErrorStack} from '../test-util';
 | |
| 
 | |
| const defineProperty = (Object as any)[zoneSymbol('defineProperty')] || Object.defineProperty;
 | |
| 
 | |
| describe(
 | |
|     'longStackTraceZone', ifEnvSupports(isSupportSetErrorStack, function() {
 | |
|       let log: Error[];
 | |
|       let lstz: Zone;
 | |
|       let longStackTraceZoneSpec = (Zone as any)['longStackTraceZoneSpec'];
 | |
|       let defaultTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
 | |
| 
 | |
|       beforeEach(function() {
 | |
|         lstz = Zone.current.fork(longStackTraceZoneSpec).fork({
 | |
|           name: 'long-stack-trace-zone-test',
 | |
|           onHandleError:
 | |
|               (parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, error: any):
 | |
|                   boolean => {
 | |
|                     parentZoneDelegate.handleError(targetZone, error);
 | |
|                     log.push(error);
 | |
|                     return false;
 | |
|                   }
 | |
|         });
 | |
| 
 | |
|         log = [];
 | |
|         jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
 | |
|       });
 | |
| 
 | |
|       afterEach(function() {
 | |
|         jasmine.DEFAULT_TIMEOUT_INTERVAL = defaultTimeout;
 | |
|       });
 | |
| 
 | |
|       function expectElapsed(stack: string, expectedCount: number) {
 | |
|         try {
 | |
|           let actualCount = stack.split('_Elapsed_').length;
 | |
|           if (actualCount !== expectedCount) {
 | |
|             expect(actualCount).toEqual(expectedCount);
 | |
|             console.log(stack);
 | |
|           }
 | |
|         } catch (e) {
 | |
|           expect(e).toBe(null);
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       it('should produce long stack traces', function(done) {
 | |
|         lstz.run(function() {
 | |
|           setTimeout(function() {
 | |
|             setTimeout(function() {
 | |
|               setTimeout(function() {
 | |
|                 expectElapsed(log[0].stack!, 3);
 | |
|                 done();
 | |
|               }, 0);
 | |
|               throw new Error('Hello');
 | |
|             }, 0);
 | |
|           }, 0);
 | |
|         });
 | |
|       });
 | |
| 
 | |
|       it('should produce long stack traces for optimized eventTask',
 | |
|          ifEnvSupports(() => isBrowser, function() {
 | |
|            lstz.run(function() {
 | |
|              const button = document.createElement('button');
 | |
|              const clickEvent = document.createEvent('Event');
 | |
|              clickEvent.initEvent('click', true, true);
 | |
|              document.body.appendChild(button);
 | |
| 
 | |
|              button.addEventListener('click', function() {
 | |
|                expectElapsed(log[0].stack!, 1);
 | |
|              });
 | |
| 
 | |
|              button.dispatchEvent(clickEvent);
 | |
| 
 | |
|              document.body.removeChild(button);
 | |
|            });
 | |
|          }));
 | |
| 
 | |
|       it('should not overwrite long stack traces data for different optimized eventTasks',
 | |
|          ifEnvSupports(() => isBrowser, function() {
 | |
|            lstz.run(function() {
 | |
|              const button = document.createElement('button');
 | |
|              const clickEvent = document.createEvent('Event');
 | |
|              clickEvent.initEvent('click', true, true);
 | |
|              document.body.appendChild(button);
 | |
| 
 | |
|              const div = document.createElement('div');
 | |
|              const enterEvent = document.createEvent('Event');
 | |
|              enterEvent.initEvent('mouseenter', true, true);
 | |
|              document.body.appendChild(div);
 | |
| 
 | |
|              button.addEventListener('click', function() {
 | |
|                throw new Error('clickError');
 | |
|              });
 | |
| 
 | |
|              div.addEventListener('mouseenter', function() {
 | |
|                throw new Error('enterError');
 | |
|              });
 | |
| 
 | |
|              button.dispatchEvent(clickEvent);
 | |
|              div.dispatchEvent(enterEvent);
 | |
| 
 | |
|              expect(log.length).toBe(2);
 | |
|              if (!isSafari() && !isIE()) {
 | |
|                expect(log[0].stack === log[1].stack).toBe(false);
 | |
|              }
 | |
| 
 | |
|              document.body.removeChild(button);
 | |
|              document.body.removeChild(div);
 | |
|            });
 | |
|          }));
 | |
| 
 | |
|       it('should produce a long stack trace even if stack setter throws', (done) => {
 | |
|         let wasStackAssigned = false;
 | |
|         let error = new Error('Expected error');
 | |
|         defineProperty(error, 'stack', {
 | |
|           configurable: false,
 | |
|           get: () => 'someStackTrace',
 | |
|           set: (v: any) => {
 | |
|             throw new Error('no writes');
 | |
|           }
 | |
|         });
 | |
|         lstz.run(() => {
 | |
|           setTimeout(() => {
 | |
|             throw error;
 | |
|           });
 | |
|         });
 | |
|         setTimeout(() => {
 | |
|           const e = log[0];
 | |
|           expect((e as any).longStack).toBeTruthy();
 | |
|           done();
 | |
|         });
 | |
|       });
 | |
| 
 | |
|       it('should produce long stack traces when has uncaught error in promise', function(done) {
 | |
|         lstz.runGuarded(function() {
 | |
|           setTimeout(function() {
 | |
|             setTimeout(function() {
 | |
|               let promise = new Promise(function(resolve, reject) {
 | |
|                 setTimeout(function() {
 | |
|                   reject(new Error('Hello Promise'));
 | |
|                 }, 0);
 | |
|               });
 | |
|               promise.then(function() {
 | |
|                 fail('should not get here');
 | |
|               });
 | |
|               setTimeout(function() {
 | |
|                 expectElapsed(log[0].stack!, 5);
 | |
|                 done();
 | |
|               }, 0);
 | |
|             }, 0);
 | |
|           }, 0);
 | |
|         });
 | |
|       });
 | |
| 
 | |
|       it('should produce long stack traces when handling error in promise', function(done) {
 | |
|         lstz.runGuarded(function() {
 | |
|           setTimeout(function() {
 | |
|             setTimeout(function() {
 | |
|               let promise = new Promise(function(resolve, reject) {
 | |
|                 setTimeout(function() {
 | |
|                   try {
 | |
|                     throw new Error('Hello Promise');
 | |
|                   } catch (err) {
 | |
|                     reject(err);
 | |
|                   }
 | |
|                 }, 0);
 | |
|               });
 | |
|               promise.catch(function(error) {
 | |
|                 // should be able to get long stack trace
 | |
|                 const longStackFrames: string = longStackTraceZoneSpec.getLongStackTrace(error);
 | |
|                 expectElapsed(longStackFrames, 4);
 | |
|                 done();
 | |
|               });
 | |
|             }, 0);
 | |
|           }, 0);
 | |
|         });
 | |
|       });
 | |
| 
 | |
|       it('should not produce long stack traces if Error.stackTraceLimit = 0', function(done) {
 | |
|         const originalStackTraceLimit = Error.stackTraceLimit;
 | |
|         lstz.run(function() {
 | |
|           setTimeout(function() {
 | |
|             setTimeout(function() {
 | |
|               setTimeout(function() {
 | |
|                 if (log[0].stack) {
 | |
|                   expectElapsed(log[0].stack!, 1);
 | |
|                 }
 | |
|                 Error.stackTraceLimit = originalStackTraceLimit;
 | |
|                 done();
 | |
|               }, 0);
 | |
|               Error.stackTraceLimit = 0;
 | |
|               throw new Error('Hello');
 | |
|             }, 0);
 | |
|           }, 0);
 | |
|         });
 | |
|       });
 | |
|     }));
 |