From 5843f3911f08de73c285eb5267d1ba0143797517 Mon Sep 17 00:00:00 2001
From: DNoved1 <dnoved1@aim.com>
Date: Wed, 2 Mar 2016 00:46:20 -0500
Subject: [PATCH 1/2] Basic code coverage w/ Istanbul for our tests

A few problems need to still be solved:
  * Automatically writing the coverage data to a file. As mentioned in
    one of the comments in test/index.html, this can be done with the
    browser file api which is only supported by chrome at the moment, or
    perhaps by using web sockets to send the data back to the server
    which can then write the file to disk.
  * Source maps - currently istanbul's code coverage is based on the
    transpiled typescript, and so does not accurately reflect the
    original code. It's possible to connect the two mentally, but
    difficult. The remap-istanbul project may be of use here.
  * The method of injecting istanbul into the SystemJS module loader is
    a bit of a hack; we can probably make it a cleaner hack by writing a
    SystemJS plugin which we use specifically for loading our files
    during testing.
---
 .gitignore      |   3 +
 jspm.config.js  | 459 ++++++++++++++++++++++++++++++++++++++++++++++--
 package.json    |  25 ++-
 test/index.html |  54 +++++-
 4 files changed, 514 insertions(+), 27 deletions(-)

diff --git a/.gitignore b/.gitignore
index 625f124..1347e22 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,6 @@ jspm_packages
 typings
 docs
 .vscode/tasks.json
+
+# Istanbul coverage reports
+coverage
diff --git a/jspm.config.js b/jspm.config.js
index e03d174..baed205 100644
--- a/jspm.config.js
+++ b/jspm.config.js
@@ -1,18 +1,45 @@
 SystemJS.config({
-    packageConfigPaths: [
-        "npm:@*/*.json",
-        "npm:*.json",
-        "github:*/*.json"
-    ],
-    transpiler: 'ts',
+    transpiler: "ts",
     typescriptOptions: {
         "tsconfig": true,
         "typeCheck": false,
-        "sourceMap": false
+        "sourceMap": true
     },
+    packages: {
+        "src": {
+            "defaultExtension": "ts",
+            "meta": {
+                "*.ts": {
+                    "loader": "ts"
+                }
+            }
+        },
+        "example": {
+            "map": {
+                "argon": "dist/argon.umd.js"
+            }
+        }
+    },
+    meta: {
+        "istanbul/lib/instrumenter.js": {
+            "format": "global",
+            "globals": {
+                "escodegen": "escodegen",
+                "esprima": "esprima"
+            }
+        }
+    }
+});
 
