Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(596)

Unified Diff: lib/unittest/string_matchers.dart

Issue 10441104: New expectation functions plus convert old tests to use these. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: lib/unittest/string_matchers.dart
===================================================================
--- lib/unittest/string_matchers.dart (revision 0)
+++ lib/unittest/string_matchers.dart (revision 0)
@@ -0,0 +1,289 @@
+// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/** Returns a matcher which matches strings that are empty. */
+IMatcher isEmptyString() => new _Empty();
Bob Nystrom 2012/05/30 23:23:51 Does this add a lot of value over just doing: exp
+
+class _Empty extends _StringMatcher {
+
+ _Empty();
+
+ bool matches(item) => (item is String && item.length == 0);
+
+ IDescription describe(IDescription description) =>
+ description.append('empty string');
+}
+
+/**
+ * Returns a matcher which matches if the interpolated string form of the
+ * match argument matches the given [matcher]. That is:
+ *
+ * expect(foo, isInterpolated(bar))
+ *
+ * is equivalent to:
+ *
+ * expect("${foo}", bar)
+ */
+IMatcher isInterpolated(matcher) => new _IsInterpolated(wrapMatcher(matcher));
Bob Nystrom 2012/05/30 23:23:51 I think this is equivalent to toString(). Do we ne
gram 2012/06/01 17:33:15 Done.
+
+class _IsInterpolated extends Matcher {
+ Matcher _matcher;
+
+ _IsInterpolated(this._matcher) {
+ if (!(_matcher is Matcher)) {
+ throw new IllegalArgumentException('isInterpolated expects Matcher');
+ }
+ }
+
+ bool matches(item) => _matcher.matches("${item}");
+
+ IDescription describe(IDescription description) =>
+ description.appendDescriptionOf(_matcher).append(' interpolated');
+}
+
+/**
+ * Returns a matcher which matches if the match argument is a string and
+ * is equal to [value] when compared case-insensitively.
+ */
+IMatcher equalToIgnoringCase(String value) => new _IsEqualIgnoringCase(value);
Bob Nystrom 2012/05/30 23:23:51 "equalTo" -> "equals"
gram 2012/06/01 17:33:15 Done.
+
+class _IsEqualIgnoringCase extends _StringMatcher {
+
+ String _value;
+ String _matchValue;
+
+ _IsEqualIgnoringCase(String this._value) {
+ if (!(_value is String)) {
Bob Nystrom 2012/05/30 23:23:51 Remove this check.
gram 2012/06/01 17:33:15 Done.
+ throw new IllegalArgumentException('equalToIgnoringCase requires string');
+ }
+ _matchValue = _value.toLowerCase();
+ }
+
+ bool matches(item) =>
+ (item is String && _matchValue == item.toLowerCase());
+
+ IDescription describe(IDescription description) =>
+ description.appendDescriptionOf(_value).append(' ignoring case');
+}
+
+//---------------------------------------------------------------------
+// Utility functions
Bob Nystrom 2012/05/30 23:23:51 Remove this comment?
gram 2012/06/01 17:33:15 I removed the --- at least.
+
+bool isWhiteSpace(String ch) => (' \n\r\t'.indexOf(ch) >= 0);
Bob Nystrom 2012/05/30 23:23:51 There is some debate here, but I think this should
gram 2012/06/01 17:33:15 Done.
+
+String _stripspace(_string) {
Bob Nystrom 2012/05/30 23:23:51 "_normalizeWhitespace"?
gram 2012/06/01 17:33:15 Done.
gram 2012/06/01 17:33:15 Done.
+ StringBuffer result = new StringBuffer();
+ bool skipSpace = true;
+ for (var i = 0; i < _string.length; i++) {
+ var character = _string[i];
+ if (isWhiteSpace(character)) {
+ if (!skipSpace) {
+ result.add(' ');
+ skipSpace = true;
+ }
+ } else {
+ result.add(character);
+ skipSpace = false;
+ }
+ }
+ return result.toString().trim();
+}
+
+/**
+ * Returns a matcher which matches if the match argument is a string and
+ * is equal to [value] when compared with all runs of white space
Bob Nystrom 2012/05/30 23:23:51 "whitespace"
gram 2012/06/01 17:33:15 Done.
+ * collapsed to single spaces and leading and trailing whitespace removed.
+ *
+ * For example, equalToIgnoringCase("hello world") will match
Bob Nystrom 2012/05/30 23:23:51 Put inline code in backticks: `equalToIgnoringWhit
gram 2012/06/01 17:33:15 Done.
+ * "hello world", " hello world" and "hello world ".
+ */
+IMatcher equalToIgnoringWhitespace(_string) =>
Bob Nystrom 2012/05/30 23:23:51 "equalTo" -> "equals"
gram 2012/06/01 17:33:15 Done.
+ new _IsEqualIgnoringWhiteSpace(_string);
+
+class _IsEqualIgnoringWhiteSpace extends _StringMatcher {
+
+ String _value;
+ String _matchValue;
+
+ _IsEqualIgnoringWhiteSpace(this._value) {
+ if (!(_value is String)) {
Bob Nystrom 2012/05/30 23:23:51 Remove check.
gram 2012/06/01 17:33:15 Done.
+ throw new
+ IllegalArgumentException('equalToIgnoringWhitespace requires string');
+ }
+ _matchValue = _stripspace(_value);
+ }
+
+ bool matches(item) => (item is String && _matchValue == _stripspace(item));
Bob Nystrom 2012/05/30 23:23:51 Unneeded ().
gram 2012/06/01 17:33:15 Done.
+
+ IDescription describe(IDescription description) =>
+ description.appendDescriptionOf(_matchValue).
Bob Nystrom 2012/05/30 23:23:51 I would use a {} here. If not, +2 indent.
gram 2012/06/01 17:33:15 Done.
+ append(' ignoring whitespace');
+
+ IDescription describeMismatch(item, IDescription mismatchDescription) {
+ if (item is String) {
+ return mismatchDescription.append('was ').
+ appendDescriptionOf(_stripspace(item));
+ } else {
+ return super.describeMismatch(item, mismatchDescription);
+ }
+ }
+}
+
+/**
+ * Returns a matcher that matches if the match argument is a string and
+ * starts with [value].
+ */
+IMatcher startsWith(substring) => new _StringStartsWith(substring);
+
+class _StringStartsWith extends _StringMatcher {
+
+ String _substring;
+
+ _StringStartsWith(String this._substring) {
+ if (!(_substring is String)) {
+ throw new
+ IllegalArgumentException('startsWith requires a string');
+ }
+ }
+
+ bool matches(item) => (item is String && item.startsWith(_substring));
+
+ IDescription describe(IDescription description) =>
+ description.append('a string starting with ').
+ appendDescriptionOf(_substring);
+}
+
+/**
+ * Returns a matcher that matches if the match argument is a string and
+ * ends with [value].
+ */
+IMatcher endsWith(value) => new _StringEndsWith(value);
+
+class _StringEndsWith extends _StringMatcher {
+
+ String _substring;
+
+ _StringEndsWith(String this._substring) {
+ if (!(_substring is String)) {
+ throw new
+ IllegalArgumentException('endsWith requires a string');
Bob Nystrom 2012/05/30 23:23:51 Indent +2.
gram 2012/06/01 17:33:15 Done.
+ }
+ }
+
+ bool matches(item) => (item is String && item.endsWith(_substring));
+
+ IDescription describe(IDescription description) =>
+ description.append('a string ending with ').
+ appendDescriptionOf(_substring);
+}
+
+/**
+ * Returns a matcher that matches if the match argument is a string and
+ * contains [substring].
+ */
+IMatcher containsString(substring) => new _StringContains(substring);
Bob Nystrom 2012/05/30 23:23:51 Can we do a single unified contains() that works w
gram 2012/06/01 17:33:15 Done.
+
+class _StringContains extends _StringMatcher {
+
+ String _substring;
+
+ _StringContains(String this._substring) {
+ if (!(_substring is String)) {
+ throw new
+ IllegalArgumentException('containsString requires a string');
+ }
+ }
+
+ bool matches(item) => (item is String && item.indexOf(_substring) >= 0);
+
+ IDescription describe(IDescription description) =>
+ description.append('a string containing ').
+ appendDescriptionOf(_substring);
+}
+
+/**
+ * Returns a matcher that matches if the match argument is a string and
+ * contains a given list of [substrings] in relative order.
+ *
+ * For example, stringContainsInOrder(["a", "e", "i", "o", "u"]) will match
+ * "abcdefghijklmnopqrstuvwxyz".
+ */
+IMatcher stringContainsInOrder(substrings) =>
+ new _StringContainsInOrder(substrings);
+
+class _StringContainsInOrder extends _StringMatcher {
+
+ List<String> _substrings;
+
+ _StringContainsInOrder(List<String> this._substrings) {
+ if (!(_substrings is List)) {
+ throw new IllegalArgumentException(
+ 'stringContainsInOrder requires a list of strings');
+ }
+ for (var s in _substrings) {
+ if (!(s is String)) {
+ throw new IllegalArgumentException(
+ 'stringContainsInOrder requires a list of strings');
+ }
+ }
+ }
+
+ bool matches(item) {
+ if (!(item is String)) {
+ return false;
+ }
+ var from_index = 0;
+ for (var s in _substrings) {
+ from_index = item.indexOf(s, from_index);
+ if (from_index < 0)
+ return false;
+ }
+ return true;
+ }
+
+ IDescription describe(IDescription description) =>
+ description.appendList('a string containing ', ', ', ' in order',
+ _substrings);
+}
+
+/**
+ * Returns a matcher that matches if the match argument is a string and
+ * matches the regular expression given by [re]. [re] can be a RegExp
+ * instance or a string; in the latter case it will be used to create
+ * a RegExp instance.
+ */
+IMatcher matches(re) => new _MatchesRegExp(re);
+
+class _MatchesRegExp extends _StringMatcher {
+ RegExp _regexp;
+
+ _MatchesRegExp(re) {
+ if (re is String) {
+ _regexp = new RegExp(re);
+ } else if (re is RegExp) {
+ _regexp = re;
+ } else {
+ throw new IllegalArgumentException('matches requires a regexp or string');
+ }
+ }
+
+ bool matches(String item) => _regexp.hasMatch(item);
+
+ IDescription describe(IDescription description) =>
Bob Nystrom 2012/05/30 23:23:51 Extra space.
gram 2012/06/01 17:33:15 Done.
+ description.append("match '${_regexp.pattern}'");
+}
+
+// String matchers match against a string. We add this intermediate
+// class to give better mismatch error messages than the base Matcher class.
+class _StringMatcher extends Matcher {
+ IDescription describeMismatch(item, IDescription mismatchDescription) {
+ if (!(item is String)) {
+ return mismatchDescription.
+ appendDescriptionOf(item).
+ append(' not a string');
+ } else {
+ return super.describeMismatch(item, mismatchDescription);
+ }
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698