Add DDC test coverage, enable skipped tests. (#83)

* Add DDC test coverage, enable tests.

* chmod +x.

* Fix crash.

* Dartfmt.
diff --git a/.gitignore b/.gitignore
index 25a1df3..98d6d21 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@
 .DS_Store
 .idea
 .pub/
+.dart_tool/
 .settings/
 build/
 packages
diff --git a/.travis.yml b/.travis.yml
index a31bd64..b4d1316 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,17 +1,54 @@
+
 language: dart
 
-dart:
-  - dev
+# Gives more resources on Travis (8GB Ram, 2 CPUs).
+# Do not remove without verifying w/ Travis.
+sudo: required
+addons:
+  chrome: stable
 
-dart_task:
-  - test: --platform vm
-  - test: --platform firefox -j 1
-  - dartanalyzer
-  - dartfmt
+# Build stages: https://docs.travis-ci.com/user/build-stages/.
+stages:
+  - presubmit
+  - build
+  - testing
 
+# 1. Run dartfmt, dartanalyzer, pub run test (VM).
+# 2. Then run a build.
+# 3. Then run tests compiled via dartdevc and dart2js.
+jobs:
+  include:
+    - stage: presubmit
+      script: ./tool/travis.sh dartfmt
+      dart: dev
+    - stage: presubmit
+      script: ./tool/travis.sh dartanalyzer
+      dart: dev
+    - stage: build
+      script: ./tool/travis.sh dartdevc_build
+      dart: dev
+    - stage: testing
+      script: ./tool/travis.sh vm_test
+      dart: dev
+    - stage: testing
+      script: ./tool/travis.sh dartdevc_test
+      dart: dev
+    - stage: testing
+      script: ./tool/travis.sh dart2js_test
+      dart: dev
+
+# Only building master means that we don't run two builds for each pull request.
 branches:
   only: [master]
 
+# Incremental pub cache and builds.
 cache:
   directories:
     - $HOME/.pub-cache
+    - .dart_tool
+
+# Necessary for Chrome and Firefox to run
+before_install:
+ - export DISPLAY=:99.0
+ - sh -e /etc/init.d/xvfb start
+ - "t=0; until (xdpyinfo -display :99 &> /dev/null || test $t -gt 10); do sleep 1; let t=$t+1; done"
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 6f5e0ea..e88abc6 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -20,10 +20,19 @@
 ### Code reviews
 All submissions, including submissions by project members, require review.
 
+### Presubmit testing
+* All code must pass analysis by the `dartanalyzer` (`dartanalyzer --fatal-warnings .`)
+* All code must be formatted by `dartfmt` (`dartfmt -w .`)
+  * _NOTE_: We currently require formatting by the `dev` channel SDK.
+* All code must pass unit tests for the VM, Dart2JS, and DartDevC (`pub run build_runner test`).
+  * _NOTE_: We currently use `build_runner` for compilation with DartDevC. It's
+    possible to run only Dart2JS and the VM without it using `pub run test`
+    directly.
+
 ### File headers
 All files in the project must start with the following header.
 
-    // Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+    // Copyright (c) 2018, 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.
 
diff --git a/dart_test.yaml b/dart_test.yaml
new file mode 100644
index 0000000..d2b9d1d
--- /dev/null
+++ b/dart_test.yaml
@@ -0,0 +1,22 @@
+presets:
+  # When run with -P travis, we have different settings/options.
+  #
+  # 1: We don't use Chrome --headless:
+  # 2: We use --reporter expanded
+  # 3: We skip anything tagged "fails-on-travis".
+  travis:
+    # TODO(https://github.com/dart-lang/test/issues/772)
+    override_platforms:
+      chrome:
+        settings:
+          headless: false
+
+    # Don't run any tests that are tagged ["fails-on-travis"].
+    exclude_tags: "fails-on-travis"
+
+    # https://github.com/dart-lang/test/blob/master/doc/configuration.md#reporter
+    reporter: expanded
+
+platforms:
+  - chrome
+  - vm
diff --git a/pubspec.yaml b/pubspec.yaml
index 972f6c6..6384585 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -9,4 +9,7 @@
   sdk: '>=2.0.0-dev.22.0 <2.0.0'
 
 dev_dependencies:
-  test: '^0.12.0'
+  build_runner: ^0.7.11
+  build_test: ^0.10.0
+  build_web_compilers: ^0.3.1
+  test: ^0.12.0
diff --git a/test/queue_list_test.dart b/test/queue_list_test.dart
index 9e6d199..eeb9a46 100644
--- a/test/queue_list_test.dart
+++ b/test/queue_list_test.dart
@@ -262,7 +262,7 @@
 
 /// Returns a queue whose internal tail has a lower index than its head.
 QueueList withInternalGap() {
-  var queue = new QueueList.from([null, null, null, null, 1, 2, 3, 4]);
+  var queue = new QueueList.from(<dynamic>[null, null, null, null, 1, 2, 3, 4]);
   for (var i = 0; i < 4; i++) {
     queue.removeFirst();
   }
diff --git a/test/typed_wrapper/iterable_test.dart b/test/typed_wrapper/iterable_test.dart
index 5de9651..a7662d1 100644
--- a/test/typed_wrapper/iterable_test.dart
+++ b/test/typed_wrapper/iterable_test.dart
@@ -350,5 +350,5 @@
         expect(wrapper.toString(), equals("(foo, bar, baz)"));
       });
     });