+SystemJS.config({
+    packageConfigPaths: [
+        "npm:@*/*.json",
+        "npm:*.json",
+        "github:*/*.json"
+    ],
     map: {
         "Cesium": "github:aelatgt/cesium@referenceFrames",
+        "assert": "github:jspm/nodelibs-assert@0.2.0-alpha",
         "aurelia-dependency-injection": "npm:aurelia-dependency-injection@1.0.0-beta.1.1.4",
         "aurelia-logging": "npm:aurelia-logging@1.0.0-beta.1.1.2",
         "aurelia-metadata": "npm:aurelia-metadata@1.0.0-beta.1.1.5",
@@ -20,24 +47,420 @@ SystemJS.config({
         "aurelia-polyfills": "npm:aurelia-polyfills@1.0.0-beta.1.0.0",
         "buffer": "github:jspm/nodelibs-buffer@0.2.0-alpha",
         "chai": "npm:chai@3.5.0",
+        "child_process": "github:jspm/nodelibs-child_process@0.2.0-alpha",
+        "constants": "github:jspm/nodelibs-constants@0.2.0-alpha",
+        "crypto": "github:jspm/nodelibs-crypto@0.2.0-alpha",
         "css": "github:systemjs/plugin-css@0.1.20",
+        "events": "github:jspm/nodelibs-events@0.2.0-alpha",
+        "fs": "github:jspm/nodelibs-fs@0.2.0-alpha",
+        "istanbul": "npm:istanbul@0.4.2",
         "mocha": "npm:mocha@2.4.5",
+        "module": "github:jspm/nodelibs-module@0.2.0-alpha",
+        "os": "github:jspm/nodelibs-os@0.2.0-alpha",
+        "path": "github:jspm/nodelibs-path@0.2.0-alpha",
         "process": "github:jspm/nodelibs-process@0.2.0-alpha",
-        "ts": "github:frankwallis/plugin-typescript@2.6.0"
+        "source-map": "npm:source-map@0.2.0",
+        "stream": "github:jspm/nodelibs-stream@0.2.0-alpha",
+        "string_decoder": "github:jspm/nodelibs-string_decoder@0.2.0-alpha",
+        "ts": "github:frankwallis/plugin-typescript@2.6.0",
+        "tty": "github:jspm/nodelibs-tty@0.2.0-alpha",
+        "uglify-js": "npm:uglify-js@2.6.2",
+        "url": "github:jspm/nodelibs-url@0.2.0-alpha",
+        "util": "github:jspm/nodelibs-util@0.2.0-alpha",
+        "vm": "github:jspm/nodelibs-vm@0.2.0-alpha"
     },
-
     packages: {
-        "src": {
-            "defaultExtension": "ts",
-            "meta": {
-                "*.ts": {
-                "loader": "ts"
-                }
+        "github:jspm/nodelibs-crypto@0.2.0-alpha": {
+            "map": {
+                "crypto-browserify": "npm:crypto-browserify@3.11.0"
             }
         },
-        "example": {
+        "github:jspm/nodelibs-os@0.2.0-alpha": {
             "map": {
-                "argon": "dist/argon.umd.js"
+                "os-browserify": "npm:os-browserify@0.2.0"
+            }
+        },
+        "github:jspm/nodelibs-stream@0.2.0-alpha": {
+            "map": {
+                "stream-browserify": "npm:stream-browserify@2.0.1"
+            }
+        },
+        "github:jspm/nodelibs-string_decoder@0.2.0-alpha": {
+            "map": {
+                "string_decoder-browserify": "npm:string_decoder@0.10.31"
+            }
+        },
+        "github:jspm/nodelibs-url@0.2.0-alpha": {
+            "map": {
+                "url-browserify": "npm:url@0.11.0"
+            }
+        },
+        "npm:align-text@0.1.4": {
+            "map": {
+                "kind-of": "npm:kind-of@3.0.2",
+                "longest": "npm:longest@1.0.1",
+                "repeat-string": "npm:repeat-string@1.5.4"
+            }
+        },
+        "npm:asn1.js@4.5.2": {
+            "map": {
+                "bn.js": "npm:bn.js@4.11.0",
+                "inherits": "npm:inherits@2.0.1",
+                "minimalistic-assert": "npm:minimalistic-assert@1.0.0"
+            }
+        },
+        "npm:browserify-aes@1.0.6": {
+            "map": {
+                "buffer-xor": "npm:buffer-xor@1.0.3",
+                "cipher-base": "npm:cipher-base@1.0.2",
+                "create-hash": "npm:create-hash@1.1.2",
+                "evp_bytestokey": "npm:evp_bytestokey@1.0.0",
+                "inherits": "npm:inherits@2.0.1"
+            }
+        },
+        "npm:browserify-cipher@1.0.0": {
+            "map": {
+                "browserify-aes": "npm:browserify-aes@1.0.6",
+                "browserify-des": "npm:browserify-des@1.0.0",
+                "evp_bytestokey": "npm:evp_bytestokey@1.0.0"
+            }
+        },
+        "npm:browserify-des@1.0.0": {
+            "map": {
+                "cipher-base": "npm:cipher-base@1.0.2",
+                "des.js": "npm:des.js@1.0.0",
+                "inherits": "npm:inherits@2.0.1"
+            }
+        },
+        "npm:browserify-rsa@4.0.1": {
+            "map": {
+                "bn.js": "npm:bn.js@4.11.0",
+                "randombytes": "npm:randombytes@2.0.3"
+            }
+        },
+        "npm:browserify-sign@4.0.0": {
+            "map": {
+                "bn.js": "npm:bn.js@4.11.0",
+                "browserify-rsa": "npm:browserify-rsa@4.0.1",
+                "create-hash": "npm:create-hash@1.1.2",
+                "create-hmac": "npm:create-hmac@1.1.4",
+                "elliptic": "npm:elliptic@6.2.3",
+                "inherits": "npm:inherits@2.0.1",
+                "parse-asn1": "npm:parse-asn1@5.0.0"
+            }
+        },
+        "npm:center-align@0.1.3": {
+            "map": {
+                "align-text": "npm:align-text@0.1.4",
+                "lazy-cache": "npm:lazy-cache@1.0.3"
+            }
+        },
+        "npm:cipher-base@1.0.2": {
+            "map": {
+                "inherits": "npm:inherits@2.0.1"
+            }
+        },
+        "npm:cliui@2.1.0": {
+            "map": {
+                "center-align": "npm:center-align@0.1.3",
+                "right-align": "npm:right-align@0.1.3",
+                "wordwrap": "npm:wordwrap@0.0.2"
+            }
+        },
+        "npm:create-ecdh@4.0.0": {
+            "map": {
+                "bn.js": "npm:bn.js@4.11.0",
+                "elliptic": "npm:elliptic@6.2.3"
+            }
+        },
+        "npm:create-hash@1.1.2": {
+            "map": {
+                "cipher-base": "npm:cipher-base@1.0.2",
+                "inherits": "npm:inherits@2.0.1",
+                "ripemd160": "npm:ripemd160@1.0.1",
+                "sha.js": "npm:sha.js@2.4.5"
+            }
+        },
+        "npm:create-hmac@1.1.4": {
+            "map": {
+                "create-hash": "npm:create-hash@1.1.2",
+                "inherits": "npm:inherits@2.0.1"
+            }
+        },
+        "npm:crypto-browserify@3.11.0": {
+            "map": {
+                "browserify-cipher": "npm:browserify-cipher@1.0.0",
+                "browserify-sign": "npm:browserify-sign@4.0.0",
+                "create-ecdh": "npm:create-ecdh@4.0.0",
+                "create-hash": "npm:create-hash@1.1.2",
+                "create-hmac": "npm:create-hmac@1.1.4",
+                "diffie-hellman": "npm:diffie-hellman@5.0.2",
+                "inherits": "npm:inherits@2.0.1",
+                "pbkdf2": "npm:pbkdf2@3.0.4",
+                "public-encrypt": "npm:public-encrypt@4.0.0",
+                "randombytes": "npm:randombytes@2.0.3"
+            }
+        },
+        "npm:des.js@1.0.0": {
+            "map": {
+                "inherits": "npm:inherits@2.0.1",
+                "minimalistic-assert": "npm:minimalistic-assert@1.0.0"
+            }
+        },
+        "npm:diffie-hellman@5.0.2": {
+            "map": {
+                "bn.js": "npm:bn.js@4.11.0",
+                "miller-rabin": "npm:miller-rabin@4.0.0",
+                "randombytes": "npm:randombytes@2.0.3"
+            }
+        },
+        "npm:elliptic@6.2.3": {
+            "map": {
+                "bn.js": "npm:bn.js@4.11.0",
+                "brorand": "npm:brorand@1.0.5",
+                "hash.js": "npm:hash.js@1.0.3",
+                "inherits": "npm:inherits@2.0.1"
+            }
+        },
+        "npm:evp_bytestokey@1.0.0": {
+            "map": {
+                "create-hash": "npm:create-hash@1.1.2"
+            }
+        },
+        "npm:hash.js@1.0.3": {
+            "map": {
+                "inherits": "npm:inherits@2.0.1"
+            }
+        },
+        "npm:kind-of@3.0.2": {
+            "map": {
+                "is-buffer": "npm:is-buffer@1.1.3"
+            }
+        },
+        "npm:miller-rabin@4.0.0": {
+            "map": {
+                "bn.js": "npm:bn.js@4.11.0",
+                "brorand": "npm:brorand@1.0.5"
+            }
+        },
+        "npm:parse-asn1@5.0.0": {
+            "map": {
+                "asn1.js": "npm:asn1.js@4.5.2",
+                "browserify-aes": "npm:browserify-aes@1.0.6",
+                "create-hash": "npm:create-hash@1.1.2",
+                "evp_bytestokey": "npm:evp_bytestokey@1.0.0",
+                "pbkdf2": "npm:pbkdf2@3.0.4"
+            }
+        },
+        "npm:pbkdf2@3.0.4": {
+            "map": {
+                "create-hmac": "npm:create-hmac@1.1.4"
+            }
+        },
+        "npm:public-encrypt@4.0.0": {
+            "map": {
+                "bn.js": "npm:bn.js@4.11.0",
+                "browserify-rsa": "npm:browserify-rsa@4.0.1",
+                "create-hash": "npm:create-hash@1.1.2",
+                "parse-asn1": "npm:parse-asn1@5.0.0",
+                "randombytes": "npm:randombytes@2.0.3"
+            }
+        },
+        "npm:readable-stream@2.0.6": {
+            "map": {
+                "core-util-is": "npm:core-util-is@1.0.2",
+                "inherits": "npm:inherits@2.0.1",
+                "isarray": "npm:isarray@1.0.0",
+                "process-nextick-args": "npm:process-nextick-args@1.0.6",
+                "string_decoder": "npm:string_decoder@0.10.31",
+                "util-deprecate": "npm:util-deprecate@1.0.2"
+            }
+        },
+        "npm:right-align@0.1.3": {
+            "map": {
+                "align-text": "npm:align-text@0.1.4"
+            }
+        },
+        "npm:sha.js@2.4.5": {
+            "map": {
+                "inherits": "npm:inherits@2.0.1"
+            }
+        },
+        "npm:source-map@0.2.0": {
+            "map": {
+                "amdefine": "npm:amdefine@1.0.0"
+            }
+        },
+        "npm:stream-browserify@2.0.1": {
+            "map": {
+                "inherits": "npm:inherits@2.0.1",
+                "readable-stream": "npm:readable-stream@2.0.6"
+            }
+        },
+        "npm:uglify-js@2.6.2": {
+            "map": {
+                "async": "npm:async@0.2.10",
+                "source-map": "npm:source-map@0.5.3",
+                "uglify-to-browserify": "npm:uglify-to-browserify@1.0.2",
+                "yargs": "npm:yargs@3.10.0"
+            }
+        },
+        "npm:url@0.11.0": {
+            "map": {
+                "punycode": "npm:punycode@1.3.2",
+                "querystring": "npm:querystring@0.2.0"
+            }
+        },
+        "npm:yargs@3.10.0": {
+            "map": {
+                "camelcase": "npm:camelcase@1.2.1",
+                "cliui": "npm:cliui@2.1.0",
+                "decamelize": "npm:decamelize@1.2.0",
+                "window-size": "npm:window-size@0.1.0"
+            }
+        },
+        "npm:argparse@1.0.6": {
+            "map": {
+                "sprintf-js": "npm:sprintf-js@1.0.3"
+            }
+        },
+        "npm:brace-expansion@1.1.3": {
+            "map": {
+                "balanced-match": "npm:balanced-match@0.3.0",
+                "concat-map": "npm:concat-map@0.0.1"
+            }
+        },
+        "npm:escodegen@1.7.1": {
+            "map": {
+                "esprima": "npm:esprima@1.2.5",
+                "estraverse": "npm:estraverse@1.9.3",
+                "esutils": "npm:esutils@2.0.2",
+                "optionator": "npm:optionator@0.5.0"
+            }
+        },
+        "npm:fileset@0.2.1": {
+            "map": {
+                "glob": "npm:glob@5.0.15",
+                "minimatch": "npm:minimatch@2.0.10"
+            }
+        },
+        "npm:glob@5.0.15": {
+            "map": {
+                "inflight": "npm:inflight@1.0.4",
+                "inherits": "npm:inherits@2.0.1",
+                "minimatch": "npm:minimatch@3.0.0",
+                "once": "npm:once@1.3.3",
+                "path-is-absolute": "npm:path-is-absolute@1.0.0"
+            }
+        },
+        "npm:handlebars@4.0.5": {
+            "map": {
+                "async": "npm:async@1.5.2",
+                "optimist": "npm:optimist@0.6.1",
+                "source-map": "npm:source-map@0.4.4"
+            }
+        },
+        "npm:inflight@1.0.4": {
+            "map": {
+                "once": "npm:once@1.3.3",
+                "wrappy": "npm:wrappy@1.0.1"
+            }
+        },
+        "npm:is-absolute@0.1.7": {
+            "map": {
+                "is-relative": "npm:is-relative@0.1.3"
+            }
+        },
+        "npm:istanbul@0.4.2": {
+            "map": {
+                "abbrev": "npm:abbrev@1.0.7",
+                "async": "npm:async@1.5.2",
+                "escodegen": "npm:escodegen@1.7.1",
+                "esprima": "npm:esprima@2.7.2",
+                "fileset": "npm:fileset@0.2.1",
+                "handlebars": "npm:handlebars@4.0.5",
+                "js-yaml": "npm:js-yaml@3.5.4",
+                "mkdirp": "npm:mkdirp@0.5.1",
+                "nopt": "npm:nopt@3.0.6",
+                "once": "npm:once@1.3.3",
+                "resolve": "npm:resolve@1.1.7",
+                "supports-color": "npm:supports-color@3.1.2",
+                "which": "npm:which@1.2.4",
+                "wordwrap": "npm:wordwrap@1.0.0"
+            }
+        },
+        "npm:js-yaml@3.5.4": {
+            "map": {
+                "argparse": "npm:argparse@1.0.6",
+                "esprima": "npm:esprima@2.7.2"
+            }
+        },
+        "npm:levn@0.2.5": {
+            "map": {
+                "prelude-ls": "npm:prelude-ls@1.1.2",
+                "type-check": "npm:type-check@0.3.2"
+            }
+        },
+        "npm:minimatch@2.0.10": {
+            "map": {
+                "brace-expansion": "npm:brace-expansion@1.1.3"
+            }
+        },
+        "npm:minimatch@3.0.0": {
+            "map": {
+                "brace-expansion": "npm:brace-expansion@1.1.3"
+            }
+        },
+        "npm:mkdirp@0.5.1": {
+            "map": {
+                "minimist": "npm:minimist@0.0.8"
+            }
+        },
+        "npm:nopt@3.0.6": {
+            "map": {
+                "abbrev": "npm:abbrev@1.0.7"
+            }
+        },
+        "npm:once@1.3.3": {
+            "map": {
+                "wrappy": "npm:wrappy@1.0.1"
+            }
+        },
+        "npm:optimist@0.6.1": {
+            "map": {
+                "minimist": "npm:minimist@0.0.8",
+                "wordwrap": "npm:wordwrap@0.0.2"
+            }
+        },
+        "npm:optionator@0.5.0": {
+            "map": {
+                "deep-is": "npm:deep-is@0.1.3",
+                "fast-levenshtein": "npm:fast-levenshtein@1.0.7",
+                "levn": "npm:levn@0.2.5",
+                "prelude-ls": "npm:prelude-ls@1.1.2",
+                "type-check": "npm:type-check@0.3.2",
+                "wordwrap": "npm:wordwrap@0.0.2"
+            }
+        },
+        "npm:source-map@0.4.4": {
+            "map": {
+                "amdefine": "npm:amdefine@1.0.0"
+            }
+        },
+        "npm:supports-color@3.1.2": {
+            "map": {
+                "has-flag": "npm:has-flag@1.0.0"
+            }
+        },
+        "npm:type-check@0.3.2": {
+            "map": {
+                "prelude-ls": "npm:prelude-ls@1.1.2"
+            }
+        },
+        "npm:which@1.2.4": {
+            "map": {
+                "is-absolute": "npm:is-absolute@0.1.7",
+                "isexe": "npm:isexe@1.1.2"
             }
         },
         "github:jspm/nodelibs-buffer@0.2.0-alpha": {
@@ -64,7 +487,7 @@ SystemJS.config({
         },
         "npm:buffer@4.5.0": {
             "map": {
-                "base64-js": "npm:base64-js@1.1.0",
+                "base64-js": "npm:base64-js@1.1.1",
                 "ieee754": "npm:ieee754@1.1.6",
                 "isarray": "npm:isarray@1.0.0"
             }
diff --git a/package.json b/package.json
index 5e94bdb..9076d05 100644
--- a/package.json
+++ b/package.json
@@ -15,14 +15,32 @@
     "devDependencies": {
       "chai": "npm:chai@^3.5.0",
       "css": "github:systemjs/plugin-css@^0.1.19",
+      "istanbul": "npm:istanbul@^0.4.2",
       "mocha": "npm:mocha@^2.3.3"
     },
     "peerDependencies": {
+      "assert": "github:jspm/nodelibs-assert@^0.2.0-alpha",
       "aurelia-logging": "npm:aurelia-logging@^1.0.0-beta.1.1.1",
       "aurelia-metadata": "npm:aurelia-metadata@^1.0.0-beta.1.1.3",
       "aurelia-pal": "npm:aurelia-pal@^1.0.0-beta.1.1.1",
       "buffer": "github:jspm/nodelibs-buffer@^0.2.0-alpha",
-      "process": "github:jspm/nodelibs-process@^0.2.0-alpha"
+      "child_process": "github:jspm/nodelibs-child_process@^0.2.0-alpha",
+      "constants": "github:jspm/nodelibs-constants@^0.2.0-alpha",
+      "crypto": "github:jspm/nodelibs-crypto@^0.2.0-alpha",
+      "events": "github:jspm/nodelibs-events@^0.2.0-alpha",
+      "fs": "github:jspm/nodelibs-fs@^0.2.0-alpha",
+      "module": "github:jspm/nodelibs-module@^0.2.0-alpha",
+      "os": "github:jspm/nodelibs-os@^0.2.0-alpha",
+      "path": "github:jspm/nodelibs-path@^0.2.0-alpha",
+      "process": "github:jspm/nodelibs-process@^0.2.0-alpha",
+      "source-map": "npm:source-map@0.2",
+      "stream": "github:jspm/nodelibs-stream@^0.2.0-alpha",
+      "string_decoder": "github:jspm/nodelibs-string_decoder@^0.2.0-alpha",
+      "tty": "github:jspm/nodelibs-tty@^0.2.0-alpha",
+      "uglify-js": "npm:uglify-js@^2.6",
+      "url": "github:jspm/nodelibs-url@^0.2.0-alpha",
+      "util": "github:jspm/nodelibs-util@^0.2.0-alpha",
+      "vm": "github:jspm/nodelibs-vm@^0.2.0-alpha"
     },
     "overrides": {
       "github:frankwallis/plugin-typescript@2.6.0": {
@@ -30,6 +48,11 @@
           "typescript": "npm:typescript@1.9.0-dev.20160226"
         }
       },
+      "npm:inherits@2.0.1": {
+        "ignore": [
+          "test.js"
+        ]
+      },
       "npm:mocha@2.4.5": {
         "browser": "mocha",
         "main": "mocha",
diff --git a/test/index.html b/test/index.html
index 44bad00..2b6f828 100644
--- a/test/index.html
+++ b/test/index.html
@@ -9,13 +9,51 @@
 <body>
     <div id="mocha"></div>
     <script>
-        System.import('mocha').then(function(mocha) {
-            mocha.setup('bdd')
-            System.import('test/test.ts').then(function() {
-                mocha.checkLeaks();
-                mocha.run();
-            })
-        })
+        System.import('istanbul/lib/instrumenter.js').then(function(Instrumenter) {
+
+            // Override the systemjs translate function so that our typescript
+            // is instrumented by istanbul for code coverage.
+            //
+            // TODO: It's probably possible to avoid this by modifying the meta
+            // property of SystemJS for our files to use a custom plugin which
+            // does this.
+            var oldSystemTranslate = System.translate;
+            System.translate = function(load) {
+                var result = oldSystemTranslate.call(this, load);
+
+                var matchResult = /((?:src|test)\/.*\.ts)$/.exec(load.address);
+                if (matchResult !== null) {
+                    var fileName = matchResult[1];
+                    result = result.then(function(code) {
+                        load.source = new Instrumenter({embedSource:true}).instrumentSync(code, fileName);
+                        // TODO: should also update load.sourceMap
+                        return load.source;
+                    });
+                }
+
+                return result;
+            }
+
+            // Setup mocha
+            System.import('mocha').then(function(mocha) {
+                mocha.setup('bdd');
+
+                // Run tests with mocha
+                System.import('test/test.ts!').then(function() {
+                    mocha.checkLeaks();
+                    mocha.run(function() {
+                        // Prompt the user to copy the code coverage data to the
+                        // clipboard.
+                        //
+                        // TODO: it would be better to automatically create the
+                        // file with the browser file api (chrome only) or with web
+                        // sockets (to pass this back to the server where it can
+                        // write the file to disk).
+                        window.prompt("The code coverage data:", JSON.stringify(window.__coverage__));
+                    });
+                });
+            });
+        });
     </script>
 </body>
-</html>
\ No newline at end of file
+</html>

From d61d48d5a762e5a6f7b1bf9e648570ebee59e61c Mon Sep 17 00:00:00 2001
From: DNoved1 <dnoved1@aim.com>
Date: Tue, 8 Mar 2016 01:05:33 -0500
Subject: [PATCH 2/2] Coverage reports now accurately reflect source

Aka the previous coverage reports over the transpiled js (from ts) now
have sourcemaps applied to them so that the coverage reports are now
over ts.

Also made coverage reports be automatically written as the tests are
run.
---
 bin/browser-sync-test.js | 44 ++++++++++++++++++++++++++++++++++++++++
 index.html               |  1 +
 package.json             |  4 ++--
 test/index.html          | 29 +++++++++++++++++---------
 4 files changed, 66 insertions(+), 12 deletions(-)
 create mode 100755 bin/browser-sync-test.js

diff --git a/bin/browser-sync-test.js b/bin/browser-sync-test.js
new file mode 100755
index 0000000..a8efc4b
--- /dev/null
+++ b/bin/browser-sync-test.js
@@ -0,0 +1,44 @@
+#!/usr/bin/env node
+
+var bs = require('browser-sync').create();
+var fs = require('fs');
+var path = require('path');
+var remap = require('remap-istanbul/lib/remap');
+var writeReport = require('remap-istanbul/lib/writeReport');
+
+bs.init({
+    server: {
+        directory: true
+    },
+    startPath: '../index.html',
+    files: '../src/**'
+}, function() {
+    bs.sockets.on('connection', function(client) {
+        client.on('argon:coverage', function(data) {
+            var coverage = data.coverage;
+            var sourceMaps = data.sourceMaps;
+            var sourceJs = data.sourceJs;
+
+            var collector = remap(coverage, {
+                readFile: function(fileName) {
+                    if (sourceJs[fileName]) {
+                        return new Buffer(sourceJs[fileName]);
+                    } else {
+                        throw new Error('No such js file "' + fileName + '".');
+                    }
+                },
+                readJSON: function(fileName) {
+                    if (sourceMaps[fileName]) {
+                        return sourceMaps[fileName];
+                    } else {
+                        throw new Error('No such source map "' + fileName + '".');
+                    }
+                }
+            });
+
+            writeReport(collector, 'html', path.join(__dirname, '../coverage')).then(function() {
+                console.log('Wrote new coverage report to "' + path.join(__dirname, '../coverage/index.html') + '".');
+            });
+        });
+    });
+});
diff --git a/index.html b/index.html
index ff88903..e52b248 100644
--- a/index.html
+++ b/index.html
@@ -8,5 +8,6 @@
   }
 </style>
 <h3><a href="/test/index.html" onclick="window.open('/test/index.html', 'Test Runner', 'width=550, height=800'); return false;">Test Runner</a></h3>
+<h3><a href="/coverage/index.html">Code Coverage</a></h3>
 <h3><a href="/">Documentation</a></h3>
 <h3><a href="/example/">Example</a></h3>
diff --git a/package.json b/package.json
index 9076d05..9c1a54b 100644
--- a/package.json
+++ b/package.json
@@ -107,6 +107,7 @@
   "devDependencies": {
     "browser-sync": "^2.11.0",
     "jspm": "^0.17.0-beta.13",
+    "remap-istanbul": "^0.5.1",
     "tsconfig-glob": "^0.2.1",
     "typedoc": "^0.3.12",
     "typescript": "^1.9.0-dev.20160303",
@@ -116,8 +117,7 @@
     "tsconfig": "tsconfig .",
     "format": "tsfmt -r",
     "build": "tsconfig . && tsfmt -r && tsc && jspm build src/argon.ts dist/argon.umd.js --format umd --global-name Argon --skip-source-maps",
-    "browser-sync": "browser-sync  start --server --directory --startPath \"index.html\" --files \"src/**\"",
-    "test": "npm run browser-sync",
+    "test": "node bin/browser-sync-test.js",
     "typedoc": "typedoc --out docs --gaID UA-63191442-2 --name argon.js --readme README.md --target ES5 --module commonjs --experimentalDecorators --excludeNotExported --excludeExternals --ignoreCompilerErrors -p src src/argon.ts src/camera.ts src/config.ts src/context.ts src/focus.ts src/mode.ts src/device.ts src/reality.ts src/viewport.ts src/session.ts src/timer.ts src/utils.ts src/vuforia.ts typings/browser.d.ts jspm_packages/npm/aurelia-dependency-injection@1.0.0-beta.1.1.4/aurelia-dependency-injection.d.ts jspm_packages/npm/aurelia-logging@1.0.0-beta.1.1.2/aurelia-logging.d.ts jspm_packages/npm/aurelia-metadata@1.0.0-beta.1.1.5/aurelia-metadata.d.ts jspm_packages/npm/aurelia-pal@1.0.0-beta.1.1.1/aurelia-pal.d.ts jspm_packages/npm/aurelia-polyfills@1.0.0-beta.1.0.0/aurelia-polyfills.d.ts"
   }
 }
diff --git a/test/index.html b/test/index.html
index 2b6f828..23145a7 100644
--- a/test/index.html
+++ b/test/index.html
@@ -10,6 +10,10 @@
     <div id="mocha"></div>
     <script>
         System.import('istanbul/lib/instrumenter.js').then(function(Instrumenter) {
+            // A map from argon source file names to their source maps
+            var sourceMaps = {};
+            // A map from argon source file names to their transpiled js
+            var sourceJs = {};
 
             // Override the systemjs translate function so that our typescript
             // is instrumented by istanbul for code coverage.
@@ -21,11 +25,19 @@
             System.translate = function(load) {
                 var result = oldSystemTranslate.call(this, load);
 
-                var matchResult = /((?:src|test)\/.*\.ts)$/.exec(load.address);
+                var matchResult = /((?:src|test)\/.*)\.ts$/.exec(load.address);
                 if (matchResult !== null) {
                     var fileName = matchResult[1];
+                    var baseFileName = fileName.slice(fileName.lastIndexOf('/') + 1)
+
                     result = result.then(function(code) {
-                        load.source = new Instrumenter({embedSource:true}).instrumentSync(code, fileName);
+                        var codeWithSourceMapComment = '//# sourceMappingURL=' + baseFileName + '.js.map\n' + code;
+
+                        sourceJs[fileName + '.js'] = codeWithSourceMapComment;
+                        sourceMaps[fileName + '.js.map'] = load.metadata.sourceMap;
+                        sourceMaps[fileName + '.js.map'].sources = [baseFileName + '.ts'];
+
+                        load.source = new Instrumenter().instrumentSync(codeWithSourceMapComment, fileName + '.js');
                         // TODO: should also update load.sourceMap
                         return load.source;
                     });
@@ -42,14 +54,11 @@
                 System.import('test/test.ts!').then(function() {
                     mocha.checkLeaks();
                     mocha.run(function() {
-                        // Prompt the user to copy the code coverage data to the
-                        // clipboard.
-                        //
-                        // TODO: it would be better to automatically create the
-                        // file with the browser file api (chrome only) or with web
-                        // sockets (to pass this back to the server where it can
-                        // write the file to disk).
-                        window.prompt("The code coverage data:", JSON.stringify(window.__coverage__));
+                        window.___browserSync___.socket.emit('argon:coverage', {
+                            coverage: window.__coverage__,
+                            sourceMaps: sourceMaps,
+                            sourceJs: sourceJs
+                        });
                     });
                 });
             });