Enable Travis-CI (#19)

Fixes #18
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..44a0542
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,24 @@
+language: dart
+
+dart:
+  - dev
+  - stable
+
+dart_task:
+  - test: --platform vm,chrome
+
+matrix:
+  include:
+    # Only validate formatting using the dev release
+    - dart: dev
+      dart_task: dartfmt
+    - dart: dev
+      dart_task: dartanalyzer
+
+# Only building master means that we don't run two builds for each pull request.
+branches:
+  only: [master]
+
+cache:
+ directories:
+   - $HOME/.pub-cache
diff --git a/lib/src/colors.dart b/lib/src/colors.dart
index e934cde..b9afab0 100644
--- a/lib/src/colors.dart
+++ b/lib/src/colors.dart
@@ -8,4 +8,3 @@
 const String YELLOW = '\u001b[33m';
 
 const String NONE = '\u001b[0m';
-
diff --git a/lib/src/file.dart b/lib/src/file.dart
index 0217c2d..6154e13 100644
--- a/lib/src/file.dart
+++ b/lib/src/file.dart
@@ -53,8 +53,7 @@
   ///
   /// Use [new SourceFile.fromString] instead.
   @Deprecated("Will be removed in 2.0.0")
-  SourceFile(String text, {url})
-      : this.decoded(text.runes, url: url);
+  SourceFile(String text, {url}) : this.decoded(text.runes, url: url);
 
   /// Creates a new source file from [text].
   ///
@@ -317,7 +316,6 @@
   SourceSpan union(SourceSpan other) {
     if (other is! FileSpan) return super.union(other);
 
-    
     _FileSpan span = expand(other);
 
     if (other is _FileSpan) {
@@ -339,7 +337,8 @@
       return super == other && sourceUrl == other.sourceUrl;
     }
 
-    return _start == other._start && _end == other._end &&
+    return _start == other._start &&
+        _end == other._end &&
         sourceUrl == other.sourceUrl;
   }
 
diff --git a/lib/src/location.dart b/lib/src/location.dart
index 2d23db1..cf99319 100644
--- a/lib/src/location.dart
+++ b/lib/src/location.dart
@@ -82,7 +82,8 @@
   }
 
   bool operator ==(other) =>
-      other is SourceLocation && sourceUrl == other.sourceUrl &&
+      other is SourceLocation &&
+      sourceUrl == other.sourceUrl &&
       offset == other.offset;
 
   int get hashCode => sourceUrl.hashCode + offset;
diff --git a/lib/src/location_mixin.dart b/lib/src/location_mixin.dart
index 653c2c4..1e5fc66 100644
--- a/lib/src/location_mixin.dart
+++ b/lib/src/location_mixin.dart
@@ -46,4 +46,3 @@
 
   String toString() => '<$runtimeType: $offset $toolString>';
 }
-
diff --git a/lib/src/span_mixin.dart b/lib/src/span_mixin.dart
index 06e2024..1f7799d 100644
--- a/lib/src/span_mixin.dart
+++ b/lib/src/span_mixin.dart
@@ -113,8 +113,8 @@
     return buffer.toString();
   }
 
-  bool operator ==(other) => other is SourceSpan &&
-      start == other.start && end == other.end;
+  bool operator ==(other) =>
+      other is SourceSpan && start == other.start && end == other.end;
 
   int get hashCode => start.hashCode + (31 * end.hashCode);
 