-  }, skip: "Re-enable this when test can run DDC (test#414).");
+  }, skip: isDart2 ? false : 'Requires a Dart2 runtime');
 }
diff --git a/test/typed_wrapper/list_test.dart b/test/typed_wrapper/list_test.dart
index 7876dbe..fcb784a 100644
--- a/test/typed_wrapper/list_test.dart
+++ b/test/typed_wrapper/list_test.dart
@@ -417,5 +417,5 @@
         expect(inner, equals(["bar", "baz", "foo"]));
       });
     });
-  }, skip: "Re-enable this when test can run DDC (test#414).");
+  }, skip: isDart2 ? false : 'Requires a Dart2 runtime');
 }
diff --git a/test/typed_wrapper/map_test.dart b/test/typed_wrapper/map_test.dart
index 75078bd..96ccf17 100644
--- a/test/typed_wrapper/map_test.dart
+++ b/test/typed_wrapper/map_test.dart
@@ -223,7 +223,7 @@
             ]));
       });
     });
-  }, skip: "Re-enable this when test can run DDC (test#414).");
+  }, skip: isDart2 ? false : 'Requires a Dart2 runtime');
 
   group("with invalid value types", () {
     Map inner;
@@ -323,5 +323,5 @@
             ]));
       });
     });
-  }, skip: "Re-enable this when test can run DDC (test#414).");
+  }, skip: isDart2 ? false : 'Requires a Dart2 runtime');
 }
diff --git a/test/typed_wrapper/queue_test.dart b/test/typed_wrapper/queue_test.dart
index e9ffb3a..0a716fe 100644
--- a/test/typed_wrapper/queue_test.dart
+++ b/test/typed_wrapper/queue_test.dart
@@ -137,5 +137,5 @@
         expect(wrapper, isEmpty);
       });
     });
-  }, skip: "Re-enable this when test can run DDC (test#414).");
+  }, skip: isDart2 ? false : 'Requires a Dart2 runtime');
 }
diff --git a/test/typed_wrapper/set_test.dart b/test/typed_wrapper/set_test.dart
index d7eed5f..37e3cd3 100644
--- a/test/typed_wrapper/set_test.dart
+++ b/test/typed_wrapper/set_test.dart
@@ -169,5 +169,5 @@
         expect(inner, unorderedEquals(["foo", "baz"]));
       });
     });
-  }, skip: "Re-enable this when test can run DDC (test#414).");
+  }, skip: isDart2 ? false : 'Requires a Dart2 runtime');
 }
diff --git a/test/utils.dart b/test/utils.dart
index d8ab082..73926a3 100644
--- a/test/utils.dart
+++ b/test/utils.dart
@@ -5,3 +5,13 @@
 import "package:test/test.dart";
 
 final Matcher throwsCastError = throwsA(new isInstanceOf<CastError>());
+
+/// A hack to determine whether we are running in a Dart 2 runtime.
+final bool isDart2 = _isTypeArgString('');
+bool _isTypeArgString<T>(T arg) {
+  try {
+    return T == String;
+  } catch (_) {
+    return false;
+  }
+}
diff --git a/tool/travis.sh b/tool/travis.sh
new file mode 100755
index 0000000..0e584b9
--- /dev/null
+++ b/tool/travis.sh
@@ -0,0 +1,65 @@
+# Copyright 2018 the Dart project authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+#!/bin/bash
+
+if [ "$#" == "0" ]; then
+  echo -e '\033[31mAt least one task argument must be provided!\033[0m'
+  exit 1
+fi
+
+EXIT_CODE=0
+
+while (( "$#" )); do
+  TASK=$1
+  case $TASK in
+  dartfmt) echo
+    echo -e '\033[1mTASK: dartfmt\033[22m'
+    echo -e 'dartfmt -n --set-exit-if-changed .'
+    dartfmt -n --set-exit-if-changed . || EXIT_CODE=$?
+    ;;
+  dartanalyzer) echo
+    echo -e '\033[1mTASK: dartanalyzer\033[22m'
+    echo -e 'dartanalyzer --fatal-warnings .'
+    dartanalyzer --fatal-warnings . || EXIT_CODE=$?
+    ;;
+  vm_test) echo
+    echo -e '\033[1mTASK: vm_test\033[22m'
+    echo -e 'pub run test -P travis -p vm -x requires-dart2'
+    pub run test -p vm || EXIT_CODE=$?
+    ;;
+  dartdevc_build) echo
+    echo -e '\033[1mTASK: build\033[22m'
+    echo -e 'pub run build_runner build --fail-on-severe'
+    pub run build_runner build --fail-on-severe || EXIT_CODE=$?
+    ;;
+  dartdevc_test) echo
+    echo -e '\033[1mTASK: dartdevc_test\033[22m'
+    echo -e 'pub run build_runner test -- -P travis -p chrome'
+    pub run build_runner test -- -p chrome || EXIT_CODE=$?
+    ;;
+  dart2js_test) echo
+    echo -e '\033[1mTASK: dart2js_test\033[22m'
+    echo -e 'pub run test -P travis -p chrome -x requires-dart2'
+    pub run test -p chrome || EXIT_CODE=$?
+    ;;
+  *) echo -e "\033[31mNot expecting TASK '${TASK}'. Error!\033[0m"
+    EXIT_CODE=1
+    ;;
+  esac
+
+  shift
+done
+
+exit $EXIT_CODE