├── .brackets.json ├── .editorconfig ├── .gitattributes ├── .gitignore ├── .npmignore ├── .travis.yml ├── README.md ├── index.js ├── package.json └── test └── index.test.js /.brackets.json: -------------------------------------------------------------------------------- 1 | { 2 | "spaceUnits": 2, 3 | "useTabChar": false, 4 | "language": { 5 | "javascript": { 6 | "linting.prefer": [ 7 | "JSHint" 8 | ], 9 | "linting.usePreferredOnly": true 10 | }, 11 | "markdown": { 12 | "wordWrap": true 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [{package.json,*.yml}] 12 | indent_size = 2 13 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | *.js text eol=lf 5 | *.jsx text eol=lf 6 | *.json text eol=lf 7 | *.html text eol=lf 8 | *.md text eol=lf 9 | *.yml text eol=lf 10 | *.css text eol=lf 11 | *.less text eol=lf 12 | *.scss text eol=lf 13 | *.sass text eol=lf 14 | *.svg text eol=lf 15 | *.xml text eol=lf 16 | 17 | # Custom for Visual Studio 18 | *.cs diff=csharp 19 | 20 | # Standard to msysgit 21 | *.doc diff=astextplain 22 | *.DOC diff=astextplain 23 | *.docx diff=astextplain 24 | *.DOCX diff=astextplain 25 | *.dot diff=astextplain 26 | *.DOT diff=astextplain 27 | *.pdf diff=astextplain 28 | *.PDF diff=astextplain 29 | *.rtf diff=astextplain 30 | *.RTF diff=astextplain 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | Desktop.ini 5 | 6 | # Recycle Bin used on file shares 7 | $RECYCLE.BIN/ 8 | 9 | # Windows shortcuts 10 | *.lnk 11 | 12 | # OSX 13 | .DS_Store 14 | .AppleDouble 15 | .LSOverride 16 | 17 | # Thumbnails 18 | ._* 19 | 20 | # Files that might appear in the root of a volume 21 | .DocumentRevisions-V100 22 | .fseventsd 23 | .Spotlight-V100 24 | .TemporaryItems 25 | .Trashes 26 | .VolumeIcon.icns 27 | 28 | # Directories potentially created on remote AFP share 29 | .AppleDB 30 | .AppleDesktop 31 | Network Trash Folder 32 | Temporary Items 33 | .apdisk 34 | 35 | # Node stuff 36 | node_modules/ 37 | coverage/ 38 | .nyc_output/ 39 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | Desktop.ini 5 | 6 | # Recycle Bin used on file shares 7 | $RECYCLE.BIN/ 8 | 9 | # Windows shortcuts 10 | *.lnk 11 | 12 | # OSX 13 | .DS_Store 14 | .AppleDouble 15 | .LSOverride 16 | 17 | # Thumbnails 18 | ._* 19 | 20 | # Files that might appear in the root of a volume 21 | .DocumentRevisions-V100 22 | .fseventsd 23 | .Spotlight-V100 24 | .TemporaryItems 25 | .Trashes 26 | .VolumeIcon.icns 27 | 28 | # Directories potentially created on remote AFP share 29 | .AppleDB 30 | .AppleDesktop 31 | Network Trash Folder 32 | Temporary Items 33 | .apdisk 34 | 35 | # Node stuff 36 | node_modules/ 37 | coverage/ 38 | .nyc_output/ 39 | 40 | # ignore the dotfiles 41 | .* 42 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - 'node' 5 | - '10' 6 | - '8' 7 | - '6' 8 | - '4' 9 | - '4.2.6' # test Buffer.from detection 10 | - 'iojs' 11 | - '0.12' 12 | - '0.10' 13 | 14 | script: 15 | - npm test 16 | 17 | addons: 18 | code_climate: 19 | repo_token: fe7918d81d3b16b08cae49cd6fe5ecc9e0b04c713cc219b77bbe1188cae02e1a 20 | 21 | after_script: 22 | - codeclimate-test-reporter < coverage/lcov.info 23 | 24 | jobs: 25 | include: 26 | - stage: npm release 27 | if: tag IS present 28 | node_js: '6' 29 | script: echo "Deploying to npm ..." 30 | after_script: skip 31 | deploy: 32 | provider: npm 33 | email: vatev.1+npm@gmail.com 34 | api_key: 35 | secure: UIw2aGEou6QGSyw+0A99n5p0YjwDvvCcOMgiWpf6lTDl0lpLefG9zVu3F9ALCW/LrQ8y5sK9oX4oColAb5dyTp2RS4EmSxVDUfxHWgZfOTQSX4V6cSD9N9bJCOZaZEqpPx2jmia56vyUs25jmcchMTzIW3WehKCQxMhg4U87fx3Qz/21qRDhNbe/SJ+viXKAZuXjqjm7agYObbBNVhvZJYkrD7WrdnzgIu6t3Fp1J01Ph5yD1AQfk/MKvFc/Q7OxqdLyGKCYGk1GGOT6+cdioa8GqeYCfnvHyimZlK/vdt2kE2MkzIO4PLpickLO5cZctUaZSJlHytqKjm6jpDxcfulSoI1YQAXzMu2SXfyoRypeJcW+CT/5KBgpZBf49e7rMQCyuqVokX3EFdikA/EhGhfQZbCLISdVrkA7q3WYcJpW5PAUl90FFcCyOS6+UOycDzXyXK2+Hz1QIJ65AoHfwr3oQ1Xoh4Qy/X6WMb3FgkpNP5Tz5K7LYk5ODkCL3b+0UqA+acik2IH/bkx8Cq5grcqkktTRqQZnVTHkrysyTSMdgVHWxqqLTUHRpGH+AYkWtlVznVu37WPLm/+MNL9x5ThUA64OVIJZz6AOkCIjxZBpzEnyPAi6i0Cc3hozb8OFLh75BYnBl2UIZw6oHJBHVH7vYEKDceUXMo+A5fwjHxg= 36 | on: 37 | tags: true 38 | repo: catdad/mock-stdio 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mock-stdio 2 | 3 | [![travis][travis.svg]][travis.link] 4 | [![cov-codeclimate][cov-codeclimate.svg]][cov-codeclimate.link] 5 | [![gpa-codeclimate][gpa-codeclimate.svg]][gpa-codeclimate.link] 6 | [![npm-downloads][npm-downloads.svg]][npm.link] 7 | [![npm-version][npm-version.svg]][npm.link] 8 | [![dm-david][dm-david.svg]][dm-david.link] 9 | 10 | [travis.svg]: https://travis-ci.org/catdad/mock-stdio.svg?branch=master 11 | [travis.link]: https://travis-ci.org/catdad/mock-stdio 12 | [cov-codeclimate.svg]: https://codeclimate.com/github/catdad/mock-stdio/badges/coverage.svg 13 | [cov-codeclimate.link]: https://codeclimate.com/github/catdad/mock-stdio/coverage 14 | [gpa-codeclimate.svg]: https://codeclimate.com/github/catdad/mock-stdio/badges/gpa.svg 15 | [gpa-codeclimate.link]: https://codeclimate.com/github/catdad/mock-stdio 16 | [npm-downloads.svg]: https://img.shields.io/npm/dm/mock-stdio.svg 17 | [npm.link]: https://www.npmjs.com/package/mock-stdio 18 | [npm-version.svg]: https://img.shields.io/npm/v/mock-stdio.svg 19 | [dm-david.svg]: https://david-dm.org/catdad/mock-stdio.svg 20 | [dm-david.link]: https://david-dm.org/catdad/mock-stdio 21 | 22 | This is just a simple module allowing you to easily test (or just ignore) code that needs to `console.log` or otherwise write to standard out and standard error. 23 | 24 | ## Install 25 | 26 | ```bash 27 | npm install --save-dev mock-stdio 28 | ``` 29 | 30 | ## Example 31 | 32 | ```javascript 33 | var mockIo = require('mock-stdio'); 34 | var expect = require('chai').expect; 35 | 36 | describe('thing', function () { 37 | it('writes to standard out', function () { 38 | // Start the mock... it will not be possible to write to 39 | // the real stdout and stderr when this is active. 40 | mockIo.start(); 41 | 42 | // Call your code. 43 | someFunction(); 44 | 45 | // When you are done, end the mock, and it will return 46 | // all the data written to stdout and stderr while the mock 47 | // was active. 48 | var result = mockIo.end(); 49 | 50 | // Make sure that what you expected was written to 51 | // the corresponding output. 52 | expect(result.stdout).to.be.a('string'); 53 | expect(result.stderr).to.be.a('string'); 54 | }); 55 | }); 56 | ``` 57 | 58 | Note that it is best to use the mock directly inside the test, rather than in `before` or `after` functions, as it will not be possible for anything within the node process to log to `stdout` and `stderr`, meaning you may lose messages that are printed by your test framework. 59 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /* jshint node: true */ 2 | 3 | var originalStdout = process.stdout.write; 4 | var originalStderr = process.stderr.write; 5 | 6 | var outData = []; 7 | var errData = []; 8 | 9 | function collect(arr) { 10 | return function (val) { 11 | /* istanbul ignore next */ 12 | try { 13 | // Buffer.from was officially introduced 14 | // in node 4.5.0, but was actually present 15 | // with only partial abilities before that. 16 | // In earlier versions of node 4, it could 17 | // not handle string data. Simply testing 18 | // for the existence of Buffer.from does not 19 | // support all versions of node. 20 | arr.push(Buffer.from(val)); 21 | } catch(e) { 22 | arr.push(new Buffer(val)); 23 | } 24 | }; 25 | } 26 | 27 | module.exports = { 28 | start: function () { 29 | process.stdout.write = collect(outData); 30 | process.stderr.write = collect(errData); 31 | }, 32 | end: function () { 33 | process.stdout.write = originalStdout; 34 | process.stderr.write = originalStderr; 35 | 36 | var data = { 37 | stdout: Buffer.concat(outData).toString(), 38 | stderr: Buffer.concat(errData).toString() 39 | }; 40 | 41 | outData = []; 42 | errData = []; 43 | 44 | return data; 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mock-stdio", 3 | "version": "1.0.3", 4 | "description": "mock stdio output for tests", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "nyc mocha" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/catdad/mock-stdio.git" 12 | }, 13 | "author": "Kiril Vatev ", 14 | "license": "ISC", 15 | "bugs": { 16 | "url": "https://github.com/catdad/mock-stdio/issues" 17 | }, 18 | "homepage": "https://github.com/catdad/mock-stdio#readme", 19 | "dependencies": {}, 20 | "devDependencies": { 21 | "chai": "^3.5.0", 22 | "codeclimate-test-reporter": "^0.4.1", 23 | "mocha": "^3.3.0", 24 | "nyc": "^10.3.2" 25 | }, 26 | "nyc": { 27 | "check-coverage": true, 28 | "lines": 100, 29 | "statements": 100, 30 | "functions": 100, 31 | "branches": 100, 32 | "reporter": [ 33 | "lcov", 34 | "text" 35 | ] 36 | }, 37 | "directories": { 38 | "test": "test" 39 | }, 40 | "keywords": [ 41 | "mock", 42 | "stdio", 43 | "stdout", 44 | "stderr", 45 | "console.log", 46 | "console.error", 47 | "console", 48 | "log" 49 | ] 50 | } 51 | -------------------------------------------------------------------------------- /test/index.test.js: -------------------------------------------------------------------------------- 1 | /* jshint node: true, mocha: true */ 2 | 3 | var expect = require('chai').expect; 4 | 5 | var lib = require('../'); 6 | 7 | describe('[index]', function () { 8 | it('has two methods', function () { 9 | expect(lib).to.have.all.keys(['start', 'end']); 10 | }); 11 | 12 | it('collects stdout data from process.stdout stream', function () { 13 | var str = 'banana'; 14 | 15 | lib.start(); 16 | 17 | process.stdout.write(str); 18 | 19 | var data = lib.end(); 20 | 21 | expect(data.stdout).to.equal(str); 22 | }); 23 | 24 | it('collects stdout data from console.log', function () { 25 | var str = 'banana'; 26 | 27 | lib.start(); 28 | 29 | console.log(str); 30 | 31 | var data = lib.end(); 32 | 33 | expect(data.stdout).to.equal(str + '\n'); 34 | }); 35 | 36 | it('collects stderr data from process.stderr stream', function () { 37 | var str = 'banana'; 38 | 39 | lib.start(); 40 | 41 | process.stderr.write(str); 42 | 43 | var data = lib.end(); 44 | 45 | expect(data.stderr).to.equal(str); 46 | }); 47 | 48 | it('collects stdout data from console.error', function () { 49 | var str = 'banana'; 50 | 51 | lib.start(); 52 | 53 | console.error(str); 54 | 55 | var data = lib.end(); 56 | 57 | expect(data.stderr).to.equal(str + '\n'); 58 | }); 59 | 60 | }); 61 | --------------------------------------------------------------------------------