├── .gitignore ├── .npmignore ├── .travis.yml ├── LICENSE ├── README.md ├── docs └── images │ ├── junit_output.jpg │ └── spec_output.jpg ├── index.js ├── package-lock.json ├── package.json └── test ├── helpers ├── mock-runner.js └── mock-test.js └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | test/ouput/ -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | test/ 2 | .travis.yml -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "node" 4 | - "lts/*" 5 | matrix: 6 | fast_finish: true 7 | sudo: false 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Glenn Morton 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mocha-circleci-reporter [![Build Status](https://travis-ci.org/sandcastle/mocha-circleci-reporter.svg)](https://travis-ci.org/sandcastle/mocha-circleci-reporter) 2 | 3 | > A Mocha reporter specifically for [Circle CI](https://circleci.com/). 4 | 5 | 6 | ## Getting Started 7 | 8 | Install the reporter as a development dependency: 9 | 10 | ```sh 11 | npm install mocha --save-dev 12 | npm install mocha-circleci-reporter --save-dev 13 | ``` 14 | 15 | Update your `package.json` to use the reporter when running Mocha: 16 | 17 | ```json 18 | { 19 | "name": "my-package", 20 | "version": "0.0.1", 21 | "scripts": { 22 | "test": "node_modules/.bin/mocha --reporter mocha-circleci-reporter test/*.js" 23 | } 24 | } 25 | ``` 26 | 27 | [mocha-junit-reporter](https://github.com/michaelleeallen/mocha-junit-reporter#usage) will output 28 | results to `test-results.xml` by default. CircleCI needs the results in the `$CIRCLE_TEST_REPORTS` directory. 29 | 30 | Either update your `circle.yml` to copy over the `test-results.xml: 31 | 32 | ```yaml 33 | test: 34 | override: 35 | - npm run test 36 | - if [[ -e test-results.xml ]]; then cp test-results.xml $CIRCLE_TEST_REPORTS/test-results.xml; fi 37 | ``` 38 | 39 | or set the `$MOCHA_FILE`: 40 | 41 | ```yaml 42 | machine: 43 | environment: 44 | MOCHA_FILE: "$CIRCLE_TEST_REPORTS/test-results.xml" 45 | ``` 46 | 47 | ## Background 48 | 49 | ### Why another reporter? 50 | 51 | As of Mocha 2.x, its not possible to use multple reporters out of the box. 52 | This complicates things when dealing with CI systems like Circle CI that 53 | require a format such as [jUnit XML](https://windyroad.com.au/dl/Open%20Source/JUnit.xsd) 54 | as a lot of the goodness that is written to console when running the default 55 | reporter (`Spec`). 56 | 57 | To overcome this, we combine the output of both the 58 | builtin `Spec` and `mocha-junit-report` reporters. 59 | 60 | Example spec output: 61 | 62 | ![spec_output.jpg](docs/images/spec_output.jpg) 63 | 64 | Example jUnit output: 65 | 66 | ![spec_output.jpg](docs/images/junit_output.jpg) 67 | 68 | 69 | ### Mocha 3.x 70 | 71 | There is work underway in Mocha 3.x to move to a plugin architecture that would 72 | make multiple reporters dead simple, until then I hope this simplifies things. 73 | 74 | https://github.com/mochajs/mocha/issues/1457 75 | 76 | -------------------------------------------------------------------------------- /docs/images/junit_output.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sandcastle/mocha-circleci-reporter/961ded9df1348c986d8ee5038a3de346b0eec5e6/docs/images/junit_output.jpg -------------------------------------------------------------------------------- /docs/images/spec_output.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sandcastle/mocha-circleci-reporter/961ded9df1348c986d8ee5038a3de346b0eec5e6/docs/images/spec_output.jpg -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use-strict'; 2 | 3 | var Spec = require('mocha').reporters.Spec; 4 | var JUnit = require('mocha-junit-reporter'); 5 | 6 | 7 | function MochaCircleCIReporter(runner, options) { 8 | new Spec(runner, options); 9 | new JUnit(runner, options); 10 | } 11 | 12 | module.exports = MochaCircleCIReporter; 13 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mocha-circleci-reporter", 3 | "version": "0.0.2", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "ansi-regex": { 8 | "version": "3.0.0", 9 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 10 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" 11 | }, 12 | "assert": { 13 | "version": "1.4.1", 14 | "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", 15 | "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", 16 | "dev": true, 17 | "requires": { 18 | "util": "0.10.3" 19 | } 20 | }, 21 | "balanced-match": { 22 | "version": "1.0.0", 23 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 24 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 25 | }, 26 | "brace-expansion": { 27 | "version": "1.1.11", 28 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 29 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 30 | "requires": { 31 | "balanced-match": "^1.0.0", 32 | "concat-map": "0.0.1" 33 | } 34 | }, 35 | "browser-stdout": { 36 | "version": "1.3.1", 37 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 38 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" 39 | }, 40 | "charenc": { 41 | "version": "0.0.2", 42 | "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", 43 | "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=" 44 | }, 45 | "commander": { 46 | "version": "2.11.0", 47 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", 48 | "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==" 49 | }, 50 | "concat-map": { 51 | "version": "0.0.1", 52 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 53 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 54 | }, 55 | "crypt": { 56 | "version": "0.0.2", 57 | "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", 58 | "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=" 59 | }, 60 | "debug": { 61 | "version": "2.6.9", 62 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 63 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 64 | "requires": { 65 | "ms": "2.0.0" 66 | } 67 | }, 68 | "diff": { 69 | "version": "3.5.0", 70 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", 71 | "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" 72 | }, 73 | "escape-string-regexp": { 74 | "version": "1.0.5", 75 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 76 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" 77 | }, 78 | "fs.realpath": { 79 | "version": "1.0.0", 80 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 81 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 82 | }, 83 | "glob": { 84 | "version": "7.1.2", 85 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", 86 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 87 | "requires": { 88 | "fs.realpath": "^1.0.0", 89 | "inflight": "^1.0.4", 90 | "inherits": "2", 91 | "minimatch": "^3.0.4", 92 | "once": "^1.3.0", 93 | "path-is-absolute": "^1.0.0" 94 | } 95 | }, 96 | "growl": { 97 | "version": "1.10.3", 98 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", 99 | "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==" 100 | }, 101 | "has-flag": { 102 | "version": "2.0.0", 103 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", 104 | "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" 105 | }, 106 | "he": { 107 | "version": "1.1.1", 108 | "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", 109 | "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=" 110 | }, 111 | "inflight": { 112 | "version": "1.0.6", 113 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 114 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 115 | "requires": { 116 | "once": "^1.3.0", 117 | "wrappy": "1" 118 | } 119 | }, 120 | "inherits": { 121 | "version": "2.0.3", 122 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 123 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 124 | }, 125 | "is-buffer": { 126 | "version": "1.1.6", 127 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", 128 | "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" 129 | }, 130 | "md5": { 131 | "version": "2.2.1", 132 | "resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz", 133 | "integrity": "sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=", 134 | "requires": { 135 | "charenc": "~0.0.1", 136 | "crypt": "~0.0.1", 137 | "is-buffer": "~1.1.1" 138 | } 139 | }, 140 | "minimatch": { 141 | "version": "3.0.4", 142 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 143 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 144 | "requires": { 145 | "brace-expansion": "^1.1.7" 146 | } 147 | }, 148 | "minimist": { 149 | "version": "0.0.8", 150 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 151 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" 152 | }, 153 | "mkdirp": { 154 | "version": "0.5.1", 155 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 156 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 157 | "requires": { 158 | "minimist": "0.0.8" 159 | } 160 | }, 161 | "mocha": { 162 | "version": "5.1.1", 163 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.1.1.tgz", 164 | "integrity": "sha512-kKKs/H1KrMMQIEsWNxGmb4/BGsmj0dkeyotEvbrAuQ01FcWRLssUNXCEUZk6SZtyJBi6EE7SL0zDDtItw1rGhw==", 165 | "requires": { 166 | "browser-stdout": "1.3.1", 167 | "commander": "2.11.0", 168 | "debug": "3.1.0", 169 | "diff": "3.5.0", 170 | "escape-string-regexp": "1.0.5", 171 | "glob": "7.1.2", 172 | "growl": "1.10.3", 173 | "he": "1.1.1", 174 | "minimatch": "3.0.4", 175 | "mkdirp": "0.5.1", 176 | "supports-color": "4.4.0" 177 | }, 178 | "dependencies": { 179 | "debug": { 180 | "version": "3.1.0", 181 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 182 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 183 | "requires": { 184 | "ms": "2.0.0" 185 | } 186 | } 187 | } 188 | }, 189 | "mocha-junit-reporter": { 190 | "version": "1.17.0", 191 | "resolved": "https://registry.npmjs.org/mocha-junit-reporter/-/mocha-junit-reporter-1.17.0.tgz", 192 | "integrity": "sha1-LlFJ7UD8XS48px5C21qx/snG2Fw=", 193 | "requires": { 194 | "debug": "^2.2.0", 195 | "md5": "^2.1.0", 196 | "mkdirp": "~0.5.1", 197 | "strip-ansi": "^4.0.0", 198 | "xml": "^1.0.0" 199 | } 200 | }, 201 | "ms": { 202 | "version": "2.0.0", 203 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 204 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 205 | }, 206 | "once": { 207 | "version": "1.4.0", 208 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 209 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 210 | "requires": { 211 | "wrappy": "1" 212 | } 213 | }, 214 | "path-is-absolute": { 215 | "version": "1.0.1", 216 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 217 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 218 | }, 219 | "strip-ansi": { 220 | "version": "4.0.0", 221 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 222 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 223 | "requires": { 224 | "ansi-regex": "^3.0.0" 225 | } 226 | }, 227 | "supports-color": { 228 | "version": "4.4.0", 229 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", 230 | "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", 231 | "requires": { 232 | "has-flag": "^2.0.0" 233 | } 234 | }, 235 | "test-console": { 236 | "version": "1.1.0", 237 | "resolved": "https://registry.npmjs.org/test-console/-/test-console-1.1.0.tgz", 238 | "integrity": "sha512-pntCc+DnxNVZxNIul3NjThWaLvIrp9GNHRMrriyFWFtq10LpbHGsagu7riq7UIZn79f9aXnKI7YgyMvf8dcKsg==", 239 | "dev": true 240 | }, 241 | "util": { 242 | "version": "0.10.3", 243 | "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", 244 | "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", 245 | "dev": true, 246 | "requires": { 247 | "inherits": "2.0.1" 248 | }, 249 | "dependencies": { 250 | "inherits": { 251 | "version": "2.0.1", 252 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", 253 | "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", 254 | "dev": true 255 | } 256 | } 257 | }, 258 | "wrappy": { 259 | "version": "1.0.2", 260 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 261 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 262 | }, 263 | "xml": { 264 | "version": "1.0.1", 265 | "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", 266 | "integrity": "sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=" 267 | } 268 | } 269 | } 270 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mocha-circleci-reporter", 3 | "version": "0.0.3", 4 | "description": "A mocha reporter that supports Circle CI, via a combined jUnit and Spec reporter output.", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "node_modules/.bin/mocha --harmony test/index.js" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/sandcastle/mocha-circleci-reporter.git" 12 | }, 13 | "keywords": [ 14 | "mocha", 15 | "reporter", 16 | "ci", 17 | "circle", 18 | "ci", 19 | "build", 20 | "js", 21 | "javascript" 22 | ], 23 | "author": "Glenn Morton", 24 | "license": "MIT", 25 | "bugs": { 26 | "url": "https://github.com/sandcastle/mocha-circleci-reporter/issues" 27 | }, 28 | "homepage": "https://github.com/sandcastle/mocha-circleci-reporter#readme", 29 | "devDependencies": { 30 | "assert": "^1.3.0", 31 | "test-console": "^1.0.0" 32 | }, 33 | "dependencies": { 34 | "mocha": "^5.1.1", 35 | "mocha-junit-reporter": "^1.17.0" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /test/helpers/mock-runner.js: -------------------------------------------------------------------------------- 1 | "use strict" 2 | 3 | var EventEmitter = require("events").EventEmitter 4 | var util = require("util") 5 | 6 | // mock test runner 7 | function Runner() { 8 | Runner.super_.call(this) 9 | } 10 | 11 | util.inherits(Runner, EventEmitter) 12 | 13 | Runner.prototype.start = function() { 14 | this.emit("start") 15 | } 16 | 17 | Runner.prototype.end = function() { 18 | this.emit("end") 19 | } 20 | 21 | Runner.prototype.startSuite = function(suite) { 22 | suite.suites = suite.suites || [] 23 | suite.tests = suite.tests || [] 24 | 25 | if (this._currentSuite) { 26 | suite.parent = this._currentSuite 27 | } 28 | 29 | this._currentSuite = suite 30 | this.emit("suite", suite) 31 | } 32 | 33 | Runner.prototype.pass = function(test) { 34 | this.emit("pass", test) 35 | this.endTest() 36 | } 37 | 38 | Runner.prototype.fail = function(test, reason) { 39 | this.emit("fail", test, reason) 40 | this.endTest() 41 | } 42 | 43 | Runner.prototype.pending = function(test) { 44 | this.emit("pending", test) 45 | this.endTest() 46 | } 47 | 48 | Runner.prototype.endTest = function() { 49 | this.emit("end test") 50 | } 51 | 52 | module.exports = Runner 53 | -------------------------------------------------------------------------------- /test/helpers/mock-test.js: -------------------------------------------------------------------------------- 1 | "use strict" 2 | 3 | function Test(fullTitle, title, duration) { 4 | return { 5 | title: title, 6 | duration: duration, 7 | fullTitle: function() { 8 | return fullTitle 9 | }, 10 | titlePath: function() { 11 | return [fullTitle] 12 | }, 13 | slow: function() {}, 14 | } 15 | } 16 | 17 | module.exports = Test 18 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | 'use-strict'; 2 | /* global describe, it, beforeEach, afterEach */ 3 | 4 | var Reporter = require('../index'); 5 | var Runner = require('./helpers/mock-runner'); 6 | var Test = require('./helpers/mock-test'); 7 | var testConsole = require('test-console'); 8 | var assert = require('assert'); 9 | var fs = require('fs'); 10 | 11 | 12 | describe('mocha-circleci-reporter', function() { 13 | 14 | var runner; 15 | var file = __dirname + '/output/console.xml'; 16 | 17 | beforeEach(function() { 18 | runner = new Runner(); 19 | }); 20 | 21 | afterEach(function(){ 22 | if (fs.existsSync(file)) { 23 | fs.unlinkSync(file); 24 | } 25 | }) 26 | 27 | it('should output spec to stdout', function() { 28 | 29 | new Reporter(runner, { 30 | reporterOptions: { mochaFile: file } 31 | }); 32 | 33 | var stdout = testConsole.stdout.inspect(); 34 | try{ 35 | executeTestRunner(); 36 | } 37 | finally{ 38 | stdout.restore(); 39 | } 40 | 41 | assert(stdout.output[1], '\u001b[0mFoo Bar module\u001b[0m\n'); 42 | }); 43 | 44 | it('should output junit file', function() { 45 | 46 | new Reporter(runner, { 47 | reporterOptions: { mochaFile: file } 48 | }); 49 | 50 | var stdout = testConsole.stdout.inspect(); 51 | try{ 52 | executeTestRunner(); 53 | 54 | assert(fs.existsSync(file)); 55 | } 56 | finally{ 57 | stdout.restore(); 58 | } 59 | }); 60 | 61 | function executeTestRunner(char){ 62 | 63 | char = char || ''; 64 | runner.start(); 65 | 66 | runner.startSuite({ 67 | title: 'Foo Bar module', 68 | tests: [1, 2] 69 | }); 70 | 71 | runner.pass(new Test('Foo can weez the juice', 'can weez the juice', 1)); 72 | runner.fail(new Test('Bar can narfle the garthog', 'can narfle the garthog', 1), { 73 | message: char + 'expected garthog to be dead' + char 74 | }); 75 | 76 | runner.startSuite({ 77 | title: 'Another suite!', 78 | tests: [1] 79 | }); 80 | runner.pass(new Test('Another suite', 'works', 4)); 81 | 82 | runner.end(); 83 | } 84 | 85 | }); 86 | --------------------------------------------------------------------------------