repackaging: all the file moves
This commit is contained in:
@ -0,0 +1,33 @@
|
||||
import {Injectable} from 'angular2/src/core/di';
|
||||
import {AnimationBuilder} from 'angular2/src/animate/animation_builder';
|
||||
import {CssAnimationBuilder} from 'angular2/src/animate/css_animation_builder';
|
||||
import {CssAnimationOptions} from 'angular2/src/animate/css_animation_options';
|
||||
import {Animation} from 'angular2/src/animate/animation';
|
||||
import {BrowserDetails} from 'angular2/src/animate/browser_details';
|
||||
|
||||
@Injectable()
|
||||
export class MockAnimationBuilder extends AnimationBuilder {
|
||||
constructor() { super(null); }
|
||||
css(): CssAnimationBuilder { return new MockCssAnimationBuilder(); }
|
||||
}
|
||||
|
||||
class MockCssAnimationBuilder extends CssAnimationBuilder {
|
||||
constructor() { super(null); }
|
||||
start(element: HTMLElement): Animation { return new MockAnimation(element, this.data); }
|
||||
}
|
||||
|
||||
class MockBrowserAbstraction extends BrowserDetails {
|
||||
doesElapsedTimeIncludesDelay(): void { this.elapsedTimeIncludesDelay = false; }
|
||||
}
|
||||
|
||||
class MockAnimation extends Animation {
|
||||
private _callback: Function;
|
||||
constructor(element: HTMLElement, data: CssAnimationOptions) {
|
||||
super(element, data, new MockBrowserAbstraction());
|
||||
}
|
||||
wait(callback: Function) { this._callback = callback; }
|
||||
flush() {
|
||||
this._callback(0);
|
||||
this._callback = null;
|
||||
}
|
||||
}
|
51
modules/@angular/platform-browser/testing/benchmark_util.ts
Normal file
51
modules/@angular/platform-browser/testing/benchmark_util.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import {BrowserDomAdapter} from 'angular2/src/platform/browser/browser_adapter';
|
||||
import {document, window} from 'angular2/src/facade/browser';
|
||||
import {NumberWrapper, isBlank} from 'angular2/src/facade/lang';
|
||||
import {BaseException, WrappedException} from 'angular2/src/facade/exceptions';
|
||||
|
||||
var DOM = new BrowserDomAdapter();
|
||||
|
||||
export function getIntParameter(name: string) {
|
||||
return NumberWrapper.parseInt(getStringParameter(name), 10);
|
||||
}
|
||||
|
||||
export function getStringParameter(name: string) {
|
||||
var els = DOM.querySelectorAll(document, `input[name="${name}"]`);
|
||||
var value;
|
||||
var el;
|
||||
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
el = els[i];
|
||||
var type = DOM.type(el);
|
||||
if ((type != 'radio' && type != 'checkbox') || DOM.getChecked(el)) {
|
||||
value = DOM.getValue(el);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isBlank(value)) {
|
||||
throw new BaseException(`Could not find and input field with name ${name}`);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
export function bindAction(selector: string, callback: Function) {
|
||||
var el = DOM.querySelector(document, selector);
|
||||
DOM.on(el, 'click', function(_) { callback(); });
|
||||
}
|
||||
|
||||
export function microBenchmark(name, iterationCount, callback) {
|
||||
var durationName = `${name}/${iterationCount}`;
|
||||
window.console.time(durationName);
|
||||
callback();
|
||||
window.console.timeEnd(durationName);
|
||||
}
|
||||
|
||||
export function windowProfile(name: string): void {
|
||||
(<any>window.console).profile(name);
|
||||
}
|
||||
|
||||
export function windowProfileEnd(name: string): void {
|
||||
(<any>window.console).profileEnd(name);
|
||||
}
|
23
modules/@angular/platform-browser/testing/browser.ts
Normal file
23
modules/@angular/platform-browser/testing/browser.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import {
|
||||
TEST_BROWSER_STATIC_PLATFORM_PROVIDERS,
|
||||
ADDITIONAL_TEST_BROWSER_PROVIDERS
|
||||
} from 'angular2/platform/testing/browser_static';
|
||||
import {BROWSER_APP_PROVIDERS} from 'angular2/platform/browser';
|
||||
|
||||
/**
|
||||
* Providers for using template cache to avoid actual XHR.
|
||||
* Re-exported here so that tests import from a single place.
|
||||
*/
|
||||
export {CACHED_TEMPLATE_PROVIDER} from 'angular2/platform/browser';
|
||||
|
||||
/**
|
||||
* Default platform providers for testing.
|
||||
*/
|
||||
export const TEST_BROWSER_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||
/*@ts2dart_const*/[TEST_BROWSER_STATIC_PLATFORM_PROVIDERS];
|
||||
|
||||
/**
|
||||
* Default application providers for testing.
|
||||
*/
|
||||
export const TEST_BROWSER_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||
/*@ts2dart_const*/[BROWSER_APP_PROVIDERS, ADDITIONAL_TEST_BROWSER_PROVIDERS];
|
76
modules/@angular/platform-browser/testing/browser_static.ts
Normal file
76
modules/@angular/platform-browser/testing/browser_static.ts
Normal file
@ -0,0 +1,76 @@
|
||||
import {
|
||||
APP_ID,
|
||||
NgZone,
|
||||
Provider,
|
||||
PLATFORM_COMMON_PROVIDERS,
|
||||
PLATFORM_INITIALIZER
|
||||
} from 'angular2/core';
|
||||
import {DirectiveResolver, ViewResolver} from 'angular2/compiler';
|
||||
import {BROWSER_APP_COMMON_PROVIDERS} from 'angular2/src/platform/browser_common';
|
||||
import {BrowserDomAdapter} from 'angular2/src/platform/browser/browser_adapter';
|
||||
|
||||
import {AnimationBuilder} from 'angular2/src/animate/animation_builder';
|
||||
import {MockAnimationBuilder} from 'angular2/src/mock/animation_builder_mock';
|
||||
import {MockDirectiveResolver} from 'angular2/src/mock/directive_resolver_mock';
|
||||
import {MockViewResolver} from 'angular2/src/mock/view_resolver_mock';
|
||||
import {MockLocationStrategy} from 'angular2/src/mock/mock_location_strategy';
|
||||
import {LocationStrategy} from 'angular2/platform/common';
|
||||
import {MockNgZone} from 'angular2/src/mock/ng_zone_mock';
|
||||
|
||||
import {XHRImpl} from "angular2/src/platform/browser/xhr_impl";
|
||||
import {XHR} from 'angular2/compiler';
|
||||
|
||||
import {
|
||||
TestComponentBuilder,
|
||||
ComponentFixtureAutoDetect,
|
||||
ComponentFixtureNoNgZone
|
||||
} from 'angular2/src/testing/test_component_builder';
|
||||
|
||||
import {BrowserDetection} from 'angular2/src/testing/utils';
|
||||
|
||||
import {ELEMENT_PROBE_PROVIDERS} from 'angular2/platform/common_dom';
|
||||
|
||||
import {IS_DART} from 'angular2/src/facade/lang';
|
||||
|
||||
import {Log} from 'angular2/src/testing/utils';
|
||||
|
||||
function initBrowserTests() {
|
||||
BrowserDomAdapter.makeCurrent();
|
||||
BrowserDetection.setup();
|
||||
}
|
||||
|
||||
function createNgZone(): NgZone {
|
||||
return IS_DART ? new MockNgZone() : new NgZone({enableLongStackTrace: true});
|
||||
}
|
||||
|
||||
/**
|
||||
* Default platform providers for testing without a compiler.
|
||||
*/
|
||||
export const TEST_BROWSER_STATIC_PLATFORM_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||
/*@ts2dart_const*/[
|
||||
PLATFORM_COMMON_PROVIDERS,
|
||||
/*@ts2dart_Provider*/{provide: PLATFORM_INITIALIZER, useValue: initBrowserTests, multi: true}
|
||||
];
|
||||
|
||||
export const ADDITIONAL_TEST_BROWSER_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||
/*@ts2dart_const*/[
|
||||
/*@ts2dart_Provider*/ {provide: APP_ID, useValue: 'a'},
|
||||
ELEMENT_PROBE_PROVIDERS,
|
||||
/*@ts2dart_Provider*/ {provide: DirectiveResolver, useClass: MockDirectiveResolver},
|
||||
/*@ts2dart_Provider*/ {provide: ViewResolver, useClass: MockViewResolver},
|
||||
Log,
|
||||
TestComponentBuilder,
|
||||
/*@ts2dart_Provider*/ {provide: NgZone, useFactory: createNgZone},
|
||||
/*@ts2dart_Provider*/ {provide: LocationStrategy, useClass: MockLocationStrategy},
|
||||
/*@ts2dart_Provider*/ {provide: AnimationBuilder, useClass: MockAnimationBuilder},
|
||||
];
|
||||
|
||||
/**
|
||||
* Default application providers for testing without a compiler.
|
||||
*/
|
||||
export const TEST_BROWSER_STATIC_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
|
||||
/*@ts2dart_const*/[
|
||||
BROWSER_APP_COMMON_PROVIDERS,
|
||||
/*@ts2dart_Provider*/ {provide: XHR, useClass: XHRImpl},
|
||||
ADDITIONAL_TEST_BROWSER_PROVIDERS
|
||||
];
|
140
modules/@angular/platform-browser/testing/browser_util.ts
Normal file
140
modules/@angular/platform-browser/testing/browser_util.ts
Normal file
@ -0,0 +1,140 @@
|
||||
import {Injectable} from 'angular2/core';
|
||||
import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
|
||||
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
|
||||
import {isPresent, isString, RegExpWrapper, StringWrapper, RegExp} from 'angular2/src/facade/lang';
|
||||
|
||||
@Injectable()
|
||||
export class Log {
|
||||
logItems: any[];
|
||||
|
||||
constructor() { this.logItems = []; }
|
||||
|
||||
add(value): void { this.logItems.push(value); }
|
||||
|
||||
fn(value) {
|
||||
return (a1: any = null, a2: any = null, a3: any = null, a4: any = null, a5: any = null) => {
|
||||
this.logItems.push(value);
|
||||
}
|
||||
}
|
||||
|
||||
clear(): void { this.logItems = []; }
|
||||
|
||||
result(): string { return this.logItems.join("; "); }
|
||||
}
|
||||
|
||||
export var browserDetection: BrowserDetection = null;
|
||||
|
||||
export class BrowserDetection {
|
||||
private _ua: string;
|
||||
|
||||
static setup() { browserDetection = new BrowserDetection(null); }
|
||||
|
||||
constructor(ua: string) {
|
||||
if (isPresent(ua)) {
|
||||
this._ua = ua;
|
||||
} else {
|
||||
this._ua = isPresent(DOM) ? DOM.getUserAgent() : '';
|
||||
}
|
||||
}
|
||||
|
||||
get isFirefox(): boolean { return this._ua.indexOf('Firefox') > -1; }
|
||||
|
||||
get isAndroid(): boolean {
|
||||
return this._ua.indexOf('Mozilla/5.0') > -1 && this._ua.indexOf('Android') > -1 &&
|
||||
this._ua.indexOf('AppleWebKit') > -1 && this._ua.indexOf('Chrome') == -1;
|
||||
}
|
||||
|
||||
get isEdge(): boolean { return this._ua.indexOf('Edge') > -1; }
|
||||
|
||||
get isIE(): boolean { return this._ua.indexOf('Trident') > -1; }
|
||||
|
||||
get isWebkit(): boolean {
|
||||
return this._ua.indexOf('AppleWebKit') > -1 && this._ua.indexOf('Edge') == -1;
|
||||
}
|
||||
|
||||
get isIOS7(): boolean {
|
||||
return this._ua.indexOf('iPhone OS 7') > -1 || this._ua.indexOf('iPad OS 7') > -1;
|
||||
}
|
||||
|
||||
get isSlow(): boolean { return this.isAndroid || this.isIE || this.isIOS7; }
|
||||
|
||||
// The Intl API is only properly supported in recent Chrome and Opera.
|
||||
// Note: Edge is disguised as Chrome 42, so checking the "Edge" part is needed,
|
||||
// see https://msdn.microsoft.com/en-us/library/hh869301(v=vs.85).aspx
|
||||
get supportsIntlApi(): boolean {
|
||||
return this._ua.indexOf('Chrome/4') > -1 && this._ua.indexOf('Edge') == -1;
|
||||
}
|
||||
}
|
||||
|
||||
export function dispatchEvent(element, eventType): void {
|
||||
DOM.dispatchEvent(element, DOM.createEvent(eventType));
|
||||
}
|
||||
|
||||
export function el(html: string): HTMLElement {
|
||||
return <HTMLElement>DOM.firstChild(DOM.content(DOM.createTemplate(html)));
|
||||
}
|
||||
|
||||
var _RE_SPECIAL_CHARS =
|
||||
['-', '[', ']', '/', '{', '}', '\\', '(', ')', '*', '+', '?', '.', '^', '$', '|'];
|
||||
var _ESCAPE_RE = RegExpWrapper.create(`[\\${_RE_SPECIAL_CHARS.join('\\')}]`);
|
||||
export function containsRegexp(input: string): RegExp {
|
||||
return RegExpWrapper.create(
|
||||
StringWrapper.replaceAllMapped(input, _ESCAPE_RE, (match) => `\\${match[0]}`));
|
||||
}
|
||||
|
||||
export function normalizeCSS(css: string): string {
|
||||
css = StringWrapper.replaceAll(css, /\s+/g, ' ');
|
||||
css = StringWrapper.replaceAll(css, /:\s/g, ':');
|
||||
css = StringWrapper.replaceAll(css, /'/g, '"');
|
||||
css = StringWrapper.replaceAll(css, / }/g, '}');
|
||||
css = StringWrapper.replaceAllMapped(css, /url\((\"|\s)(.+)(\"|\s)\)(\s*)/g,
|
||||
(match) => `url("${match[2]}")`);
|
||||
css = StringWrapper.replaceAllMapped(css, /\[(.+)=([^"\]]+)\]/g,
|
||||
(match) => `[${match[1]}="${match[2]}"]`);
|
||||
return css;
|
||||
}
|
||||
|
||||
var _singleTagWhitelist = ['br', 'hr', 'input'];
|
||||
export function stringifyElement(el): string {
|
||||
var result = '';
|
||||
if (DOM.isElementNode(el)) {
|
||||
var tagName = DOM.tagName(el).toLowerCase();
|
||||
|
||||
// Opening tag
|
||||
result += `<${tagName}`;
|
||||
|
||||
// Attributes in an ordered way
|
||||
var attributeMap = DOM.attributeMap(el);
|
||||
var keys = [];
|
||||
attributeMap.forEach((v, k) => keys.push(k));
|
||||
ListWrapper.sort(keys);
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
var key = keys[i];
|
||||
var attValue = attributeMap.get(key);
|
||||
if (!isString(attValue)) {
|
||||
result += ` ${key}`;
|
||||
} else {
|
||||
result += ` ${key}="${attValue}"`;
|
||||
}
|
||||
}
|
||||
result += '>';
|
||||
|
||||
// Children
|
||||
var childrenRoot = DOM.templateAwareRoot(el);
|
||||
var children = isPresent(childrenRoot) ? DOM.childNodes(childrenRoot) : [];
|
||||
for (let j = 0; j < children.length; j++) {
|
||||
result += stringifyElement(children[j]);
|
||||
}
|
||||
|
||||
// Closing tag
|
||||
if (!ListWrapper.contains(_singleTagWhitelist, tagName)) {
|
||||
result += `</${tagName}>`;
|
||||
}
|
||||
} else if (DOM.isCommentNode(el)) {
|
||||
result += `<!--${DOM.nodeValue(el)}-->`;
|
||||
} else {
|
||||
result += DOM.getText(el);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
3
modules/@angular/platform-browser/testing/e2e_util.dart
Normal file
3
modules/@angular/platform-browser/testing/e2e_util.dart
Normal file
@ -0,0 +1,3 @@
|
||||
library angular2.e2e_util;
|
||||
|
||||
// empty as this file is node.js specific and should not be transpiled to dart
|
23
modules/@angular/platform-browser/testing/e2e_util.ts
Normal file
23
modules/@angular/platform-browser/testing/e2e_util.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import * as webdriver from 'selenium-webdriver';
|
||||
|
||||
export var browser: protractor.IBrowser = global['browser'];
|
||||
export var $: cssSelectorHelper = global['$'];
|
||||
|
||||
export function clickAll(buttonSelectors) {
|
||||
buttonSelectors.forEach(function(selector) { $(selector).click(); });
|
||||
}
|
||||
|
||||
export function verifyNoBrowserErrors() {
|
||||
// TODO(tbosch): Bug in ChromeDriver: Need to execute at least one command
|
||||
// so that the browser logs can be read out!
|
||||
browser.executeScript('1+1');
|
||||
browser.manage().logs().get('browser').then(function(browserLog) {
|
||||
var filteredLog = browserLog.filter(function(logEntry) {
|
||||
if (logEntry.level.value >= webdriver.logging.Level.INFO.value) {
|
||||
console.log('>> ' + logEntry.message);
|
||||
}
|
||||
return logEntry.level.value > webdriver.logging.Level.WARNING.value;
|
||||
});
|
||||
expect(filteredLog).toEqual([]);
|
||||
});
|
||||
}
|
136
modules/@angular/platform-browser/testing/matchers.dart
Normal file
136
modules/@angular/platform-browser/testing/matchers.dart
Normal file
@ -0,0 +1,136 @@
|
||||
library testing.matchers;
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:guinness2/guinness2.dart' as gns;
|
||||
|
||||
import 'package:angular2/src/platform/dom/dom_adapter.dart' show DOM;
|
||||
|
||||
import 'package:angular2/src/facade/lang.dart' show isString;
|
||||
|
||||
Expect expect(actual, [matcher]) {
|
||||
final expect = new Expect(actual);
|
||||
if (matcher != null) expect.to(matcher);
|
||||
return expect;
|
||||
}
|
||||
|
||||
const _u = const Object();
|
||||
|
||||
bool elementContainsStyle(element, styles) {
|
||||
var allPassed = true;
|
||||
if (isString(styles)) {
|
||||
allPassed = DOM.hasStyle(element, styles);
|
||||
} else {
|
||||
styles.forEach((prop, style) {
|
||||
allPassed = allPassed && DOM.hasStyle(element, prop, style);
|
||||
});
|
||||
}
|
||||
return allPassed;
|
||||
}
|
||||
|
||||
expectErrorMessage(actual, expectedMessage) {
|
||||
expect(actual.toString()).toContain(expectedMessage);
|
||||
}
|
||||
|
||||
expectException(Function actual, expectedMessage) {
|
||||
try {
|
||||
actual();
|
||||
} catch (e, s) {
|
||||
expectErrorMessage(e, expectedMessage);
|
||||
}
|
||||
}
|
||||
|
||||
class Expect extends gns.Expect {
|
||||
Expect(actual) : super(actual);
|
||||
|
||||
NotExpect get not => new NotExpect(actual);
|
||||
|
||||
void toEqual(expected) => toHaveSameProps(expected);
|
||||
void toContainError(message) => expectErrorMessage(this.actual, message);
|
||||
void toThrowError([message = ""]) => toThrowWith(message: message);
|
||||
void toThrowErrorWith(message) => expectException(this.actual, message);
|
||||
void toBePromise() => gns.guinness.matchers.toBeTrue(actual is Future);
|
||||
void toHaveCssClass(className) =>
|
||||
gns.guinness.matchers.toBeTrue(DOM.hasClass(actual, className));
|
||||
void toHaveCssStyle(styles) {
|
||||
gns.guinness.matchers.toBeTrue(elementContainsStyle(actual, styles));
|
||||
}
|
||||
void toMatchPattern(pattern) =>
|
||||
gns.guinness.matchers.toBeTrue(pattern.hasMatch(actual));
|
||||
void toImplement(expected) => toBeA(expected);
|
||||
void toBeNaN() =>
|
||||
gns.guinness.matchers.toBeTrue(double.NAN.compareTo(actual) == 0);
|
||||
void toHaveText(expected) => _expect(elementText(actual), expected);
|
||||
void toHaveBeenCalledWith([a = _u, b = _u, c = _u, d = _u, e = _u, f = _u]) =>
|
||||
_expect(_argsMatch(actual, a, b, c, d, e, f), true,
|
||||
reason: 'method invoked with correct arguments');
|
||||
Function get _expect => gns.guinness.matchers.expect;
|
||||
|
||||
// TODO(tbosch): move this hack into Guinness
|
||||
_argsMatch(spyFn, [a0 = _u, a1 = _u, a2 = _u, a3 = _u, a4 = _u, a5 = _u]) {
|
||||
var calls = spyFn.calls;
|
||||
final toMatch = _takeDefined([a0, a1, a2, a3, a4, a5]);
|
||||
if (calls.isEmpty) {
|
||||
return false;
|
||||
} else {
|
||||
gns.SamePropsMatcher matcher = new gns.SamePropsMatcher(toMatch);
|
||||
for (var i = 0; i < calls.length; i++) {
|
||||
var call = calls[i];
|
||||
// TODO: create a better error message, not just 'Expected: <true> Actual: <false>'.
|
||||
// For hacking this is good:
|
||||
// print(call.positionalArguments);
|
||||
if (matcher.matches(call.positionalArguments, null)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
List _takeDefined(List iter) => iter.takeWhile((_) => _ != _u).toList();
|
||||
}
|
||||
|
||||
class NotExpect extends gns.NotExpect {
|
||||
NotExpect(actual) : super(actual);
|
||||
|
||||
void toEqual(expected) => toHaveSameProps(expected);
|
||||
void toBePromise() => gns.guinness.matchers.toBeFalse(actual is Future);
|
||||
void toHaveCssClass(className) =>
|
||||
gns.guinness.matchers.toBeFalse(DOM.hasClass(actual, className));
|
||||
void toHaveCssStyle(styles) {
|
||||
gns.guinness.matchers.toBeFalse(elementContainsStyle(actual, styles));
|
||||
}
|
||||
void toMatchPattern(pattern) =>
|
||||
gns.guinness.matchers.toBeFalse(pattern.hasMatch(actual));
|
||||
void toBeNull() => gns.guinness.matchers.toBeFalse(actual == null);
|
||||
Function get _expect => gns.guinness.matchers.expect;
|
||||
}
|
||||
|
||||
String elementText(n) {
|
||||
hasNodes(n) {
|
||||
var children = DOM.childNodes(n);
|
||||
return children != null && children.length > 0;
|
||||
}
|
||||
|
||||
if (n is Iterable) {
|
||||
return n.map(elementText).join("");
|
||||
}
|
||||
|
||||
if (DOM.isCommentNode(n)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (DOM.isElementNode(n) && DOM.tagName(n) == 'CONTENT') {
|
||||
return elementText(DOM.getDistributedNodes(n));
|
||||
}
|
||||
|
||||
if (DOM.hasShadowRoot(n)) {
|
||||
return elementText(DOM.childNodesAsList(DOM.getShadowRoot(n)));
|
||||
}
|
||||
|
||||
if (hasNodes(n)) {
|
||||
return elementText(DOM.childNodesAsList(n));
|
||||
}
|
||||
|
||||
return DOM.getText(n);
|
||||
}
|
318
modules/@angular/platform-browser/testing/matchers.ts
Normal file
318
modules/@angular/platform-browser/testing/matchers.ts
Normal file
@ -0,0 +1,318 @@
|
||||
import {DOM} from 'angular2/src/platform/dom/dom_adapter';
|
||||
import {global, isString} from 'angular2/src/facade/lang';
|
||||
import {StringMapWrapper} from 'angular2/src/facade/collection';
|
||||
|
||||
/**
|
||||
* Jasmine matchers that check Angular specific conditions.
|
||||
*/
|
||||
export interface NgMatchers extends jasmine.Matchers {
|
||||
/**
|
||||
* Expect the value to be a `Promise`.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* {@example testing/ts/matchers.ts region='toBePromise'}
|
||||
*/
|
||||
toBePromise(): boolean;
|
||||
|
||||
/**
|
||||
* Expect the value to be an instance of a class.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* {@example testing/ts/matchers.ts region='toBeAnInstanceOf'}
|
||||
*/
|
||||
toBeAnInstanceOf(expected: any): boolean;
|
||||
|
||||
/**
|
||||
* Expect the element to have exactly the given text.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* {@example testing/ts/matchers.ts region='toHaveText'}
|
||||
*/
|
||||
toHaveText(expected: any): boolean;
|
||||
|
||||
/**
|
||||
* Expect the element to have the given CSS class.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* {@example testing/ts/matchers.ts region='toHaveCssClass'}
|
||||
*/
|
||||
toHaveCssClass(expected: any): boolean;
|
||||
|
||||
/**
|
||||
* Expect the element to have the given CSS styles.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* {@example testing/ts/matchers.ts region='toHaveCssStyle'}
|
||||
*/
|
||||
toHaveCssStyle(expected: any): boolean;
|
||||
|
||||
/**
|
||||
* Expect a class to implement the interface of the given class.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* {@example testing/ts/matchers.ts region='toImplement'}
|
||||
*/
|
||||
toImplement(expected: any): boolean;
|
||||
|
||||
/**
|
||||
* Expect an exception to contain the given error text.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* {@example testing/ts/matchers.ts region='toContainError'}
|
||||
*/
|
||||
toContainError(expected: any): boolean;
|
||||
|
||||
/**
|
||||
* Expect a function to throw an error with the given error text when executed.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* {@example testing/ts/matchers.ts region='toThrowErrorWith'}
|
||||
*/
|
||||
toThrowErrorWith(expectedMessage: any): boolean;
|
||||
|
||||
/**
|
||||
* Expect a string to match the given regular expression.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* {@example testing/ts/matchers.ts region='toMatchPattern'}
|
||||
*/
|
||||
toMatchPattern(expectedMessage: any): boolean;
|
||||
|
||||
/**
|
||||
* Invert the matchers.
|
||||
*/
|
||||
not: NgMatchers;
|
||||
}
|
||||
|
||||
var _global = <any>(typeof window === 'undefined' ? global : window);
|
||||
|
||||
/**
|
||||
* Jasmine matching function with Angular matchers mixed in.
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* {@example testing/ts/matchers.ts region='toHaveText'}
|
||||
*/
|
||||
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 :-(
|
||||
Map.prototype['jasmineToString'] = function() {
|
||||
var m = this;
|
||||
if (!m) {
|
||||
return '' + m;
|
||||
}
|
||||
var res = [];
|
||||
m.forEach((v, k) => { res.push(`${k}:${v}`); });
|
||||
return `{ ${res.join(',')} }`;
|
||||
};
|
||||
|
||||
_global.beforeEach(function() {
|
||||
jasmine.addMatchers({
|
||||
// Custom handler for Map as Jasmine does not support it yet
|
||||
toEqual: function(util, customEqualityTesters) {
|
||||
return {
|
||||
compare: function(actual, expected) {
|
||||
return {pass: util.equals(actual, expected, [compareMap])};
|
||||
}
|
||||
};
|
||||
|
||||
function compareMap(actual, expected) {
|
||||
if (actual instanceof Map) {
|
||||
var pass = actual.size === expected.size;
|
||||
if (pass) {
|
||||
actual.forEach((v, k) => { pass = pass && util.equals(v, expected.get(k)); });
|
||||
}
|
||||
return pass;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
toBePromise: function() {
|
||||
return {
|
||||
compare: function(actual, expectedClass) {
|
||||
var pass = typeof actual === 'object' && typeof actual.then === 'function';
|
||||
return {pass: pass, get message() { return 'Expected ' + actual + ' to be a promise'; }};
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
toBeAnInstanceOf: function() {
|
||||
return {
|
||||
compare: function(actual, expectedClass) {
|
||||
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 {
|
||||
compare: function(actual, expectedText) {
|
||||
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)};
|
||||
|
||||
function buildError(isNot) {
|
||||
return function(actual, className) {
|
||||
return {
|
||||
pass: DOM.hasClass(actual, className) == !isNot,
|
||||
get message() {
|
||||
return `Expected ${actual.outerHTML} ${isNot ? 'not ' : ''}to contain the CSS class "${className}"`;
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
toHaveCssStyle: function() {
|
||||
return {
|
||||
compare: function(actual, styles) {
|
||||
var allPassed;
|
||||
if (isString(styles)) {
|
||||
allPassed = DOM.hasStyle(actual, styles);
|
||||
} else {
|
||||
allPassed = !StringMapWrapper.isEmpty(styles);
|
||||
StringMapWrapper.forEach(styles, (style, prop) => {
|
||||
allPassed = allPassed && DOM.hasStyle(actual, prop, style);
|
||||
});
|
||||
}
|
||||
|
||||
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}"`;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
toContainError: function() {
|
||||
return {
|
||||
compare: function(actual, expectedText) {
|
||||
var errorMessage = actual.toString();
|
||||
return {
|
||||
pass: errorMessage.indexOf(expectedText) > -1,
|
||||
get message() { return 'Expected ' + errorMessage + ' to contain ' + expectedText; }
|
||||
};
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
toThrowErrorWith: function() {
|
||||
return {
|
||||
compare: function(actual, expectedText) {
|
||||
try {
|
||||
actual();
|
||||
return {
|
||||
pass: false,
|
||||
get message() { return "Was expected to throw, but did not throw"; }
|
||||
};
|
||||
} catch (e) {
|
||||
var errorMessage = e.toString();
|
||||
return {
|
||||
pass: errorMessage.indexOf(expectedText) > -1,
|
||||
get message() { return 'Expected ' + errorMessage + ' to contain ' + expectedText; }
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
toMatchPattern() {
|
||||
return {compare: buildError(false), negativeCompare: buildError(true)};
|
||||
|
||||
function buildError(isNot) {
|
||||
return function(actual, regex) {
|
||||
return {
|
||||
pass: regex.test(actual) == !isNot,
|
||||
get message() {
|
||||
return `Expected ${actual} ${isNot ? 'not ' : ''}to match ${regex.toString()}`;
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
toImplement: function() {
|
||||
return {
|
||||
compare: function(actualObject, expectedInterface) {
|
||||
var objProps = Object.keys(actualObject.constructor.prototype);
|
||||
var intProps = Object.keys(expectedInterface.prototype);
|
||||
|
||||
var missedMethods = [];
|
||||
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: ' +
|
||||
missedMethods.join(", ");
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function elementText(n) {
|
||||
var hasNodes = (n) => {
|
||||
var children = DOM.childNodes(n);
|
||||
return children && children.length > 0;
|
||||
};
|
||||
|
||||
if (n instanceof Array) {
|
||||
return n.map(elementText).join("");
|
||||
}
|
||||
|
||||
if (DOM.isCommentNode(n)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (DOM.isElementNode(n) && DOM.tagName(n) == 'CONTENT') {
|
||||
return elementText(Array.prototype.slice.apply(DOM.getDistributedNodes(n)));
|
||||
}
|
||||
|
||||
if (DOM.hasShadowRoot(n)) {
|
||||
return elementText(DOM.childNodesAsList(DOM.getShadowRoot(n)));
|
||||
}
|
||||
|
||||
if (hasNodes(n)) {
|
||||
return elementText(DOM.childNodesAsList(n));
|
||||
}
|
||||
|
||||
return DOM.getText(n);
|
||||
}
|
3
modules/@angular/platform-browser/testing/perf_util.dart
Normal file
3
modules/@angular/platform-browser/testing/perf_util.dart
Normal file
@ -0,0 +1,3 @@
|
||||
library angular2.testing.perf_util;
|
||||
|
||||
// empty as this file is node.js specific and should not be transpiled to dart
|
63
modules/@angular/platform-browser/testing/perf_util.ts
Normal file
63
modules/@angular/platform-browser/testing/perf_util.ts
Normal file
@ -0,0 +1,63 @@
|
||||
export {verifyNoBrowserErrors} from './e2e_util';
|
||||
|
||||
var benchpress = global['benchpress'];
|
||||
var bind = benchpress.bind;
|
||||
var Options = benchpress.Options;
|
||||
|
||||
export function runClickBenchmark(config) {
|
||||
browser.ignoreSynchronization = !config.waitForAngular2;
|
||||
var buttons = config.buttons.map(function(selector) { return $(selector); });
|
||||
config.work = function() { buttons.forEach(function(button) { button.click(); }); };
|
||||
return runBenchmark(config);
|
||||
}
|
||||
|
||||
export function runBenchmark(config) {
|
||||
return getScaleFactor(browser.params.benchmark.scaling)
|
||||
.then(function(scaleFactor) {
|
||||
var description = {};
|
||||
var urlParams = [];
|
||||
if (config.params) {
|
||||
config.params.forEach(function(param) {
|
||||
var name = param.name;
|
||||
var value = applyScaleFactor(param.value, scaleFactor, param.scale);
|
||||
urlParams.push(name + '=' + value);
|
||||
description[name] = value;
|
||||
});
|
||||
}
|
||||
var url = encodeURI(config.url + '?' + urlParams.join('&'));
|
||||
return browser.get(url).then(function() {
|
||||
return global['benchpressRunner'].sample({
|
||||
id: config.id,
|
||||
execute: config.work,
|
||||
prepare: config.prepare,
|
||||
microMetrics: config.microMetrics,
|
||||
bindings: [bind(Options.SAMPLE_DESCRIPTION).toValue(description)]
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getScaleFactor(possibleScalings) {
|
||||
return browser.executeScript('return navigator.userAgent')
|
||||
.then(function(userAgent: string) {
|
||||
var scaleFactor = 1;
|
||||
possibleScalings.forEach(function(entry) {
|
||||
if (userAgent.match(entry.userAgent)) {
|
||||
scaleFactor = entry.value;
|
||||
}
|
||||
});
|
||||
return scaleFactor;
|
||||
});
|
||||
}
|
||||
|
||||
function applyScaleFactor(value, scaleFactor, method) {
|
||||
if (method === 'log2') {
|
||||
return value + Math.log(scaleFactor) / Math.LN2;
|
||||
} else if (method === 'sqrt') {
|
||||
return value * Math.sqrt(scaleFactor);
|
||||
} else if (method === 'linear') {
|
||||
return value * scaleFactor;
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
130
modules/@angular/platform-browser/testing/shims_for_IE.js
Normal file
130
modules/@angular/platform-browser/testing/shims_for_IE.js
Normal file
@ -0,0 +1,130 @@
|
||||
// function.name (all IE)
|
||||
/*! @source http://stackoverflow.com/questions/6903762/function-name-not-supported-in-ie*/
|
||||
if (!Object.hasOwnProperty('name')) {
|
||||
Object.defineProperty(Function.prototype, 'name', {
|
||||
get: function() {
|
||||
var matches = this.toString().match(/^\s*function\s*(\S*)\s*\(/);
|
||||
var name = matches && matches.length > 1 ? matches[1] : "";
|
||||
// For better performance only parse once, and then cache the
|
||||
// result through a new accessor for repeated access.
|
||||
Object.defineProperty(this, 'name', {value: name});
|
||||
return name;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// URL polyfill for SystemJS (all IE)
|
||||
/*! @source https://github.com/ModuleLoader/es6-module-loader/blob/master/src/url-polyfill.js*/
|
||||
// from https://gist.github.com/Yaffle/1088850
|
||||
(function(global) {
|
||||
function URLPolyfill(url, baseURL) {
|
||||
if (typeof url != 'string') {
|
||||
throw new TypeError('URL must be a string');
|
||||
}
|
||||
var m = String(url).replace(/^\s+|\s+$/g, "").match(/^([^:\/?#]+:)?(?:\/\/(?:([^:@\/?#]*)(?::([^:@\/?#]*))?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/);
|
||||
if (!m) {
|
||||
throw new RangeError();
|
||||
}
|
||||
var protocol = m[1] || "";
|
||||
var username = m[2] || "";
|
||||
var password = m[3] || "";
|
||||
var host = m[4] || "";
|
||||
var hostname = m[5] || "";
|
||||
var port = m[6] || "";
|
||||
var pathname = m[7] || "";
|
||||
var search = m[8] || "";
|
||||
var hash = m[9] || "";
|
||||
if (baseURL !== undefined) {
|
||||
var base = baseURL instanceof URLPolyfill ? baseURL : new URLPolyfill(baseURL);
|
||||
var flag = protocol === "" && host === "" && username === "";
|
||||
if (flag && pathname === "" && search === "") {
|
||||
search = base.search;
|
||||
}
|
||||
if (flag && pathname.charAt(0) !== "/") {
|
||||
pathname = (pathname !== "" ? (((base.host !== "" || base.username !== "") && base.pathname === "" ? "/" : "") + base.pathname.slice(0, base.pathname.lastIndexOf("/") + 1) + pathname) : base.pathname);
|
||||
}
|
||||
// dot segments removal
|
||||
var output = [];
|
||||
pathname.replace(/^(\.\.?(\/|$))+/, "")
|
||||
.replace(/\/(\.(\/|$))+/g, "/")
|
||||
.replace(/\/\.\.$/, "/../")
|
||||
.replace(/\/?[^\/]*/g, function (p) {
|
||||
if (p === "/..") {
|
||||
output.pop();
|
||||
} else {
|
||||
output.push(p);
|
||||
}
|
||||
});
|
||||
pathname = output.join("").replace(/^\//, pathname.charAt(0) === "/" ? "/" : "");
|
||||
if (flag) {
|
||||
port = base.port;
|
||||
hostname = base.hostname;
|
||||
host = base.host;
|
||||
password = base.password;
|
||||
username = base.username;
|
||||
}
|
||||
if (protocol === "") {
|
||||
protocol = base.protocol;
|
||||
}
|
||||
}
|
||||
|
||||
// convert windows file URLs to use /
|
||||
if (protocol == 'file:')
|
||||
pathname = pathname.replace(/\\/g, '/');
|
||||
|
||||
this.origin = protocol + (protocol !== "" || host !== "" ? "//" : "") + host;
|
||||
this.href = protocol + (protocol !== "" || host !== "" ? "//" : "") + (username !== "" ? username + (password !== "" ? ":" + password : "") + "@" : "") + host + pathname + search + hash;
|
||||
this.protocol = protocol;
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.host = host;
|
||||
this.hostname = hostname;
|
||||
this.port = port;
|
||||
this.pathname = pathname;
|
||||
this.search = search;
|
||||
this.hash = hash;
|
||||
}
|
||||
global.URLPolyfill = URLPolyfill;
|
||||
})(typeof self != 'undefined' ? self : global);
|
||||
|
||||
//classList (IE9)
|
||||
/*! @license please refer to http://unlicense.org/ */
|
||||
/*! @author Eli Grey */
|
||||
/*! @source https://github.com/eligrey/classList.js */
|
||||
;if("document" in self&&!("classList" in document.createElement("_"))){(function(j){"use strict";if(!("Element" in j)){return}var a="classList",f="prototype",m=j.Element[f],b=Object,k=String[f].trim||function(){return this.replace(/^\s+|\s+$/g,"")},c=Array[f].indexOf||function(q){var p=0,o=this.length;for(;p<o;p++){if(p in this&&this[p]===q){return p}}return -1},n=function(o,p){this.name=o;this.code=DOMException[o];this.message=p},g=function(p,o){if(o===""){throw new n("SYNTAX_ERR","An invalid or illegal string was specified")}if(/\s/.test(o)){throw new n("INVALID_CHARACTER_ERR","String contains an invalid character")}return c.call(p,o)},d=function(s){var r=k.call(s.getAttribute("class")||""),q=r?r.split(/\s+/):[],p=0,o=q.length;for(;p<o;p++){this.push(q[p])}this._updateClassName=function(){s.setAttribute("class",this.toString())}},e=d[f]=[],i=function(){return new d(this)};n[f]=Error[f];e.item=function(o){return this[o]||null};e.contains=function(o){o+="";return g(this,o)!==-1};e.add=function(){var s=arguments,r=0,p=s.length,q,o=false;do{q=s[r]+"";if(g(this,q)===-1){this.push(q);o=true}}while(++r<p);if(o){this._updateClassName()}};e.remove=function(){var t=arguments,s=0,p=t.length,r,o=false;do{r=t[s]+"";var q=g(this,r);if(q!==-1){this.splice(q,1);o=true}}while(++s<p);if(o){this._updateClassName()}};e.toggle=function(p,q){p+="";var o=this.contains(p),r=o?q!==true&&"remove":q!==false&&"add";if(r){this[r](p)}return !o};e.toString=function(){return this.join(" ")};if(b.defineProperty){var l={get:i,enumerable:true,configurable:true};try{b.defineProperty(m,a,l)}catch(h){if(h.number===-2146823252){l.enumerable=false;b.defineProperty(m,a,l)}}}else{if(b[f].__defineGetter__){m.__defineGetter__(a,i)}}}(self))};
|
||||
|
||||
//console mock (IE9)
|
||||
if (!window.console) window.console = {};
|
||||
if (!window.console.log) window.console.log = function () { };
|
||||
if (!window.console.error) window.console.error = function () { };
|
||||
if (!window.console.warn) window.console.warn = function () { };
|
||||
if (!window.console.assert) window.console.assert = function () { };
|
||||
|
||||
//RequestAnimationFrame (IE9, Android 4.1, 4.2, 4.3)
|
||||
/*! @author Paul Irish */
|
||||
/*! @source https://gist.github.com/paulirish/1579671 */
|
||||
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
|
||||
// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
|
||||
|
||||
// requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel
|
||||
|
||||
// MIT license
|
||||
|
||||
(function() {
|
||||
var lastTime = 0;
|
||||
|
||||
if (!window.requestAnimationFrame)
|
||||
window.requestAnimationFrame = function(callback, element) {
|
||||
var currTime = Date.now();
|
||||
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
|
||||
var id = window.setTimeout(function() { callback(currTime + timeToCall); },
|
||||
timeToCall);
|
||||
lastTime = currTime + timeToCall;
|
||||
return id;
|
||||
};
|
||||
|
||||
if (!window.cancelAnimationFrame)
|
||||
window.cancelAnimationFrame = function(id) {
|
||||
clearTimeout(id);
|
||||
};
|
||||
}());
|
@ -0,0 +1,178 @@
|
||||
library angular2.src.testing.testing_internal_core;
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:guinness2/guinness2.dart' as gns;
|
||||
export 'package:guinness2/guinness2.dart'
|
||||
hide
|
||||
Expect,
|
||||
expect,
|
||||
NotExpect,
|
||||
beforeEach,
|
||||
it,
|
||||
iit,
|
||||
xit,
|
||||
describe,
|
||||
ddescribe,
|
||||
xdescribe,
|
||||
SpyObject,
|
||||
SpyFunction;
|
||||
|
||||
export 'matchers.dart' show expect, Expect, NotExpect;
|
||||
|
||||
import 'package:angular2/src/core/reflection/reflection.dart';
|
||||
import 'package:angular2/src/core/reflection/reflection_capabilities.dart';
|
||||
|
||||
import 'package:angular2/src/core/di/provider.dart' show bind;
|
||||
import 'package:angular2/src/facade/collection.dart' show StringMapWrapper;
|
||||
|
||||
import 'async_test_completer.dart';
|
||||
export 'async_test_completer.dart' show AsyncTestCompleter;
|
||||
|
||||
import 'test_injector.dart';
|
||||
export 'test_injector.dart' show inject;
|
||||
|
||||
TestInjector _testInjector = getTestInjector();
|
||||
bool _inIt = false;
|
||||
bool _initialized = false;
|
||||
List<dynamic> _platformProviders = [];
|
||||
List<dynamic> _applicationProviders = [];
|
||||
|
||||
void setDartBaseTestProviders(List<dynamic> platform, List<dynamic> application) {
|
||||
_platformProviders = platform;
|
||||
_applicationProviders = application;
|
||||
}
|
||||
|
||||
void testSetup() {
|
||||
if (_initialized) {
|
||||
return;
|
||||
}
|
||||
_initialized = true;
|
||||
reflector.reflectionCapabilities = new ReflectionCapabilities();
|
||||
setBaseTestProviders(_platformProviders, _applicationProviders);
|
||||
// beforeEach configuration:
|
||||
// - clear the bindings before each test,
|
||||
// - collect the bindings before each test, see beforeEachProviders(),
|
||||
// - create the test injector to be used in beforeEach() and it()
|
||||
|
||||
gns.beforeEach(() {
|
||||
_testInjector.reset();
|
||||
});
|
||||
|
||||
var completerProvider = bind(AsyncTestCompleter).toFactory(() {
|
||||
// Mark the test as async when an AsyncTestCompleter is injected in an it(),
|
||||
if (!_inIt) throw 'AsyncTestCompleter can only be injected in an "it()"';
|
||||
return new AsyncTestCompleter();
|
||||
});
|
||||
|
||||
gns.beforeEach(() {
|
||||
_testInjector.addProviders([completerProvider]);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows overriding default providers defined in test_injector.js.
|
||||
*
|
||||
* The given function must return a list of DI providers.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* beforeEachProviders(() => [
|
||||
* bind(Compiler).toClass(MockCompiler),
|
||||
* bind(SomeToken).toValue(myValue),
|
||||
* ]);
|
||||
*/
|
||||
void beforeEachProviders(Function fn) {
|
||||
testSetup();
|
||||
gns.beforeEach(() {
|
||||
var providers = fn();
|
||||
if (providers != null) _testInjector.addProviders(providers);
|
||||
});
|
||||
}
|
||||
|
||||
@Deprecated('using beforeEachProviders instead')
|
||||
void beforeEachBindings(Function fn) {
|
||||
beforeEachProviders(fn);
|
||||
}
|
||||
|
||||
void beforeEach(fn) {
|
||||
testSetup();
|
||||
gns.beforeEach(fn);
|
||||
}
|
||||
|
||||
void _it(gnsFn, name, fn) {
|
||||
testSetup();
|
||||
gnsFn(name, () {
|
||||
_inIt = true;
|
||||
var retVal = fn();
|
||||
_inIt = false;
|
||||
return retVal;
|
||||
});
|
||||
}
|
||||
|
||||
void it(name, fn, [timeOut = null]) {
|
||||
_it(gns.it, name, fn);
|
||||
}
|
||||
|
||||
void iit(name, fn, [timeOut = null]) {
|
||||
_it(gns.iit, name, fn);
|
||||
}
|
||||
|
||||
void xit(name, fn, [timeOut = null]) {
|
||||
_it(gns.xit, name, fn);
|
||||
}
|
||||
|
||||
void describe(name, fn) {
|
||||
testSetup();
|
||||
gns.describe(name, fn);
|
||||
}
|
||||
|
||||
void ddescribe(name, fn) {
|
||||
testSetup();
|
||||
gns.ddescribe(name, fn);
|
||||
}
|
||||
|
||||
void xdescribe(name, fn) {
|
||||
testSetup();
|
||||
gns.xdescribe(name, fn);
|
||||
}
|
||||
|
||||
class SpyFunction extends gns.SpyFunction {
|
||||
SpyFunction(String name) : super(name);
|
||||
|
||||
// TODO: vsavkin move to guinness
|
||||
andReturn(value) {
|
||||
return andCallFake(([a0, a1, a2, a3, a4, a5]) => value);
|
||||
}
|
||||
}
|
||||
|
||||
class SpyObject extends gns.SpyObject {
|
||||
final Map<String, SpyFunction> _spyFuncs = {};
|
||||
|
||||
SpyObject([arg]) {}
|
||||
|
||||
SpyFunction spy(String funcName) =>
|
||||
_spyFuncs.putIfAbsent(funcName, () => new SpyFunction(funcName));
|
||||
|
||||
void prop(String funcName, value) {
|
||||
_spyFuncs
|
||||
.putIfAbsent("get:${funcName}", () => new SpyFunction(funcName))
|
||||
.andReturn(value);
|
||||
}
|
||||
|
||||
static stub([object = null, config = null, overrides = null]) {
|
||||
if (object is! 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;
|
||||
}
|
||||
}
|
||||
|
||||
bool isInInnerZone() => Zone.current['_innerZone'] == true;
|
Reference in New Issue
Block a user