137 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			137 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
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 = getDOM().hasStyle(element, styles);
 | 
						|
  } else {
 | 
						|
    styles.forEach((prop, style) {
 | 
						|
      allPassed = allPassed && getDOM().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(getDOM().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(getDOM().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 = getDOM().childNodes(n);
 | 
						|
    return children != null && children.length > 0;
 | 
						|
  }
 | 
						|
 | 
						|
  if (n is Iterable) {
 | 
						|
    return n.map(elementText).join("");
 | 
						|
  }
 | 
						|
 | 
						|
  if (getDOM().isCommentNode(n)) {
 | 
						|
    return '';
 | 
						|
  }
 | 
						|
 | 
						|
  if (getDOM().isElementNode(n) && getDOM().tagName(n) == 'CONTENT') {
 | 
						|
    return elementText(getDOM().getDistributedNodes(n));
 | 
						|
  }
 | 
						|
 | 
						|
  if (getDOM().hasShadowRoot(n)) {
 | 
						|
    return elementText(getDOM().childNodesAsList(getDOM().getShadowRoot(n)));
 | 
						|
  }
 | 
						|
 | 
						|
  if (hasNodes(n)) {
 | 
						|
    return elementText(getDOM().childNodesAsList(n));
 | 
						|
  }
 | 
						|
 | 
						|
  return getDOM().getText(n);
 | 
						|
}
 |