angular2
Version:
Angular 2 - a web framework for modern web apps
210 lines • 28.4 kB
JavaScript
import { StringMapWrapper } from 'angular2/src/facade/collection';
import { global, isFunction, Math } from 'angular2/src/facade/lang';
import { provide } from 'angular2/src/core/di';
import { createTestInjector, FunctionWithParamTokens } from './test_injector';
import { browserDetection } from './utils';
export { inject } from './test_injector';
export { expect } from './matchers';
export var proxy = (t) => t;
var _global = (typeof window === 'undefined' ? global : window);
export var afterEach = _global.afterEach;
export class AsyncTestCompleter {
constructor(_done) {
this._done = _done;
}
done() { this._done(); }
}
var jsmBeforeEach = _global.beforeEach;
var jsmDescribe = _global.describe;
var jsmDDescribe = _global.fdescribe;
var jsmXDescribe = _global.xdescribe;
var jsmIt = _global.it;
var jsmIIt = _global.fit;
var jsmXIt = _global.xit;
var runnerStack = [];
var inIt = false;
jasmine.DEFAULT_TIMEOUT_INTERVAL = 500;
var globalTimeOut = browserDetection.isSlow ? 3000 : jasmine.DEFAULT_TIMEOUT_INTERVAL;
var testProviders;
/**
* Mechanism to run `beforeEach()` functions of Angular tests.
*
* Note: Jasmine own `beforeEach` is used by this library to handle DI providers.
*/
class BeforeEachRunner {
constructor(_parent) {
this._parent = _parent;
this._fns = [];
}
beforeEach(fn) { this._fns.push(fn); }
run(injector) {
if (this._parent)
this._parent.run(injector);
this._fns.forEach((fn) => {
return isFunction(fn) ? fn() : fn.execute(injector);
});
}
}
// Reset the test providers before each test
jsmBeforeEach(() => { testProviders = []; });
function _describe(jsmFn, ...args) {
var parentRunner = runnerStack.length === 0 ? null : runnerStack[runnerStack.length - 1];
var runner = new BeforeEachRunner(parentRunner);
runnerStack.push(runner);
var suite = jsmFn(...args);
runnerStack.pop();
return suite;
}
export function describe(...args) {
return _describe(jsmDescribe, ...args);
}
export function ddescribe(...args) {
return _describe(jsmDDescribe, ...args);
}
export function xdescribe(...args) {
return _describe(jsmXDescribe, ...args);
}
export function beforeEach(fn) {
if (runnerStack.length > 0) {
// Inside a describe block, beforeEach() uses a BeforeEachRunner
runnerStack[runnerStack.length - 1].beforeEach(fn);
}
else {
// Top level beforeEach() are delegated to jasmine
jsmBeforeEach(fn);
}
}
/**
* Allows overriding default providers defined in test_injector.js.
*
* The given function must return a list of DI providers.
*
* Example:
*
* beforeEachBindings(() => [
* provide(Compiler, {useClass: MockCompiler}),
* provide(SomeToken, {useValue: myValue}),
* ]);
*/
export function beforeEachProviders(fn) {
jsmBeforeEach(() => {
var bindings = fn();
if (!bindings)
return;
testProviders = [...testProviders, ...bindings];
});
}
/**
* @deprecated
*/
export function beforeEachBindings(fn) {
beforeEachProviders(fn);
}
function _it(jsmFn, name, testFn, testTimeOut) {
var runner = runnerStack[runnerStack.length - 1];
var timeOut = Math.max(globalTimeOut, testTimeOut);
if (testFn instanceof FunctionWithParamTokens) {
// The test case uses inject(). ie `it('test', inject([AsyncTestCompleter], (async) => { ...
// }));`
if (testFn.hasToken(AsyncTestCompleter)) {
jsmFn(name, (done) => {
var completerProvider = provide(AsyncTestCompleter, {
useFactory: () => {
// Mark the test as async when an AsyncTestCompleter is injected in an it()
if (!inIt)
throw new Error('AsyncTestCompleter can only be injected in an "it()"');
return new AsyncTestCompleter(done);
}
});
var injector = createTestInjector([...testProviders, completerProvider]);
runner.run(injector);
inIt = true;
testFn.execute(injector);
inIt = false;
}, timeOut);
}
else {
jsmFn(name, () => {
var injector = createTestInjector(testProviders);
runner.run(injector);
testFn.execute(injector);
}, timeOut);
}
}
else {
// The test case doesn't use inject(). ie `it('test', (done) => { ... }));`
if (testFn.length === 0) {
jsmFn(name, () => {
var injector = createTestInjector(testProviders);
runner.run(injector);
testFn();
}, timeOut);
}
else {
jsmFn(name, (done) => {
var injector = createTestInjector(testProviders);
runner.run(injector);
testFn(done);
}, timeOut);
}
}
}
export function it(name, fn, timeOut = null) {
return _it(jsmIt, name, fn, timeOut);
}
export function xit(name, fn, timeOut = null) {
return _it(jsmXIt, name, fn, timeOut);
}
export function iit(name, fn, timeOut = null) {
return _it(jsmIIt, name, fn, timeOut);
}
export class SpyObject {
constructor(type = null) {
if (type) {
for (var prop in type.prototype) {
var m = null;
try {
m = type.prototype[prop];
}
catch (e) {
}
if (typeof m === 'function') {
this.spy(prop);
}
}
}
}
// Noop so that SpyObject has the same interface as in Dart
noSuchMethod(args) { }
spy(name) {
if (!this[name]) {
this[name] = this._createGuinnessCompatibleSpy(name);
}
return this[name];
}
prop(name, value) { this[name] = value; }
static stub(object = null, config = null, overrides = null) {
if (!(object instanceof SpyObject)) {
overrides = config;
config = object;
object = new SpyObject();
}
var m = StringMapWrapper.merge(config, overrides);
StringMapWrapper.forEach(m, (value, key) => { object.spy(key).andReturn(value); });
return object;
}
/** @internal */
_createGuinnessCompatibleSpy(name) {
var newSpy = jasmine.createSpy(name);
newSpy.andCallFake = newSpy.and.callFake;
newSpy.andReturn = newSpy.and.returnValue;
newSpy.reset = newSpy.calls.reset;
// revisit return null here (previously needed for rtts_assert).
newSpy.and.returnValue(null);
return newSpy;
}
}
export function isInInnerZone() {
return global.zone._innerZone === true;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdGluZ19pbnRlcm5hbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImFuZ3VsYXIyL3NyYy90ZXN0aW5nL3Rlc3RpbmdfaW50ZXJuYWwudHMiXSwibmFtZXMiOlsiQXN5bmNUZXN0Q29tcGxldGVyIiwiQXN5bmNUZXN0Q29tcGxldGVyLmNvbnN0cnVjdG9yIiwiQXN5bmNUZXN0Q29tcGxldGVyLmRvbmUiLCJCZWZvcmVFYWNoUnVubmVyIiwiQmVmb3JlRWFjaFJ1bm5lci5jb25zdHJ1Y3RvciIsIkJlZm9yZUVhY2hSdW5uZXIuYmVmb3JlRWFjaCIsIkJlZm9yZUVhY2hSdW5uZXIucnVuIiwiX2Rlc2NyaWJlIiwiZGVzY3JpYmUiLCJkZGVzY3JpYmUiLCJ4ZGVzY3JpYmUiLCJiZWZvcmVFYWNoIiwiYmVmb3JlRWFjaFByb3ZpZGVycyIsImJlZm9yZUVhY2hCaW5kaW5ncyIsIl9pdCIsIml0IiwieGl0IiwiaWl0IiwiU3B5T2JqZWN0IiwiU3B5T2JqZWN0LmNvbnN0cnVjdG9yIiwiU3B5T2JqZWN0Lm5vU3VjaE1ldGhvZCIsIlNweU9iamVjdC5zcHkiLCJTcHlPYmplY3QucHJvcCIsIlNweU9iamVjdC5zdHViIiwiU3B5T2JqZWN0Ll9jcmVhdGVHdWlubmVzc0NvbXBhdGlibGVTcHkiLCJpc0luSW5uZXJab25lIl0sIm1hcHBpbmdzIjoiT0FDTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sZ0NBQWdDO09BQ3hELEVBQUMsTUFBTSxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUMsTUFBTSwwQkFBMEI7T0FHMUQsRUFBQyxPQUFPLEVBQUMsTUFBTSxzQkFBc0I7T0FFckMsRUFBQyxrQkFBa0IsRUFBRSx1QkFBdUIsRUFBUyxNQUFNLGlCQUFpQjtPQUM1RSxFQUFDLGdCQUFnQixFQUFDLE1BQU0sU0FBUztBQUV4QyxTQUFRLE1BQU0sUUFBTyxpQkFBaUIsQ0FBQztBQUV2QyxTQUFRLE1BQU0sUUFBbUIsWUFBWSxDQUFDO0FBRTlDLFdBQVcsS0FBSyxHQUFtQixD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SUFBSUEsQ0FBQ0EsR0FBR0EsZ0JBQWdCQSxDQUFDQSxLQUFLQSxDQUFDQSxNQUFNQSxFQUFFQSxTQUFTQSxDQUFDQSxDQUFDQTtRQUNsREEsZ0JBQWdCQSxDQUFDQSxPQUFPQSxDQUFDQSxDQUFDQSxFQUFFQSxDQUFDQSxLQUFLQSxFQUFFQSxHQUFHQSxPQUFPQSxNQUFNQSxDQUFDQSxHQUFHQSxDQUFDQSxHQUFHQSxDQUFDQSxDQUFDQSxTQUFTQSxDQUFDQSxLQUFLQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQSxDQUFDQTtRQUNuRkEsTUFBTUEsQ0FBQ0EsTUFBTUEsQ0FBQ0E7SUFDaEJBLENBQUNBO0lBRURMLGdCQUFnQkE7SUFDaEJBLDRCQUE0QkEsQ0FBQ0EsSUFBSUE7UUFDL0JNLElBQUlBLE1BQU1BLEdBQThCQSxPQUFPQSxDQUFDQSxTQUFTQSxDQUFDQSxJQUFJQSxDQUFDQSxDQUFDQTtRQUNoRUEsTUFBTUEsQ0FBQ0EsV0FBV0EsR0FBUUEsTUFBTUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsUUFBUUEsQ0FBQ0E7UUFDOUNBLE1BQU1BLENBQUNBLFNBQVNBLEdBQVFBLE1BQU1BLENBQUNBLEdBQUdBLENBQUNBLFdBQVdBLENBQUNBO1FBQy9DQSxNQUFNQSxDQUFDQSxLQUFLQSxHQUFRQSxNQUFNQSxDQUFDQSxLQUFLQSxDQUFDQSxLQUFLQSxDQUFDQTtRQUN2Q0EsZ0VBQWdFQTtRQUNoRUEsTUFBTUEsQ0FBQ0EsR0FBR0EsQ0FBQ0EsV0FBV0EsQ0FBQ0EsSUFBSUEsQ0FBQ0EsQ0FBQ0E7UUFDN0JBLE1BQU1BLENBQUNBLE1BQU1BLENBQUNBO0lBQ2hCQSxDQUFDQTtBQUNITixDQUFDQTtBQUVEO0lBQ0VPLE1BQU1BLENBQWNBLE1BQU1BLENBQUNBLElBQUtBLENBQUNBLFVBQVVBLEtBQUtBLElBQUlBLENBQUNBO0FBQ3ZEQSxDQUFDQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7RE9NfSBmcm9tICdhbmd1bGFyMi9zcmMvcGxhdGZvcm0vZG9tL2RvbV9hZGFwdGVyJztcbmltcG9ydCB7U3RyaW5nTWFwV3JhcHBlcn0gZnJvbSAnYW5ndWxhcjIvc3JjL2ZhY2FkZS9jb2xsZWN0aW9uJztcbmltcG9ydCB7Z2xvYmFsLCBpc0Z1bmN0aW9uLCBNYXRofSBmcm9tICdhbmd1bGFyMi9zcmMvZmFjYWRlL2xhbmcnO1xuaW1wb3J0IHtOZ1pvbmVab25lfSBmcm9tICdhbmd1bGFyMi9zcmMvY29yZS96b25lL25nX3pvbmUnO1xuXG5pbXBvcnQge3Byb3ZpZGV9IGZyb20gJ2FuZ3VsYXIyL3NyYy9jb3JlL2RpJztcblxuaW1wb3J0IHtjcmVhdGVUZXN0SW5qZWN0b3IsIEZ1bmN0aW9uV2l0aFBhcmFtVG9rZW5zLCBpbmplY3R9IGZyb20gJy4vdGVzdF9pbmplY3Rvcic7XG5pbXBvcnQge2Jyb3dzZXJEZXRlY3Rpb259IGZyb20gJy4vdXRpbHMnO1xuXG5leHBvcnQge2luamVjdH0gZnJvbSAnLi90ZXN0X2luamVjdG9yJztcblxuZXhwb3J0IHtleHBlY3QsIE5nTWF0Y2hlcnN9IGZyb20gJy4vbWF0Y2hlcnMnO1xuXG5leHBvcnQgdmFyIHByb3h5OiBDbGFzc0RlY29yYXRvciA9ICh0KSA9PiB0O1xuXG52YXIgX2dsb2JhbDogamFzbWluZS5HbG9iYWxQb2xsdXRlciA9IDxhbnk+KHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnID8gZ2xvYmFsIDogd2luZG93KTtcblxuZXhwb3J0IHZhciBhZnRlckVhY2g6IEZ1bmN0aW9uID0gX2dsb2JhbC5hZnRlckVhY2g7XG5cbmV4cG9ydCB0eXBlIFN5bmNUZXN0Rm4gPSAoKSA9PiB2b2lkO1xudHlwZSBBc3luY1Rlc3RGbiA9IChkb25lOiAoKSA9PiB2b2lkKSA9PiB2b2lkO1xudHlwZSBBbnlUZXN0Rm4gPSBTeW5jVGVzdEZuIHwgQXN5bmNUZXN0Rm47XG5cbmV4cG9ydCBjbGFzcyBBc3luY1Rlc3RDb21wbGV0ZXIge1xuICBjb25zdHJ1Y3Rvcihwcml2YXRlIF9kb25lOiBGdW5jdGlvbikge31cblxuICBkb25lKCk6IHZvaWQgeyB0aGlzLl9kb25lKCk7IH1cbn1cblxudmFyIGpzbUJlZm9yZUVhY2ggPSBfZ2xvYmFsLmJlZm9yZUVhY2g7XG52YXIganNtRGVzY3JpYmUgPSBfZ2xvYmFsLmRlc2NyaWJlO1xudmFyIGpzbUREZXNjcmliZSA9IF9nbG9iYWwuZmRlc2NyaWJlO1xudmFyIGpzbVhEZXNjcmliZSA9IF9nbG9iYWwueGRlc2NyaWJlO1xudmFyIGpzbUl0ID0gX2dsb2JhbC5pdDtcbnZhciBqc21JSXQgPSBfZ2xvYmFsLmZpdDtcbnZhciBqc21YSXQgPSBfZ2xvYmFsLnhpdDtcblxudmFyIHJ1bm5lclN0YWNrID0gW107XG52YXIgaW5JdCA9IGZhbHNlO1xuamFzbWluZS5ERUZBVUxUX1RJTUVPVVRfSU5URVJWQUwgPSA1MDA7XG52YXIgZ2xvYmFsVGltZU91dCA9IGJyb3dzZXJEZXRlY3Rpb24uaXNTbG93ID8gMzAwMCA6IGphc21pbmUuREVGQVVMVF9USU1FT1VUX0lOVEVSVkFMO1xuXG52YXIgdGVzdFByb3ZpZGVycztcblxuLyoqXG4gKiBNZWNoYW5pc20gdG8gcnVuIGBiZWZvcmVFYWNoKClgIGZ1bmN0aW9ucyBvZiBBbmd1bGFyIHRlc3RzLlxuICpcbiAqIE5vdGU6IEphc21pbmUgb3duIGBiZWZvcmVFYWNoYCBpcyB1c2VkIGJ5IHRoaXMgbGlicmFyeSB0byBoYW5kbGUgREkgcHJvdmlkZXJzLlxuICovXG5jbGFzcyBCZWZvcmVFYWNoUnVubmVyIHtcbiAgcHJpdmF0ZSBfZm5zOiBBcnJheTxGdW5jdGlvbldpdGhQYXJhbVRva2VucyB8IFN5bmNUZXN0Rm4+ID0gW107XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBfcGFyZW50OiBCZWZvcmVFYWNoUnVubmVyKSB7fVxuXG4gIGJlZm9yZUVhY2goZm46IEZ1bmN0aW9uV2l0aFBhcmFtVG9rZW5zIHwgU3luY1Rlc3RGbik6IHZvaWQgeyB0aGlzLl9mbnMucHVzaChmbik7IH1cblxuICBydW4oaW5qZWN0b3IpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fcGFyZW50KSB0aGlzLl9wYXJlbnQucnVuKGluamVjdG9yKTtcbiAgICB0aGlzLl9mbnMuZm9yRWFjaCgoZm4pID0+IHtcbiAgICAgIHJldHVybiBpc0Z1bmN0aW9uKGZuKSA/ICg8U3luY1Rlc3RGbj5mbikoKSA6ICg8RnVuY3Rpb25XaXRoUGFyYW1Ub2tlbnM+Zm4pLmV4ZWN1dGUoaW5qZWN0b3IpO1xuICAgIH0pO1xuICB9XG59XG5cbi8vIFJlc2V0IHRoZSB0ZXN0IHByb3ZpZGVycyBiZWZvcmUgZWFjaCB0ZXN0XG5qc21CZWZvcmVFYWNoKCgpID0+IHsgdGVzdFByb3ZpZGVycyA9IFtdOyB9KTtcblxuZnVuY3Rpb24gX2Rlc2NyaWJlKGpzbUZuLCAuLi5hcmdzKSB7XG4gIHZhciBwYXJlbnRSdW5uZXIgPSBydW5uZXJTdGFjay5sZW5ndGggPT09IDAgPyBudWxsIDogcnVubmVyU3RhY2tbcnVubmVyU3RhY2subGVuZ3RoIC0gMV07XG4gIHZhciBydW5uZXIgPSBuZXcgQmVmb3JlRWFjaFJ1bm5lcihwYXJlbnRSdW5uZXIpO1xuICBydW5uZXJTdGFjay5wdXNoKHJ1bm5lcik7XG4gIHZhciBzdWl0ZSA9IGpzbUZuKC4uLmFyZ3MpO1xuICBydW5uZXJTdGFjay5wb3AoKTtcbiAgcmV0dXJuIHN1aXRlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVzY3JpYmUoLi4uYXJncyk6IHZvaWQge1xuICByZXR1cm4gX2Rlc2NyaWJlKGpzbURlc2NyaWJlLCAuLi5hcmdzKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRkZXNjcmliZSguLi5hcmdzKTogdm9pZCB7XG4gIHJldHVybiBfZGVzY3JpYmUoanNtRERlc2NyaWJlLCAuLi5hcmdzKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHhkZXNjcmliZSguLi5hcmdzKTogdm9pZCB7XG4gIHJldHVybiBfZGVzY3JpYmUoanNtWERlc2NyaWJlLCAuLi5hcmdzKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJlZm9yZUVhY2goZm46IEZ1bmN0aW9uV2l0aFBhcmFtVG9rZW5zIHwgU3luY1Rlc3RGbik6IHZvaWQge1xuICBpZiAocnVubmVyU3RhY2subGVuZ3RoID4gMCkge1xuICAgIC8vIEluc2lkZSBhIGRlc2NyaWJlIGJsb2NrLCBiZWZvcmVFYWNoKCkgdXNlcyBhIEJlZm9yZUVhY2hSdW5uZXJcbiAgICBydW5uZXJTdGFja1tydW5uZXJTdGFjay5sZW5ndGggLSAxXS5iZWZvcmVFYWNoKGZuKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBUb3AgbGV2ZWwgYmVmb3JlRWFjaCgpIGFyZSBkZWxlZ2F0ZWQgdG8gamFzbWluZVxuICAgIGpzbUJlZm9yZUVhY2goPFN5bmNUZXN0Rm4+Zm4pO1xuICB9XG59XG5cbi8qKlxuICogQWxsb3dzIG92ZXJyaWRpbmcgZGVmYXVsdCBwcm92aWRlcnMgZGVmaW5lZCBpbiB0ZXN0X2luamVjdG9yLmpzLlxuICpcbiAqIFRoZSBnaXZlbiBmdW5jdGlvbiBtdXN0IHJldHVybiBhIGxpc3Qgb2YgREkgcHJvdmlkZXJzLlxuICpcbiAqIEV4YW1wbGU6XG4gKlxuICogICBiZWZvcmVFYWNoQmluZGluZ3MoKCkgPT4gW1xuICogICAgIHByb3ZpZGUoQ29tcGlsZXIsIHt1c2VDbGFzczogTW9ja0NvbXBpbGVyfSksXG4gKiAgICAgcHJvdmlkZShTb21lVG9rZW4sIHt1c2VWYWx1ZTogbXlWYWx1ZX0pLFxuICogICBdKTtcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJlZm9yZUVhY2hQcm92aWRlcnMoZm4pOiB2b2lkIHtcbiAganNtQmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgdmFyIGJpbmRpbmdzID0gZm4oKTtcbiAgICBpZiAoIWJpbmRpbmdzKSByZXR1cm47XG4gICAgdGVzdFByb3ZpZGVycyA9IFsuLi50ZXN0UHJvdmlkZXJzLCAuLi5iaW5kaW5nc107XG4gIH0pO1xufVxuXG4vKipcbiAqIEBkZXByZWNhdGVkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBiZWZvcmVFYWNoQmluZGluZ3MoZm4pOiB2b2lkIHtcbiAgYmVmb3JlRWFjaFByb3ZpZGVycyhmbik7XG59XG5cbmZ1bmN0aW9uIF9pdChqc21GbjogRnVuY3Rpb24sIG5hbWU6IHN0cmluZywgdGVzdEZuOiBGdW5jdGlvbldpdGhQYXJhbVRva2VucyB8IEFueVRlc3RGbixcbiAgICAgICAgICAgICB0ZXN0VGltZU91dDogbnVtYmVyKTogdm9pZCB7XG4gIHZhciBydW5uZXIgPSBydW5uZXJTdGFja1tydW5uZXJTdGFjay5sZW5ndGggLSAxXTtcbiAgdmFyIHRpbWVPdXQgPSBNYXRoLm1heChnbG9iYWxUaW1lT3V0LCB0ZXN0VGltZU91dCk7XG5cbiAgaWYgKHRlc3RGbiBpbnN0YW5jZW9mIEZ1bmN0aW9uV2l0aFBhcmFtVG9rZW5zKSB7XG4gICAgLy8gVGhlIHRlc3QgY2FzZSB1c2VzIGluamVjdCgpLiBpZSBgaXQoJ3Rlc3QnLCBpbmplY3QoW0FzeW5jVGVzdENvbXBsZXRlcl0sIChhc3luYykgPT4geyAuLi5cbiAgICAvLyB9KSk7YFxuXG4gICAgaWYgKHRlc3RGbi5oYXNUb2tlbihBc3luY1Rlc3RDb21wbGV0ZXIpKSB7XG4gICAgICBqc21GbihuYW1lLCAoZG9uZSkgPT4ge1xuICAgICAgICB2YXIgY29tcGxldGVyUHJvdmlkZXIgPSBwcm92aWRlKEFzeW5jVGVzdENvbXBsZXRlciwge1xuICAgICAgICAgIHVzZUZhY3Rvcnk6ICgpID0+IHtcbiAgICAgICAgICAgIC8vIE1hcmsgdGhlIHRlc3QgYXMgYXN5bmMgd2hlbiBhbiBBc3luY1Rlc3RDb21wbGV0ZXIgaXMgaW5qZWN0ZWQgaW4gYW4gaXQoKVxuICAgICAgICAgICAgaWYgKCFpbkl0KSB0aHJvdyBuZXcgRXJyb3IoJ0FzeW5jVGVzdENvbXBsZXRlciBjYW4gb25seSBiZSBpbmplY3RlZCBpbiBhbiBcIml0KClcIicpO1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBBc3luY1Rlc3RDb21wbGV0ZXIoZG9uZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICB2YXIgaW5qZWN0b3IgPSBjcmVhdGVUZXN0SW5qZWN0b3IoWy4uLnRlc3RQcm92aWRlcnMsIGNvbXBsZXRlclByb3ZpZGVyXSk7XG4gICAgICAgIHJ1bm5lci5ydW4oaW5qZWN0b3IpO1xuXG4gICAgICAgIGluSXQgPSB0cnVlO1xuICAgICAgICB0ZXN0Rm4uZXhlY3V0ZShpbmplY3Rvcik7XG4gICAgICAgIGluSXQgPSBmYWxzZTtcbiAgICAgIH0sIHRpbWVPdXQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBqc21GbihuYW1lLCAoKSA9PiB7XG4gICAgICAgIHZhciBpbmplY3RvciA9IGNyZWF0ZVRlc3RJbmplY3Rvcih0ZXN0UHJvdmlkZXJzKTtcbiAgICAgICAgcnVubmVyLnJ1bihpbmplY3Rvcik7XG4gICAgICAgIHRlc3RGbi5leGVjdXRlKGluamVjdG9yKTtcbiAgICAgIH0sIHRpbWVPdXQpO1xuICAgIH1cblxuICB9IGVsc2Uge1xuICAgIC8vIFRoZSB0ZXN0IGNhc2UgZG9lc24ndCB1c2UgaW5qZWN0KCkuIGllIGBpdCgndGVzdCcsIChkb25lKSA9PiB7IC4uLiB9KSk7YFxuXG4gICAgaWYgKCg8YW55PnRlc3RGbikubGVuZ3RoID09PSAwKSB7XG4gICAgICBqc21GbihuYW1lLCAoKSA9PiB7XG4gICAgICAgIHZhciBpbmplY3RvciA9IGNyZWF0ZVRlc3RJbmplY3Rvcih0ZXN0UHJvdmlkZXJzKTtcbiAgICAgICAgcnVubmVyLnJ1bihpbmplY3Rvcik7XG4gICAgICAgICg8U3luY1Rlc3RGbj50ZXN0Rm4pKCk7XG4gICAgICB9LCB0aW1lT3V0KTtcbiAgICB9IGVsc2Uge1xuICAgICAganNtRm4obmFtZSwgKGRvbmUpID0+IHtcbiAgICAgICAgdmFyIGluamVjdG9yID0gY3JlYXRlVGVzdEluamVjdG9yKHRlc3RQcm92aWRlcnMpO1xuICAgICAgICBydW5uZXIucnVuKGluamVjdG9yKTtcbiAgICAgICAgKDxBc3luY1Rlc3RGbj50ZXN0Rm4pKGRvbmUpO1xuICAgICAgfSwgdGltZU91dCk7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpdChuYW1lLCBmbiwgdGltZU91dCA9IG51bGwpOiB2b2lkIHtcbiAgcmV0dXJuIF9pdChqc21JdCwgbmFtZSwgZm4sIHRpbWVPdXQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24geGl0KG5hbWUsIGZuLCB0aW1lT3V0ID0gbnVsbCk6IHZvaWQge1xuICByZXR1cm4gX2l0KGpzbVhJdCwgbmFtZSwgZm4sIHRpbWVPdXQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaWl0KG5hbWUsIGZuLCB0aW1lT3V0ID0gbnVsbCk6IHZvaWQge1xuICByZXR1cm4gX2l0KGpzbUlJdCwgbmFtZSwgZm4sIHRpbWVPdXQpO1xufVxuXG5cbmV4cG9ydCBpbnRlcmZhY2UgR3VpbmVzc0NvbXBhdGlibGVTcHkgZXh0ZW5kcyBqYXNtaW5lLlNweSB7XG4gIC8qKiBCeSBjaGFpbmluZyB0aGUgc3B5IHdpdGggYW5kLnJldHVyblZhbHVlLCBhbGwgY2FsbHMgdG8gdGhlIGZ1bmN0aW9uIHdpbGwgcmV0dXJuIGEgc3BlY2lmaWNcbiAgICogdmFsdWUuICovXG4gIGFuZFJldHVybih2YWw6IGFueSk6IHZvaWQ7XG4gIC8qKiBCeSBjaGFpbmluZyB0aGUgc3B5IHdpdGggYW5kLmNhbGxGYWtlLCBhbGwgY2FsbHMgdG8gdGhlIHNweSB3aWxsIGRlbGVnYXRlIHRvIHRoZSBzdXBwbGllZFxuICAgKiBmdW5jdGlvbi4gKi9cbiAgYW5kQ2FsbEZha2UoZm46IEZ1bmN0aW9uKTogR3VpbmVzc0NvbXBhdGlibGVTcHk7XG4gIC8qKiByZW1vdmVzIGFsbCByZWNvcmRlZCBjYWxscyAqL1xuICByZXNldCgpO1xufVxuXG5leHBvcnQgY2xhc3MgU3B5T2JqZWN0IHtcbiAgY29uc3RydWN0b3IodHlwZSA9IG51bGwpIHtcbiAgICBpZiAodHlwZSkge1xuICAgICAgZm9yICh2YXIgcHJvcCBpbiB0eXBlLnByb3RvdHlwZSkge1xuICAgICAgICB2YXIgbSA9IG51bGw7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgbSA9IHR5cGUucHJvdG90eXBlW3Byb3BdO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgLy8gQXMgd2UgYXJlIGNyZWF0aW5nIHNweXMgZm9yIGFic3RyYWN0IGNsYXNzZXMsXG4gICAgICAgICAgLy8gdGhlc2UgY2xhc3NlcyBtaWdodCBoYXZlIGdldHRlcnMgdGhhdCB0aHJvdyB3aGVuIHRoZXkgYXJlIGFjY2Vzc2VkLlxuICAgICAgICAgIC8vIEFzIHdlIGFyZSBvbmx5IGF1dG8gY3JlYXRpbmcgc3B5cyBmb3IgbWV0aG9kcywgdGhpc1xuICAgICAgICAgIC8vIHNob3VsZCBub3QgbWF0dGVyLlxuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgbSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHRoaXMuc3B5KHByb3ApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG4gIC8vIE5vb3Agc28gdGhhdCBTcHlPYmplY3QgaGFzIHRoZSBzYW1lIGludGVyZmFjZSBhcyBpbiBEYXJ0XG4gIG5vU3VjaE1ldGhvZChhcmdzKSB7fVxuXG4gIHNweShuYW1lKSB7XG4gICAgaWYgKCF0aGlzW25hbWVdKSB7XG4gICAgICB0aGlzW25hbWVdID0gdGhpcy5fY3JlYXRlR3Vpbm5lc3NDb21wYXRpYmxlU3B5KG5hbWUpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpc1tuYW1lXTtcbiAgfVxuXG4gIHByb3AobmFtZSwgdmFsdWUpIHsgdGhpc1tuYW1lXSA9IHZhbHVlOyB9XG5cbiAgc3RhdGljIHN0dWIob2JqZWN0ID0gbnVsbCwgY29uZmlnID0gbnVsbCwgb3ZlcnJpZGVzID0gbnVsbCkge1xuICAgIGlmICghKG9iamVjdCBpbnN0YW5jZW9mIFNweU9iamVjdCkpIHtcbiAgICAgIG92ZXJyaWRlcyA9IGNvbmZpZztcbiAgICAgIGNvbmZpZyA9IG9iamVjdDtcbiAgICAgIG9iamVjdCA9IG5ldyBTcHlPYmplY3QoKTtcbiAgICB9XG5cbiAgICB2YXIgbSA9IFN0cmluZ01hcFdyYXBwZXIubWVyZ2UoY29uZmlnLCBvdmVycmlkZXMpO1xuICAgIFN0cmluZ01hcFdyYXBwZXIuZm9yRWFjaChtLCAodmFsdWUsIGtleSkgPT4geyBvYmplY3Quc3B5KGtleSkuYW5kUmV0dXJuKHZhbHVlKTsgfSk7XG4gICAgcmV0dXJuIG9iamVjdDtcbiAgfVxuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgX2NyZWF0ZUd1aW5uZXNzQ29tcGF0aWJsZVNweShuYW1lKTogR3VpbmVzc0NvbXBhdGlibGVTcHkge1xuICAgIHZhciBuZXdTcHk6IEd1aW5lc3NDb21wYXRpYmxlU3B5ID0gPGFueT5qYXNtaW5lLmNyZWF0ZVNweShuYW1lKTtcbiAgICBuZXdTcHkuYW5kQ2FsbEZha2UgPSA8YW55Pm5ld1NweS5hbmQuY2FsbEZha2U7XG4gICAgbmV3U3B5LmFuZFJldHVybiA9IDxhbnk+bmV3U3B5LmFuZC5yZXR1cm5WYWx1ZTtcbiAgICBuZXdTcHkucmVzZXQgPSA8YW55Pm5ld1NweS5jYWxscy5yZXNldDtcbiAgICAvLyByZXZpc2l0IHJldHVybiBudWxsIGhlcmUgKHByZXZpb3VzbHkgbmVlZGVkIGZvciBydHRzX2Fzc2VydCkuXG4gICAgbmV3U3B5LmFuZC5yZXR1cm5WYWx1ZShudWxsKTtcbiAgICByZXR1cm4gbmV3U3B5O1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0luSW5uZXJab25lKCk6IGJvb2xlYW4ge1xuICByZXR1cm4gKDxOZ1pvbmVab25lPmdsb2JhbC56b25lKS5faW5uZXJab25lID09PSB0cnVlO1xufVxuIl19