2015-10-13 03:29:13 -04:00
|
|
|
library testing.matchers;
|
2015-10-08 18:33:17 -04:00
|
|
|
|
|
|
|
import 'dart:async';
|
|
|
|
|
2016-02-10 19:54:32 -05:00
|
|
|
import 'package:guinness2/guinness2.dart' as gns;
|
2015-10-08 18:33:17 -04:00
|
|
|
|
2015-11-19 18:09:34 -05:00
|
|
|
import 'package:angular2/src/platform/dom/dom_adapter.dart' show DOM;
|
2015-10-08 18:33:17 -04:00
|
|
|
|
2015-11-17 15:37:39 -05:00
|
|
|
import 'package:angular2/src/facade/lang.dart' show isString;
|
|
|
|
|
2015-10-08 18:33:17 -04:00
|
|
|
Expect expect(actual, [matcher]) {
|
|
|
|
final expect = new Expect(actual);
|
|
|
|
if (matcher != null) expect.to(matcher);
|
|
|
|
return expect;
|
|
|
|
}
|
|
|
|
|
|
|
|
const _u = const Object();
|
|
|
|
|
2015-11-17 15:37:39 -05:00
|
|
|
bool elementContainsStyle(element, styles) {
|
|
|
|
var allPassed = true;
|
|
|
|
if (isString(styles)) {
|
2016-04-28 20:50:03 -04:00
|
|
|
allPassed = getDOM().hasStyle(element, styles);
|
2015-11-17 15:37:39 -05:00
|
|
|
} else {
|
|
|
|
styles.forEach((prop, style) {
|
2016-04-28 20:50:03 -04:00
|
|
|
allPassed = allPassed && getDOM().hasStyle(element, prop, style);
|
2015-11-17 15:37:39 -05:00
|
|
|
});
|
|
|
|
}
|
|
|
|
return allPassed;
|
|
|
|
}
|
|
|
|
|
2015-10-08 18:33:17 -04:00
|
|
|
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) =>
|
2016-04-28 20:50:03 -04:00
|
|
|
gns.guinness.matchers.toBeTrue(getDOM().hasClass(actual, className));
|
2015-11-17 15:37:39 -05:00
|
|
|
void toHaveCssStyle(styles) {
|
|
|
|
gns.guinness.matchers.toBeTrue(elementContainsStyle(actual, styles));
|
|
|
|
}
|
2016-03-08 18:37:03 -05:00
|
|
|
void toMatchPattern(pattern) =>
|
|
|
|
gns.guinness.matchers.toBeTrue(pattern.hasMatch(actual));
|
2015-10-08 18:33:17 -04:00
|
|
|
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) =>
|
2016-04-28 20:50:03 -04:00
|
|
|
gns.guinness.matchers.toBeFalse(getDOM().hasClass(actual, className));
|
2015-11-17 15:37:39 -05:00
|
|
|
void toHaveCssStyle(styles) {
|
|
|
|
gns.guinness.matchers.toBeFalse(elementContainsStyle(actual, styles));
|
|
|
|
}
|
2016-03-08 18:37:03 -05:00
|
|
|
void toMatchPattern(pattern) =>
|
|
|
|
gns.guinness.matchers.toBeFalse(pattern.hasMatch(actual));
|
2015-10-08 18:33:17 -04:00
|
|
|
void toBeNull() => gns.guinness.matchers.toBeFalse(actual == null);
|
|
|
|
Function get _expect => gns.guinness.matchers.expect;
|
|
|
|
}
|
|
|
|
|
|
|
|
String elementText(n) {
|
|
|
|
hasNodes(n) {
|
2016-04-28 20:50:03 -04:00
|
|
|
var children = getDOM().childNodes(n);
|
2015-10-08 18:33:17 -04:00
|
|
|
return children != null && children.length > 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (n is Iterable) {
|
|
|
|
return n.map(elementText).join("");
|
|
|
|
}
|
|
|
|
|
2016-04-28 20:50:03 -04:00
|
|
|
if (getDOM().isCommentNode(n)) {
|
2015-10-08 18:33:17 -04:00
|
|
|
return '';
|
|
|
|
}
|
|
|
|
|
2016-04-28 20:50:03 -04:00
|
|
|
if (getDOM().isElementNode(n) && getDOM().tagName(n) == 'CONTENT') {
|
|
|
|
return elementText(getDOM().getDistributedNodes(n));
|
2015-10-08 18:33:17 -04:00
|
|
|
}
|
|
|
|
|
2016-04-28 20:50:03 -04:00
|
|
|
if (getDOM().hasShadowRoot(n)) {
|
|
|
|
return elementText(getDOM().childNodesAsList(getDOM().getShadowRoot(n)));
|
2015-10-08 18:33:17 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (hasNodes(n)) {
|
2016-04-28 20:50:03 -04:00
|
|
|
return elementText(getDOM().childNodesAsList(n));
|
2015-10-08 18:33:17 -04:00
|
|
|
}
|
|
|
|
|
2016-04-28 20:50:03 -04:00
|
|
|
return getDOM().getText(n);
|
2015-10-08 18:33:17 -04:00
|
|
|
}
|