Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the ability to save report output to a file #509

Merged
merged 1 commit into from Mar 11, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Expand Up @@ -6,4 +6,6 @@ tunnel
node_modules
.idea
.coverage_data
cover_html
cover_html
test-results.xml
reports
18 changes: 15 additions & 3 deletions lib/ci/index.js
Expand Up @@ -10,6 +10,7 @@ var HookRunner = require('../hook_runner')
var log = require('npmlog')
var cleanExit = require('../clean_exit')
var isa = require('../isa')
var ReportFile = require('./report_file')

function App(config, finalizer){
this.exited = false
Expand All @@ -19,7 +20,9 @@ function App(config, finalizer){
this.Process = Process
this.hookRunners = {}
this.results = []
this.reporter = this.initReporter(this.config.get('reporter'))
this.reportFileName = this.config.get('report_file')
this.reportFile = this.initReportFileStream(this.reportFileName)
this.reporter = this.initReporter(this.config.get('reporter'), this.reportFile)
if (!this.reporter){
console.error('Test reporter `' + reporter + '` not found.')
this.cleanExit(1)
Expand All @@ -28,13 +31,22 @@ function App(config, finalizer){

App.prototype = {
__proto__: EventEmitter.prototype,
initReporter: function(reporter){
initReportFileStream: function(path) {
if(path) {
var reportFile = new ReportFile(path, process.stdout)
return reportFile.stream
} else {
return process.stdout
}

},
initReporter: function(reporter, stream){
if (isa(reporter, String)){
var TestReporter = test_reporters[reporter]
if (!TestReporter){
return null
}
return new TestReporter
return new TestReporter(false, stream)
} else {
return reporter
}
Expand Down
28 changes: 28 additions & 0 deletions lib/ci/report_file.js
@@ -0,0 +1,28 @@
var fs = require('fs')
var path = require('path')
var mkdirp = require('mkdirp')
var PassThrough = require('stream').PassThrough

function ReportFile(reportFile, out) {
this.file = reportFile

this.outputStream = new PassThrough()

mkdirp.sync(path.dirname(path.resolve(reportFile)))

var fileStream = fs.createWriteStream(reportFile, 'w+')

this.outputStream.on('data', function(data) {
out.write(data)
fileStream.write(data)
})

this.outputStream.on('end', function(data) {
out.end(data)
fileStream.end(data)
})

this.stream = this.outputStream
}

module.exports = ReportFile
4 changes: 3 additions & 1 deletion package.json
Expand Up @@ -62,9 +62,11 @@
"cheerio": "^0.18.0",
"concat-stream": "^1.4.7",
"ispy": "^0.1.2",
"mkdirp": "^0.5.0",
"mocha": "^2.1.0",
"request": "^2.51.0",
"sinon": "^1.12.2"
"sinon": "^1.12.2",
"tmp": "0.0.25"
},
"bin": {
"testem": "./testem.js"
Expand Down
103 changes: 103 additions & 0 deletions tests/ci/report_file_tests.js
@@ -0,0 +1,103 @@
var fs = require('fs')
var App = require('../../lib/ci')
var TestReporter = require('../../lib/ci/test_reporters/tap_reporter')
var Config = require('../../lib/config')
var bd = require('bodydouble')
var mock = bd.mock
var stub = bd.stub
var assert = require('chai').assert
var expect = require('chai').expect
var Process = require('did_it_work')
var exec = require('child_process').exec
var rimraf = require('rimraf')
var path = require('path')
var PassThrough = require('stream').PassThrough
var ReportFile = require('../../lib/ci/report_file')
var XUnitReporter = require('../../lib/ci/test_reporters/xunit_reporter')
var tmp = require('tmp')

describe('report file output', function() {
var mainReportDir, reportDir, filename;
before(function(done) {
tmp.dir(function(err, path) {
mainReportDir = path
done()
})
})
after(function(done) {
rimraf(mainReportDir, function() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be removed, when tmp.dir({unsafeCleanup: true}, cb) is used in before.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried that and it was still throwing crazy errors on Windows and folders were still hanging around.

On Mar 4, 2015, at 12:10 AM, Johannes W?rbach <notifications@github.commailto:notifications@github.com> wrote:

In tests/ci/report_file_tests.jshttps://github.com//pull/509#discussion_r25757807:

+var path = require('path')
+var PassThrough = require('stream').PassThrough
+var ReportFile = require('../../lib/ci/report_file')
+var XUnitReporter = require('../../lib/ci/test_reporters/xunit_reporter')
+var tmp = require('tmp')
+
+describe('report file output', function() {

  • var mainReportDir, reportDir, filename;
  • before(function(done) {
  • tmp.dir(function(err, path) {
  •  mainReportDir = path
    
  •  done()
    
  • })
  • })
  • after(function(done) {
  • rimraf(mainReportDir, function() {

This could be removed, when tmp.dir({unsafeCleanup: true}, cb) is used in before.

Reply to this email directly or view it on GitHubhttps://github.com//pull/509/files#r25757807.

done()
})
})

beforeEach(function(done) {
tmp.dir({template: path.join(mainReportDir, '/reports-XXXXXX')}, function(err, dirPath){
if(err) throw err
reportDir = dirPath

tmp.file({dir: dirPath, name: 'test-reports.xml'}, function(err, filePath) {
filename = filePath
done()
})
})
})

it('allows passing in report_file from config', function(){
var fakeReporter = {}
var config = new Config('ci', {
reporter: fakeReporter,
report_file: filename
})
var app = new App(config)
assert.strictEqual(app.reportFileName, filename)
})

it("doesn't create a file if the report_file parameter is not passed in", function(done){
var filename = tmp.tmpNameSync()
var fakeReporter = {}
var config = new Config('ci', {
reporter: fakeReporter,
})
var app = new App(config)
fs.readFile(filename, function(error, data) {
expect(error).not.to.be.null
done()
})
})

it('writes out results to the normal output stream', function(){
var fakeStdout = new PassThrough()
var reportFile = new ReportFile(filename, fakeStdout)
reportFile.stream.write('some test results')
var output = fakeStdout.read().toString()
assert.match(output, /some test results/)
})

it('writes out results to the file', function(done){
var stream = new PassThrough()
var reportFile = new ReportFile(filename, stream)
var reportStream = reportFile.stream

reportStream.on('finish', function() {
fs.readFile(filename, function(error, data) {
assert.match(data, /test data/)
done()
})
})
reportStream.write('test data')
reportStream.end()
})

it("creates folders in the path if they don't exist", function(done) {
var nestedFilename = tmp.tmpNameSync({dir: reportDir, name: 'nested/test/folders/test-reports.xml'})

var fakeStdout = new PassThrough()
var reportFile = new ReportFile(nestedFilename, fakeStdout)

fs.open(nestedFilename, 'r', function(error, fd) {
expect(error).to.be.null
done()
})
})
})