diff --git a/lib/src/span_with_context.dart b/lib/src/span_with_context.dart
index a02d780..41697a0 100644
--- a/lib/src/span_with_context.dart
+++ b/lib/src/span_with_context.dart
@@ -22,7 +22,7 @@
   /// [text] should start at `start.column` from the beginning of a line in
   /// [context].
   SourceSpanWithContext(
-          SourceLocation start, SourceLocation end, String text, this._context)
+      SourceLocation start, SourceLocation end, String text, this._context)
       : super(start, end, text) {
     if (!context.contains(text)) {
       throw new ArgumentError(
diff --git a/test/file_test.dart b/test/file_test.dart
index 54bc3d3..3f02a8b 100644
--- a/test/file_test.dart
+++ b/test/file_test.dart
@@ -87,7 +87,7 @@
       test("column may not be outside the file", () {
         expect(() => file.getOffset(2, 100), throwsRangeError);
       });
- 
+
       test("column may not be outside the line", () {
         expect(() => file.getOffset(1, 20), throwsRangeError);
       });
@@ -109,8 +109,8 @@
 
     group("for span().union()", () {
       test("source URLs must match", () {
-        var other = new SourceSpan(
-            new SourceLocation(10), new SourceLocation(11), "_");
+        var other =
+            new SourceSpan(new SourceLocation(10), new SourceLocation(11), "_");
 
         expect(() => file.span(9, 10).union(other), throwsArgumentError);
       });
@@ -312,10 +312,8 @@
       });
 
       test("returns a base SourceSpan for a SourceSpan input", () {
-        var other = new SourceSpan(
-            new SourceLocation(0, sourceUrl: "foo.dart"),
-            new SourceLocation(5, sourceUrl: "foo.dart"),
-            "hey, ");
+        var other = new SourceSpan(new SourceLocation(0, sourceUrl: "foo.dart"),
+            new SourceLocation(5, sourceUrl: "foo.dart"), "hey, ");
         var result = span.union(other);
         expect(result, isNot(new isInstanceOf<FileSpan>()));
         expect(result.start, equals(other.start));
diff --git a/test/highlight_test.dart b/test/highlight_test.dart
index 74faed5..08d2e17 100644
--- a/test/highlight_test.dart
+++ b/test/highlight_test.dart
@@ -62,22 +62,19 @@
   });
 
   test("works for a point span in an empty file", () {
-    expect(new SourceFile("").location(0).pointSpan().highlight(),
-        equals("""
+    expect(new SourceFile("").location(0).pointSpan().highlight(), equals("""
 
 ^"""));
   });
 
   test("works for a single-line file without a newline", () {
-    expect(new SourceFile("foo bar").span(0, 7).highlight(),
-        equals("""
+    expect(new SourceFile("foo bar").span(0, 7).highlight(), equals("""
 foo bar
 ^^^^^^^"""));
   });
 
   test("emits tabs for tabs", () {
-    expect(new SourceFile(" \t \t\tfoo bar").span(5, 8).highlight(),
-        equals("""
+    expect(new SourceFile(" \t \t\tfoo bar").span(5, 8).highlight(), equals("""
  \t \t\tfoo bar
  \t \t\t^^^"""));
   });
diff --git a/test/location_test.dart b/test/location_test.dart
index dcd497a..3a32a92 100644
--- a/test/location_test.dart
+++ b/test/location_test.dart
@@ -8,8 +8,8 @@
 main() {
   var location;
   setUp(() {
-    location = new SourceLocation(15,
-        line: 2, column: 6, sourceUrl: "foo.dart");
+    location =
+        new SourceLocation(15, line: 2, column: 6, sourceUrl: "foo.dart");
   });
 
   group('errors', () {
@@ -28,13 +28,13 @@
     });
 
     test('for distance() source URLs must match', () {
-      expect(() => location.distance(new SourceLocation(0)),
-          throwsArgumentError);
+      expect(
+          () => location.distance(new SourceLocation(0)), throwsArgumentError);
     });
 
     test('for compareTo() source URLs must match', () {
-      expect(() => location.compareTo(new SourceLocation(0)),
-          throwsArgumentError);
+      expect(
+          () => location.compareTo(new SourceLocation(0)), throwsArgumentError);
     });
   });
 
@@ -81,7 +81,6 @@
     });
   });
 
-
   group("equality", () {
     test("two locations with the same offset and source are equal", () {
       var other = new SourceLocation(15, sourceUrl: "foo.dart");
diff --git a/test/span_test.dart b/test/span_test.dart
index f980f30..b7637cf 100644
--- a/test/span_test.dart
+++ b/test/span_test.dart
@@ -9,10 +9,8 @@
 main() {
   var span;
   setUp(() {
-    span = new SourceSpan(
-        new SourceLocation(5, sourceUrl: "foo.dart"),
-        new SourceLocation(12, sourceUrl: "foo.dart"),
-        "foo bar");
+    span = new SourceSpan(new SourceLocation(5, sourceUrl: "foo.dart"),
+        new SourceLocation(12, sourceUrl: "foo.dart"), "foo bar");
   });
 
   group('errors', () {
@@ -40,26 +38,28 @@
       test('context must contain text', () {
         var start = new SourceLocation(2);
         var end = new SourceLocation(5);
-        expect(() => new SourceSpanWithContext(
-              start, end, "abc", "--axc--"), throwsArgumentError);
+        expect(() => new SourceSpanWithContext(start, end, "abc", "--axc--"),
+            throwsArgumentError);
       });
 
       test('text starts at start.column in context', () {
         var start = new SourceLocation(3);
         var end = new SourceLocation(5);
-        expect(() => new SourceSpanWithContext(
-              start, end, "abc", "--abc--"), throwsArgumentError);
+        expect(() => new SourceSpanWithContext(start, end, "abc", "--abc--"),
+            throwsArgumentError);
       });
 
       test('text starts at start.column of line in multi-line context', () {
         var start = new SourceLocation(4, line: 55, column: 3);
         var end = new SourceLocation(7, line: 55, column: 6);
-        expect(() => new SourceSpanWithContext(
-              start, end, "abc", "\n--abc--"), throwsArgumentError);
-        expect(() => new SourceSpanWithContext(
-              start, end, "abc", "\n----abc--"), throwsArgumentError);
-        expect(() => new SourceSpanWithContext(
-              start, end, "abc", "\n\n--abc--"), throwsArgumentError);
+        expect(() => new SourceSpanWithContext(start, end, "abc", "\n--abc--"),
+            throwsArgumentError);
+        expect(
+            () => new SourceSpanWithContext(start, end, "abc", "\n----abc--"),
+            throwsArgumentError);
+        expect(
+            () => new SourceSpanWithContext(start, end, "abc", "\n\n--abc--"),
+            throwsArgumentError);
 
         // However, these are valid:
         new SourceSpanWithContext(start, end, "abc", "\n---abc--");
@@ -75,10 +75,14 @@
         new SourceSpanWithContext(start1, end1, "abc", "--abc--abc--\n");
         new SourceSpanWithContext(start2, end2, "abc", "--abc---abc--\n");
         new SourceSpanWithContext(start2, end2, "abc", "---abc--abc--\n");
-        expect(() => new SourceSpanWithContext(
-              start1, end1, "abc", "---abc--abc--\n"), throwsArgumentError);
-        expect(() => new SourceSpanWithContext(
-              start2, end2, "abc", "--abc--abc--\n"), throwsArgumentError);
+        expect(
+            () => new SourceSpanWithContext(
+                start1, end1, "abc", "---abc--abc--\n"),
+            throwsArgumentError);
+        expect(
+            () => new SourceSpanWithContext(
+                start2, end2, "abc", "--abc--abc--\n"),
+            throwsArgumentError);
       });
     });
 
@@ -103,10 +107,8 @@
     });
 
     test('for compareTo() source URLs must match', () {
-      var other = new SourceSpan(
-          new SourceLocation(12, sourceUrl: "bar.dart"),
-          new SourceLocation(13, sourceUrl: "bar.dart"),
-          "_");
+      var other = new SourceSpan(new SourceLocation(12, sourceUrl: "bar.dart"),
+          new SourceLocation(13, sourceUrl: "bar.dart"), "_");
 
       expect(() => span.compareTo(other), throwsArgumentError);
     });
@@ -121,10 +123,8 @@
 
   group("union()", () {
     test("works with a preceding adjacent span", () {
-      var other = new SourceSpan(
-          new SourceLocation(0, sourceUrl: "foo.dart"),
-          new SourceLocation(5, sourceUrl: "foo.dart"),
-          "hey, ");
+      var other = new SourceSpan(new SourceLocation(0, sourceUrl: "foo.dart"),
+          new SourceLocation(5, sourceUrl: "foo.dart"), "hey, ");
 
       var result = span.union(other);
       expect(result.start, equals(other.start));
@@ -133,10 +133,8 @@
     });
 
     test("works with a preceding overlapping span", () {
-      var other = new SourceSpan(
-          new SourceLocation(0, sourceUrl: "foo.dart"),
-          new SourceLocation(8, sourceUrl: "foo.dart"),
-          "hey, foo");
+      var other = new SourceSpan(new SourceLocation(0, sourceUrl: "foo.dart"),
+          new SourceLocation(8, sourceUrl: "foo.dart"), "hey, foo");
 
       var result = span.union(other);
       expect(result.start, equals(other.start));
@@ -145,10 +143,8 @@
     });
 
     test("works with a following adjacent span", () {
-      var other = new SourceSpan(
-          new SourceLocation(12, sourceUrl: "foo.dart"),
-          new SourceLocation(16, sourceUrl: "foo.dart"),
-          " baz");
+      var other = new SourceSpan(new SourceLocation(12, sourceUrl: "foo.dart"),
+          new SourceLocation(16, sourceUrl: "foo.dart"), " baz");
 
       var result = span.union(other);
       expect(result.start, equals(span.start));
@@ -157,10 +153,8 @@
     });
 
     test("works with a following overlapping span", () {
-      var other = new SourceSpan(
-          new SourceLocation(9, sourceUrl: "foo.dart"),
-          new SourceLocation(16, sourceUrl: "foo.dart"),
-          "bar baz");
+      var other = new SourceSpan(new SourceLocation(9, sourceUrl: "foo.dart"),
+          new SourceLocation(16, sourceUrl: "foo.dart"), "bar baz");
 
       var result = span.union(other);
       expect(result.start, equals(span.start));
@@ -169,19 +163,15 @@
     });
 
     test("works with an internal overlapping span", () {
-      var other = new SourceSpan(
-          new SourceLocation(7, sourceUrl: "foo.dart"),
-          new SourceLocation(10, sourceUrl: "foo.dart"),
-          "o b");
+      var other = new SourceSpan(new SourceLocation(7, sourceUrl: "foo.dart"),
+          new SourceLocation(10, sourceUrl: "foo.dart"), "o b");
 
       expect(span.union(other), equals(span));
     });
 
     test("works with an external overlapping span", () {
-      var other = new SourceSpan(
-          new SourceLocation(0, sourceUrl: "foo.dart"),
-          new SourceLocation(16, sourceUrl: "foo.dart"),
-          "hey, foo bar baz");
+      var other = new SourceSpan(new SourceLocation(0, sourceUrl: "foo.dart"),
+          new SourceLocation(16, sourceUrl: "foo.dart"), "hey, foo bar baz");
 
       expect(span.union(other), equals(other));
     });
@@ -206,11 +196,10 @@
     });
 
     test("gracefully handles empty text", () {
-      var span = new SourceSpan(
-          new SourceLocation(5), new SourceLocation(5), "");
+      var span =
+          new SourceSpan(new SourceLocation(5), new SourceLocation(5), "");
 
-      expect(span.message("oh no"),
-          equals("line 1, column 6: oh no"));
+      expect(span.message("oh no"), equals("line 1, column 6: oh no"));
     });
 
     test("doesn't colorize if color is false", () {
@@ -221,8 +210,7 @@
     });
 
     test("colorizes if color is true", () {
-      expect(span.message("oh no", color: true),
-          equals("""
+      expect(span.message("oh no", color: true), equals("""
 line 1, column 6 of foo.dart: oh no
 ${colors.RED}foo bar${colors.NONE}
 ${colors.RED}^^^^^^^${colors.NONE}"""));
@@ -251,20 +239,16 @@
 
   group("compareTo()", () {
     test("sorts by start location first", () {
-      var other = new SourceSpan(
-          new SourceLocation(6, sourceUrl: "foo.dart"),
-          new SourceLocation(14, sourceUrl: "foo.dart"),
-          "oo bar b");
+      var other = new SourceSpan(new SourceLocation(6, sourceUrl: "foo.dart"),
+          new SourceLocation(14, sourceUrl: "foo.dart"), "oo bar b");
 
       expect(span.compareTo(other), lessThan(0));
       expect(other.compareTo(span), greaterThan(0));
     });
 
     test("sorts by length second", () {
-      var other = new SourceSpan(
-          new SourceLocation(5, sourceUrl: "foo.dart"),
-          new SourceLocation(14, sourceUrl: "foo.dart"),
-          "foo bar b");
+      var other = new SourceSpan(new SourceLocation(5, sourceUrl: "foo.dart"),
+          new SourceLocation(14, sourceUrl: "foo.dart"), "foo bar b");
 
       expect(span.compareTo(other), lessThan(0));
       expect(other.compareTo(span), greaterThan(0));
@@ -277,37 +261,29 @@
 
   group("equality", () {
     test("two spans with the same locations are equal", () {
-      var other = new SourceSpan(
-          new SourceLocation(5, sourceUrl: "foo.dart"),
-          new SourceLocation(12, sourceUrl: "foo.dart"),
-          "foo bar");
+      var other = new SourceSpan(new SourceLocation(5, sourceUrl: "foo.dart"),
+          new SourceLocation(12, sourceUrl: "foo.dart"), "foo bar");
 
       expect(span, equals(other));
     });
 
     test("a different start isn't equal", () {
-      var other = new SourceSpan(
-          new SourceLocation(0, sourceUrl: "foo.dart"),
-          new SourceLocation(12, sourceUrl: "foo.dart"),
-          "hey, foo bar");
+      var other = new SourceSpan(new SourceLocation(0, sourceUrl: "foo.dart"),
+          new SourceLocation(12, sourceUrl: "foo.dart"), "hey, foo bar");
 
       expect(span, isNot(equals(other)));
     });
 
     test("a different end isn't equal", () {
-      var other = new SourceSpan(
-          new SourceLocation(5, sourceUrl: "foo.dart"),
-          new SourceLocation(16, sourceUrl: "foo.dart"),
-          "foo bar baz");
+      var other = new SourceSpan(new SourceLocation(5, sourceUrl: "foo.dart"),
+          new SourceLocation(16, sourceUrl: "foo.dart"), "foo bar baz");
 
       expect(span, isNot(equals(other)));
     });
 
     test("a different source URL isn't equal", () {
-      var other = new SourceSpan(
-          new SourceLocation(5, sourceUrl: "bar.dart"),
-          new SourceLocation(12, sourceUrl: "bar.dart"),
-          "foo bar");
+      var other = new SourceSpan(new SourceLocation(5, sourceUrl: "bar.dart"),
+          new SourceLocation(12, sourceUrl: "bar.dart"), "foo bar");
 
       expect(span, isNot(equals(other)));
     });