Adding mapbox-gl branch
This commit is contained in:
@@ -0,0 +1,375 @@
|
||||
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
goog.provide('goog.testing.stacktraceTest');
|
||||
goog.setTestOnly('goog.testing.stacktraceTest');
|
||||
|
||||
goog.require('goog.functions');
|
||||
goog.require('goog.string');
|
||||
goog.require('goog.testing.ExpectedFailures');
|
||||
goog.require('goog.testing.PropertyReplacer');
|
||||
goog.require('goog.testing.StrictMock');
|
||||
goog.require('goog.testing.asserts');
|
||||
goog.require('goog.testing.jsunit');
|
||||
goog.require('goog.testing.stacktrace');
|
||||
goog.require('goog.testing.stacktrace.Frame');
|
||||
goog.require('goog.userAgent');
|
||||
|
||||
var stubs = new goog.testing.PropertyReplacer();
|
||||
var expectedFailures;
|
||||
function setUpPage() {
|
||||
expectedFailures = new goog.testing.ExpectedFailures();
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
stubs.set(goog.testing.stacktrace, 'isClosureInspectorActive_', function() {
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
stubs.reset();
|
||||
expectedFailures.handleTearDown();
|
||||
}
|
||||
|
||||
function testParseStackFrameInV8() {
|
||||
var frameString = ' at Error (unknown source)';
|
||||
var frame = goog.testing.stacktrace.parseStackFrame_(frameString);
|
||||
var expected = new goog.testing.stacktrace.Frame('', 'Error', '', '', '');
|
||||
assertObjectEquals('exception name only', expected, frame);
|
||||
|
||||
frameString = ' at Object.assert (file:///.../asserts.js:29:10)';
|
||||
frame = goog.testing.stacktrace.parseStackFrame_(frameString);
|
||||
expected = new goog.testing.stacktrace.Frame('Object', 'assert', '', '',
|
||||
'file:///.../asserts.js:29:10');
|
||||
assertObjectEquals('context object + function name + url', expected, frame);
|
||||
|
||||
frameString = ' at Object.x.y.z (/Users/bob/file.js:564:9)';
|
||||
frame = goog.testing.stacktrace.parseStackFrame_(frameString);
|
||||
expected = new goog.testing.stacktrace.Frame('Object.x.y', 'z', '', '',
|
||||
'/Users/bob/file.js:564:9');
|
||||
assertObjectEquals('nested context object + function name + url',
|
||||
expected, frame);
|
||||
|
||||
frameString = ' at http://www.example.com/jsunit.js:117:13';
|
||||
frame = goog.testing.stacktrace.parseStackFrame_(frameString);
|
||||
expected = new goog.testing.stacktrace.Frame('', '', '', '',
|
||||
'http://www.example.com/jsunit.js:117:13');
|
||||
assertObjectEquals('url only', expected, frame);
|
||||
|
||||
frameString = ' at [object Object].exec [as execute] (file:///foo)';
|
||||
frame = goog.testing.stacktrace.parseStackFrame_(frameString);
|
||||
expected = new goog.testing.stacktrace.Frame('[object Object]', 'exec',
|
||||
'execute', '', 'file:///foo');
|
||||
assertObjectEquals('function alias', expected, frame);
|
||||
|
||||
frameString = ' at new Class (file:///foo)';
|
||||
frame = goog.testing.stacktrace.parseStackFrame_(frameString);
|
||||
expected = new goog.testing.stacktrace.Frame('', 'new Class', '', '',
|
||||
'file:///foo');
|
||||
assertObjectEquals('constructor call', expected, frame);
|
||||
|
||||
frameString = ' at new <anonymous> (file:///foo)';
|
||||
frame = goog.testing.stacktrace.parseStackFrame_(frameString);
|
||||
expected = new goog.testing.stacktrace.Frame('', 'new <anonymous>', '', '',
|
||||
'file:///foo');
|
||||
assertObjectEquals('anonymous constructor call', expected, frame);
|
||||
|
||||
frameString = ' at Array.forEach (native)';
|
||||
frame = goog.testing.stacktrace.parseStackFrame_(frameString);
|
||||
expected = new goog.testing.stacktrace.Frame('Array', 'forEach', '', '', '');
|
||||
assertObjectEquals('native function call', expected, frame);
|
||||
|
||||
frameString = ' at foo (eval at file://bar)';
|
||||
frame = goog.testing.stacktrace.parseStackFrame_(frameString);
|
||||
expected = new goog.testing.stacktrace.Frame('', 'foo', '', '',
|
||||
'eval at file://bar');
|
||||
assertObjectEquals('eval', expected, frame);
|
||||
|
||||
frameString = ' at foo.bar (closure/goog/foo.js:11:99)';
|
||||
frame = goog.testing.stacktrace.parseStackFrame_(frameString);
|
||||
expected = new goog.testing.stacktrace.Frame('foo', 'bar', '', '',
|
||||
'closure/goog/foo.js:11:99');
|
||||
assertObjectEquals('Path without schema', expected, frame);
|
||||
|
||||
// In the Chrome console, execute: console.log(eval('Error().stack')).
|
||||
frameString =
|
||||
' at eval (eval at <anonymous> (unknown source), <anonymous>:1:1)';
|
||||
frame = goog.testing.stacktrace.parseStackFrame_(frameString);
|
||||
expected = new goog.testing.stacktrace.Frame('', 'eval', '', '',
|
||||
'eval at <anonymous> (unknown source), <anonymous>:1:1');
|
||||
assertObjectEquals('nested eval', expected, frame);
|
||||
}
|
||||
|
||||
function testParseStackFrameInOpera() {
|
||||
var frameString = '@';
|
||||
var frame = goog.testing.stacktrace.parseStackFrame_(frameString);
|
||||
var expected = new goog.testing.stacktrace.Frame('', '', '', '', '');
|
||||
assertObjectEquals('empty frame', expected, frame);
|
||||
|
||||
frameString = '@javascript:console.log(Error().stack):1';
|
||||
frame = goog.testing.stacktrace.parseStackFrame_(frameString);
|
||||
expected = new goog.testing.stacktrace.Frame('', '', '', '',
|
||||
'javascript:console.log(Error().stack):1');
|
||||
assertObjectEquals('javascript path only', expected, frame);
|
||||
|
||||
frameString = '@file:///foo:42';
|
||||
frame = goog.testing.stacktrace.parseStackFrame_(frameString);
|
||||
expected = new goog.testing.stacktrace.Frame('', '', '', '',
|
||||
'file:///foo:42');
|
||||
assertObjectEquals('path only', expected, frame);
|
||||
|
||||
// (function go() { throw Error() })()
|
||||
// var c = go; c()
|
||||
frameString = 'go([arguments not available])@';
|
||||
frame = goog.testing.stacktrace.parseStackFrame_(frameString);
|
||||
expected = new goog.testing.stacktrace.Frame('', 'go', '',
|
||||
'([arguments not available])', '');
|
||||
assertObjectEquals('name and empty path', expected, frame);
|
||||
|
||||
frameString = 'go([arguments not available])@file:///foo:42';
|
||||
frame = goog.testing.stacktrace.parseStackFrame_(frameString);
|
||||
expected = new goog.testing.stacktrace.Frame('', 'go', '',
|
||||
'([arguments not available])', 'file:///foo:42');
|
||||
assertObjectEquals('name and path', expected, frame);
|
||||
|
||||
// (function() { throw Error() })()
|
||||
frameString =
|
||||
'<anonymous function>([arguments not available])@file:///foo:42';
|
||||
frame = goog.testing.stacktrace.parseStackFrame_(frameString);
|
||||
expected = new goog.testing.stacktrace.Frame('', '', '',
|
||||
'([arguments not available])', 'file:///foo:42');
|
||||
assertObjectEquals('anonymous function', expected, frame);
|
||||
|
||||
// var b = {foo: function() { throw Error() }}
|
||||
frameString = '<anonymous function: foo>()@file:///foo:42';
|
||||
frame = goog.testing.stacktrace.parseStackFrame_(frameString);
|
||||
expected = new goog.testing.stacktrace.Frame(
|
||||
'', 'foo', '', '()', 'file:///foo:42');
|
||||
assertObjectEquals('object literal function', expected, frame);
|
||||
|
||||
// var c = {}; c.foo = function() { throw Error() }
|
||||
frameString = '<anonymous function: c.foo>()@file:///foo:42';
|
||||
frame = goog.testing.stacktrace.parseStackFrame_(frameString);
|
||||
expected = new goog.testing.stacktrace.Frame(
|
||||
'c', 'foo', '', '()', 'file:///foo:42');
|
||||
assertObjectEquals('named object literal function', expected, frame);
|
||||
|
||||
frameString = '<anonymous function: Foo.prototype.bar>()@';
|
||||
frame = goog.testing.stacktrace.parseStackFrame_(frameString);
|
||||
expected = new goog.testing.stacktrace.Frame(
|
||||
'Foo.prototype', 'bar', '', '()', '');
|
||||
assertObjectEquals('prototype function', expected, frame);
|
||||
|
||||
frameString = '<anonymous function: goog.Foo.prototype.bar>()@';
|
||||
frame = goog.testing.stacktrace.parseStackFrame_(frameString);
|
||||
expected = new goog.testing.stacktrace.Frame(
|
||||
'goog.Foo.prototype', 'bar', '', '()', '');
|
||||
assertObjectEquals('namespaced prototype function', expected, frame);
|
||||
}
|
||||
|
||||
// All test strings are parsed with the conventional and long
|
||||
// frame algorithms.
|
||||
function testParseStackFrameInFirefox() {
|
||||
var frameString = 'Error("Assertion failed")@:0';
|
||||
var frame = goog.testing.stacktrace.parseStackFrame_(frameString);
|
||||
var expected = new goog.testing.stacktrace.Frame('', 'Error', '',
|
||||
'("Assertion failed")', '');
|
||||
assertObjectEquals('function name + arguments', expected, frame);
|
||||
|
||||
frame = goog.testing.stacktrace.parseLongFirefoxFrame_(frameString);
|
||||
assertObjectEquals('function name + arguments', expected, frame);
|
||||
|
||||
frameString = '()@file:///foo:42';
|
||||
frame = goog.testing.stacktrace.parseStackFrame_(frameString);
|
||||
expected = new goog.testing.stacktrace.Frame('', '', '', '()',
|
||||
'file:///foo:42');
|
||||
assertObjectEquals('anonymous function', expected, frame);
|
||||
|
||||
frame = goog.testing.stacktrace.parseLongFirefoxFrame_(frameString);
|
||||
assertObjectEquals('anonymous function', expected, frame);
|
||||
|
||||
frameString = '@javascript:alert(0)';
|
||||
frame = goog.testing.stacktrace.parseStackFrame_(frameString);
|
||||
expected = new goog.testing.stacktrace.Frame('', '', '', '',
|
||||
'javascript:alert(0)');
|
||||
assertObjectEquals('anonymous function', expected, frame);
|
||||
|
||||
frame = goog.testing.stacktrace.parseLongFirefoxFrame_(frameString);
|
||||
assertObjectEquals('anonymous function', expected, frame);
|
||||
}
|
||||
|
||||
function testCanonicalizeFrame() {
|
||||
var frame = new goog.testing.stacktrace.Frame('<window>', 'foo', 'bar',
|
||||
'("<a>\'&")', 'http://x?a=1&b=2:1');
|
||||
assertEquals('canonical stack frame, everything is escaped',
|
||||
'<window>.foo("<a>\'&amp;") ' +
|
||||
'[as bar] at http://x?a=1&b=2:1', frame.toCanonicalString());
|
||||
}
|
||||
|
||||
function testDeobfuscateFunctionName() {
|
||||
goog.testing.stacktrace.setDeobfuscateFunctionName(function(name) {
|
||||
return name.replace(/\$/g, '.');
|
||||
});
|
||||
|
||||
var frame = new goog.testing.stacktrace.Frame('', 'a$b$c', 'd$e', '', '');
|
||||
assertEquals('deobfuscated function name', 'a.b.c [as d.e]',
|
||||
frame.toCanonicalString());
|
||||
}
|
||||
|
||||
function testFramesToString() {
|
||||
var normalFrame = new goog.testing.stacktrace.Frame('', 'foo', '', '', '');
|
||||
var anonFrame = new goog.testing.stacktrace.Frame('', '', '', '', '');
|
||||
var frames = [normalFrame, anonFrame, null, anonFrame];
|
||||
var stack = goog.testing.stacktrace.framesToString_(frames);
|
||||
assertEquals('framesToString', '> foo\n> anonymous\n> (unknown)\n', stack);
|
||||
}
|
||||
|
||||
function testFollowCallChain() {
|
||||
var func = function(var_args) {
|
||||
return goog.testing.stacktrace.followCallChain_();
|
||||
};
|
||||
|
||||
// Created a fake type with a toString method.
|
||||
function LocalType() {};
|
||||
LocalType.prototype.toString = function() {
|
||||
return 'sg';
|
||||
};
|
||||
|
||||
// Create a mock with no expectations.
|
||||
var mock = new goog.testing.StrictMock(LocalType);
|
||||
|
||||
mock.$replay();
|
||||
|
||||
var frames = func(undefined, null, false, 0, '', {}, goog.nullFunction,
|
||||
mock, new LocalType);
|
||||
|
||||
// Opera before version 10 doesn't support the caller attribute. In that
|
||||
// browser followCallChain_() returns empty stack trace.
|
||||
expectedFailures.expectFailureFor(goog.userAgent.OPERA &&
|
||||
!goog.userAgent.isVersionOrHigher('10'));
|
||||
try {
|
||||
assertTrue('The stack trace consists of >=2 frames', frames.length >= 2);
|
||||
} catch (e) {
|
||||
expectedFailures.handleException(e);
|
||||
}
|
||||
|
||||
if (frames.length >= 2) {
|
||||
assertEquals('innermost function is anonymous', '', frames[0].getName());
|
||||
// There are white space differences how browsers convert functions to
|
||||
// strings.
|
||||
var expected = '(undefined,null,false,0,"",[objectObject],function(){},' +
|
||||
'goog.testing.Mock,sg)';
|
||||
assertEquals('arguments of the innermost function (ignoring whitespaces)',
|
||||
expected, frames[0].args_.replace(/\s/g, ''));
|
||||
assertEquals('test function name', 'testFollowCallChain',
|
||||
frames[1].getName());
|
||||
}
|
||||
|
||||
mock.$verify();
|
||||
}
|
||||
|
||||
// Create a stack trace string with one modest record and one long record,
|
||||
// Verify that all frames are parsed. The length of the long arg is set
|
||||
// to blow Firefox 3x's stack if put through a RegExp.
|
||||
function testParsingLongStackTrace() {
|
||||
var longArg = goog.string.buildString(
|
||||
'(', goog.string.repeat('x', 1000000), ')');
|
||||
var stackTrace = goog.string.buildString(
|
||||
'shortFrame()@:0\n',
|
||||
'longFrame',
|
||||
longArg,
|
||||
'@http://google.com/somescript:0\n');
|
||||
var frames = goog.testing.stacktrace.parse_(stackTrace);
|
||||
assertEquals('number of returned frames', 2, frames.length);
|
||||
var expected = new goog.testing.stacktrace.Frame(
|
||||
'', 'shortFrame', '', '()', '');
|
||||
assertObjectEquals('short frame', expected, frames[0]);
|
||||
|
||||
expected = new goog.testing.stacktrace.Frame(
|
||||
'', 'longFrame', '', longArg, 'http://google.com/somescript:0');
|
||||
assertObjectEquals('exception name only', expected, frames[1]);
|
||||
}
|
||||
|
||||
function testParseStackFrameInIE10() {
|
||||
var frameString = ' at foo (http://bar:4000/bar.js:150:3)';
|
||||
var frame = goog.testing.stacktrace.parseStackFrame_(frameString);
|
||||
var expected = new goog.testing.stacktrace.Frame('', 'foo', '', '',
|
||||
'http://bar:4000/bar.js:150:3');
|
||||
assertObjectEquals('name and path', expected, frame);
|
||||
|
||||
frameString = ' at Anonymous function (http://bar:4000/bar.js:150:3)';
|
||||
frame = goog.testing.stacktrace.parseStackFrame_(frameString);
|
||||
expected = new goog.testing.stacktrace.Frame('', 'Anonymous function', '', '',
|
||||
'http://bar:4000/bar.js:150:3');
|
||||
assertObjectEquals('Anonymous function', expected, frame);
|
||||
|
||||
frameString = ' at Global code (http://bar:4000/bar.js:150:3)';
|
||||
frame = goog.testing.stacktrace.parseStackFrame_(frameString);
|
||||
expected = new goog.testing.stacktrace.Frame('', 'Global code', '', '',
|
||||
'http://bar:4000/bar.js:150:3');
|
||||
assertObjectEquals('Global code', expected, frame);
|
||||
|
||||
frameString = ' at foo (eval code:150:3)';
|
||||
frame = goog.testing.stacktrace.parseStackFrame_(frameString);
|
||||
expected = new goog.testing.stacktrace.Frame('', 'foo', '', '',
|
||||
'eval code:150:3');
|
||||
assertObjectEquals('eval code', expected, frame);
|
||||
|
||||
frameString = ' at eval code (eval code:150:3)';
|
||||
frame = goog.testing.stacktrace.parseStackFrame_(frameString);
|
||||
expected = new goog.testing.stacktrace.Frame('', 'eval code', '', '',
|
||||
'eval code:150:3');
|
||||
assertObjectEquals('nested eval', expected, frame);
|
||||
}
|
||||
|
||||
// Verifies that retrieving the stack trace works when the 'stack' field of an
|
||||
// exception contains an array of CallSites instead of a string. This is the
|
||||
// case when running in a lightweight V8 runtime (for instance, in gjstests),
|
||||
// as opposed to a browser environment.
|
||||
function testGetStackFrameWithV8CallSites() {
|
||||
// A function to create V8 CallSites. Note that CallSite is an extern and thus
|
||||
// cannot be mocked with closure mocks.
|
||||
function createCallSite(functionName, fileName, lineNumber, colNumber) {
|
||||
return {
|
||||
getFunctionName: goog.functions.constant(functionName),
|
||||
getFileName: goog.functions.constant(fileName),
|
||||
getLineNumber: goog.functions.constant(lineNumber),
|
||||
getColumnNumber: goog.functions.constant(colNumber)
|
||||
};
|
||||
}
|
||||
|
||||
// Mock the goog.testing.stacktrace.getStack_ function, which normally
|
||||
// triggers an exception for the purpose of reading and returning its stack
|
||||
// trace. Here, pretend that V8 provided an array of CallSites instead of the
|
||||
// string that browsers provide.
|
||||
stubs.set(goog.testing.stacktrace, 'getNativeStack_', function() {
|
||||
return [
|
||||
createCallSite('fn1', 'file1', 1, 2),
|
||||
createCallSite('fn2', 'file2', 3, 4),
|
||||
createCallSite('fn3', 'file3', 5, 6)
|
||||
];
|
||||
});
|
||||
|
||||
// Retrieve the stacktrace. This should translate the array of CallSites into
|
||||
// a single multi-line string.
|
||||
var stackTrace = goog.testing.stacktrace.get();
|
||||
|
||||
// Make sure the stack trace was translated correctly.
|
||||
var frames = stackTrace.split('\n');
|
||||
assertEquals(frames[0], '> fn1 at file1:1:2');
|
||||
assertEquals(frames[1], '> fn2 at file2:3:4');
|
||||
assertEquals(frames[2], '> fn3 at file3:5:6');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user