Support operating system selectors under Node.js (#747)

Closes #742
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1c34aeb..314b4c1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,10 +1,15 @@
 ## 0.12.30
 
+* Platform selectors for operating systems now work for Node.js tests
+  ([#742][]).
+
 * `fail()` is now typed to return `Null`, so it can be used in the same places
   as a raw `throw`.
 
 * Run Chrome in headless mode unless debugging is enabled.
 
+[#742]: https://github.com/dart-lang/test/issues/742
+
 ## 0.12.29+1
 
 * Fix strong mode runtime cast failures.
diff --git a/README.md b/README.md
index 94cdb33..733595c 100644
--- a/README.md
+++ b/README.md
@@ -233,14 +233,14 @@
 * `blink`: Whether the test is running in a browser that uses the Blink
   rendering engine.
 
-* `windows`: Whether the test is running on Windows. If `vm` is false, this will
-  be `false` as well.
+* `windows`: Whether the test is running on Windows. This can only be `true` if
+  either `vm` or `node` is true.
 
-* `mac-os`: Whether the test is running on Mac OS. If `vm` is false, this will
-  be `false` as well.
+* `mac-os`: Whether the test is running on Mac OS. This can only be `true` if
+  either `vm` or `node` is true.
 
-* `linux`: Whether the test is running on Linux. If `vm` is false, this will be
-  `false` as well.
+* `linux`: Whether the test is running on Linux. This can only be `true` if
+  either `vm` or `node` is true.
 
 * `android`: Whether the test is running on Android. If `vm` is false, this will
   be `false` as well, which means that this *won't* be true if the test is
diff --git a/lib/src/runner/plugin/platform_helpers.dart b/lib/src/runner/plugin/platform_helpers.dart
index e7dd55c..dba0f5d 100644
--- a/lib/src/runner/plugin/platform_helpers.dart
+++ b/lib/src/runner/plugin/platform_helpers.dart
@@ -50,7 +50,9 @@
   suiteChannel.sink.add({
     'platform': platform.serialize(),
     'metadata': suiteConfig.metadata.serialize(),
-    'os': platform == TestPlatform.vm ? currentOS.identifier : null,
+    'os': (platform == TestPlatform.vm || platform == TestPlatform.nodeJS)
+        ? currentOS.identifier
+        : null,
     'asciiGlyphs': Platform.isWindows,
     'path': path,
     'collectTraces': Configuration.current.reporter == 'json',
diff --git a/pubspec.yaml b/pubspec.yaml
index a7dc7a6..23b2552 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: test
-version: 0.12.30-dev
+version: 0.12.30
 author: Dart Team <misc@dartlang.org>
 description: A library for writing dart unit tests.
 homepage: https://github.com/dart-lang/test
diff --git a/test/runner/node/runner_test.dart b/test/runner/node/runner_test.dart
index 018d47b..059ac04 100644
--- a/test/runner/node/runner_test.dart
+++ b/test/runner/node/runner_test.dart
@@ -8,6 +8,7 @@
 import 'package:test_descriptor/test_descriptor.dart' as d;
 
 import 'package:test/test.dart';
+import 'package:test/src/util/io.dart';
 
 import '../../io.dart';
 
@@ -277,6 +278,39 @@
       expect(test.stdout, emitsThrough(contains("+1: All tests passed!")));
       await test.shouldExit(0);
     });
+
+    test("matches the current OS", () async {
+      await d.file("test.dart", '''
+        import 'dart:async';
+
+        import 'package:test/test.dart';
+
+        void main() {
+          test("fail", () => throw 'oh no',
+              onPlatform: {"${currentOS.identifier}": new Skip()});
+        }
+      ''').create();
+
+      var test = await runTest(["-p", "node", "test.dart"]);
+      expect(test.stdout, emitsThrough(contains("+0 ~1: All tests skipped.")));
+      await test.shouldExit(0);
+    });
+
+    test("doesn't match a different OS", () async {
+      await d.file("test.dart", '''
+        import 'dart:async';
+
+        import 'package:test/test.dart';
+
+        void main() {
+          test("success", () {}, onPlatform: {"${otherOS}": new Skip()});
+        }
+      ''').create();
+
+      var test = await runTest(["-p", "node", "test.dart"]);
+      expect(test.stdout, emitsThrough(contains("+1: All tests passed!")));
+      await test.shouldExit(0);
+    });
   });
 
   group("with an @OnPlatform annotation", () {