├── .gitignore ├── .npmignore ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── bin.js ├── index.js ├── package.json └── test ├── data-tapped.txt ├── data-verbose-tapped.txt ├── data-verbose.txt ├── data.txt └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .travis.yml 2 | CONTRIBUTING.md 3 | test/ 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - lts/* 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Contributions welcome! 4 | 5 | **Before spending lots of time on something, ask for feedback on your idea first!** 6 | 7 | Please search issues and pull requests before adding something new to avoid duplicating efforts and conversations. 8 | 9 | In addition to improving the project by refactoring code and implementing relevant features, this project welcomes the following types of contributions: 10 | 11 | - **Ideas**: participate in an issue thread or start your own to have your voice heard. 12 | - **Writing**: contribute your expertise in an area by helping expand the included content. 13 | - **Copy editing**: fix typos, clarify language, and generally improve the quality of the content. 14 | - **Formatting**: help keep content easy to read with consistent formatting. 15 | 16 | ## Installing 17 | 18 | Fork and clone the repo, then `npm install` to install all dependencies. 19 | 20 | ## Testing 21 | 22 | Tests are run with `npm test`. Unless you're creating a failing test to increase test coverage or show a problem, please make sure all tests are passing before submitting a pull request. 23 | 24 | ## Code Style 25 | 26 | [![standard][standard-image]][standard-url] 27 | 28 | This repository uses [`standard`][standard-url] to maintain code style and consistency and avoid style arguments. `npm test` runs `standard` so you don't have to! 29 | 30 | [standard-image]: https://cdn.rawgit.com/feross/standard/master/badge.svg 31 | [standard-url]: https://github.com/feross/standard 32 | [semistandard-image]: https://cdn.rawgit.com/flet/semistandard/master/badge.svg 33 | [semistandard-url]: https://github.com/Flet/semistandard 34 | 35 | --- 36 | 37 | # Collaborating Guidelines 38 | 39 | **This is an OPEN Open Source Project.** 40 | 41 | ## What? 42 | 43 | Individuals making significant and valuable contributions are given commit access to the project to contribute as they see fit. This project is more like an open wiki than a standard guarded open source project. 44 | 45 | ## Rules 46 | 47 | There are a few basic ground rules for collaborators: 48 | 49 | 1. **No `--force` pushes** or modifying the Git history in any way. 50 | 1. **Non-master branches** ought to be used for ongoing work. 51 | 1. **External API changes and significant modifications** ought to be subject to an **internal pull request** to solicit feedback from other collaborators. 52 | 1. Internal pull requests to solicit feedback are *encouraged* for any other non-trivial contribution but left to the discretion of the contributor. 53 | 1. Contributors should attempt to adhere to the prevailing code style. 54 | 55 | ## Releases 56 | 57 | Declaring formal releases remains the prerogative of the project maintainer. 58 | 59 | ## Changes to this arrangement 60 | 61 | This is an experiment and feedback is welcome! This document may also be subject to pull requests or changes by collaborators where you believe you have something valuable to add or change. 62 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Dan Flettre 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. 4 | 5 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 6 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # standard-tap 2 | 3 | [![npm][npm-image]][npm-url] 4 | [![travis][travis-image]][travis-url] 5 | [![downloads][downloads-image]][downloads-url] 6 | 7 | [npm-image]: https://img.shields.io/npm/v/standard-tap.svg?style=flat-square 8 | [npm-url]: https://www.npmjs.com/package/standard-tap 9 | [travis-image]: https://img.shields.io/travis/standard/standard-tap.svg?style=flat-square 10 | [travis-url]: https://travis-ci.org/standard/standard-tap 11 | [downloads-image]: https://img.shields.io/npm/dm/standard-tap.svg?style=flat 12 | [downloads-url]: https://npmjs.org/package/standard-tap 13 | 14 | Format JavaScript Standard Style as TAP output. 15 | 16 | ## Install 17 | 18 | ``` 19 | npm install -g standard-tap 20 | ``` 21 | 22 | ## Usage 23 | 24 | Pipe "compact" text into `standard-tap` to get back TAP formatted results: 25 | ```bash 26 | standard | standard-tap 27 | 28 | standard --verbose | standard-tap 29 | ``` 30 | 31 | This works with any [standard-engine](https://github.com/standard/standard-engine)-based style command! 32 | ```bash 33 | semistandard --verbose | standard-tap 34 | doublestandard --verbose | standard-tap 35 | ``` 36 | 37 | Or, just run `standard-tap` directly and it will use `standard` and give you TAP output: 38 | ```bash 39 | standard-tap 40 | ``` 41 | 42 | All [standard](https://standardjs.com) command line flags are supported when using it this way: 43 | ```bash 44 | standard-tap --format --verbose test1.js test2.js 45 | ``` 46 | 47 | ## Inspired by 48 | - https://github.com/standard/snazzy 49 | - https://github.com/sindresorhus/eslint-tap 50 | 51 | ## Contributing 52 | 53 | Contributions welcome! Please read the [contributing guidelines](CONTRIBUTING.md) first. 54 | 55 | ## License 56 | 57 | [ISC](LICENSE.md) 58 | -------------------------------------------------------------------------------- /bin.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var makeTap = require('./index.js') 4 | var cp = require('child_process') 5 | var minimist = require('minimist') 6 | var path = require('path') 7 | var concat = require('concat-stream') 8 | 9 | var STANDARD_CMD = path.join(require.resolve('standard'), '../.bin/standard') 10 | if (/^win/.test(process.platform)) STANDARD_CMD += '.cmd' 11 | 12 | var argv = minimist(process.argv.slice(2), { 13 | boolean: [ 14 | 'stdin' 15 | ] 16 | }) 17 | 18 | process.stdout.on('error', function () {}) 19 | 20 | var stream 21 | if (!process.stdin.isTTY || argv._[0] === '-' || argv.stdin) { 22 | stream = process.stdin 23 | } else { 24 | var args = process.argv.slice(2) 25 | var standard = cp.spawn(STANDARD_CMD, args) 26 | standard.stderr.pipe(process.stderr) 27 | stream = standard.stdout 28 | 29 | var standardCode 30 | standard.on('exit', function (code) { standardCode = code }) 31 | process.on('exit', function (code) { 32 | if (code === 0 && standardCode !== 0) { 33 | console.error('non-zero exit from the `standard` command') 34 | process.exit(standardCode) 35 | } 36 | }) 37 | } 38 | 39 | var concatStream = concat({ encoding: 'string' }, function (data) { 40 | var output = makeTap(data, { complex: true }) 41 | console.log(output.output) 42 | if (output.errors) process.exit(1) 43 | }) 44 | stream.pipe(concatStream) 45 | 46 | stream.on('error', handleError) 47 | 48 | function handleError (err) { 49 | console.error(err) 50 | process.exit(1) 51 | } 52 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | module.exports = makeTap 2 | 3 | var jsonify = require('standard-json') 4 | var yamlish = require('yamlish') 5 | 6 | function makeTap (rawtext, opts) { 7 | opts = opts || { complex: false } 8 | 9 | var results = jsonify(rawtext) 10 | 11 | var ret = '\nTAP version 13\n' 12 | var total = 0 13 | 14 | results.forEach(function (result) { 15 | var messages = result.messages 16 | 17 | if (messages.length === 0) { 18 | return 19 | } 20 | 21 | ret += messages.map(function (el) { 22 | var testName = 'Linter Rule' 23 | if (el.ruleId) testName += ': ' + el.ruleId 24 | return 'not ok ' + (++total) + ' ' + testName + '\n ---' + yamlish.encode({ 25 | message: el.message, 26 | severity: 'error', 27 | file: result.filePath, 28 | line: el.line || 0, 29 | name: el.ruleId 30 | }) + '\n ...\n' 31 | }).join('\n') + '\n' 32 | }) 33 | 34 | ret += '1..' + total 35 | 36 | if (opts.complex) return { output: ret, errors: total } 37 | return ret 38 | } 39 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "standard-tap", 3 | "description": "Format JavaScript Standard Style as TAP output", 4 | "version": "1.0.4", 5 | "author": "Dan Flettre ", 6 | "bin": { 7 | "standard-tap": "./bin.js" 8 | }, 9 | "bugs": { 10 | "url": "https://github.com/flet/standard-tap/issues" 11 | }, 12 | "dependencies": { 13 | "concat-stream": "^2.0.0", 14 | "minimist": "^1.1.2", 15 | "standard": "*", 16 | "standard-json": "^1.0.0", 17 | "yamlish": "0.0.7" 18 | }, 19 | "devDependencies": { 20 | "tap-spec": "^5.0.0", 21 | "tape": "^5.0.0" 22 | }, 23 | "homepage": "https://github.com/flet/standard-tap", 24 | "keywords": [ 25 | "format", 26 | "javascript", 27 | "output", 28 | "standard", 29 | "style", 30 | "tap", 31 | "tape" 32 | ], 33 | "license": "ISC", 34 | "main": "index.js", 35 | "preferGlobal": true, 36 | "repository": { 37 | "type": "git", 38 | "url": "https://github.com/flet/standard-tap.git" 39 | }, 40 | "scripts": { 41 | "test": "standard && tape test/*.js | tap-spec" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /test/data-tapped.txt: -------------------------------------------------------------------------------- 1 | 2 | TAP version 13 3 | not ok 1 Linter Rule 4 | --- 5 | message: Strings must use singlequote. 6 | severity: error 7 | file: /someplace/index.js 8 | line: 5 9 | name: ~ 10 | ... 11 | 12 | not ok 2 Linter Rule 13 | --- 14 | message: Extra semicolon. 15 | severity: error 16 | file: /someplace/index.js 17 | line: 15 18 | name: ~ 19 | ... 20 | 21 | 1..2 -------------------------------------------------------------------------------- /test/data-verbose-tapped.txt: -------------------------------------------------------------------------------- 1 | 2 | TAP version 13 3 | not ok 1 Linter Rule: quotes 4 | --- 5 | message: Strings must use singlequote. 6 | severity: error 7 | file: /someplace/index.js 8 | line: 5 9 | name: quotes 10 | ... 11 | 12 | not ok 2 Linter Rule: semi 13 | --- 14 | message: Extra semicolon. 15 | severity: error 16 | file: /someplace/index.js 17 | line: 15 18 | name: semi 19 | ... 20 | 21 | 1..2 -------------------------------------------------------------------------------- /test/data-verbose.txt: -------------------------------------------------------------------------------- 1 | standard: Use JavaScript Standard Style (https://github.com/feross/standard) 2 | /someplace/index.js:5:23: Strings must use singlequote. (quotes) 3 | /someplace/index.js:15:36: Extra semicolon. (semi) 4 | -------------------------------------------------------------------------------- /test/data.txt: -------------------------------------------------------------------------------- 1 | standard: Use JavaScript Standard Style (https://github.com/feross/standard) 2 | /someplace/index.js:5:23: Strings must use singlequote. 3 | /someplace/index.js:15:36: Extra semicolon. 4 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | var test = require('tape') 2 | var stdTap = require('../') 3 | var fs = require('fs') 4 | var path = require('path') 5 | 6 | test('stdTap', function (t) { 7 | t.plan(1) 8 | var data = fs.readFileSync(path.join(__dirname, 'data.txt'), { encoding: 'utf8' }) 9 | var dataTapped = fs.readFileSync(path.join(__dirname, 'data-tapped.txt'), { encoding: 'utf8' }) 10 | 11 | var output = stdTap(data) 12 | 13 | t.equal(dataTapped, output, 'TAP formatted') 14 | }) 15 | 16 | test('stdTap --verbose', function (t) { 17 | t.plan(1) 18 | var data = fs.readFileSync(path.join(__dirname, 'data-verbose.txt'), { encoding: 'utf8' }) 19 | var dataTapped = fs.readFileSync(path.join(__dirname, 'data-verbose-tapped.txt'), { encoding: 'utf8' }) 20 | 21 | var output = stdTap(data) 22 | 23 | t.equal(dataTapped, output, 'TAP formatted --verbose') 24 | }) 25 | 26 | test('stdTap complex true', function (t) { 27 | t.plan(2) 28 | var data = fs.readFileSync(path.join(__dirname, 'data.txt'), { encoding: 'utf8' }) 29 | var dataTapped = fs.readFileSync(path.join(__dirname, 'data-tapped.txt'), { encoding: 'utf8' }) 30 | 31 | var output = stdTap(data, { complex: true }) 32 | 33 | t.equal(dataTapped, output.output, 'TAP formatted output') 34 | t.equal(2, output.errors, 'TAP formatted error count') 35 | }) 36 | 37 | test('stdTap complex true - no errors', function (t) { 38 | t.plan(2) 39 | var data = '' 40 | var dataTapped = '\nTAP version 13\n1..0' 41 | 42 | var output = stdTap(data, { complex: true }) 43 | 44 | t.equal(dataTapped, output.output, 'TAP formatted output') 45 | t.equal(0, output.errors, 'TAP formatted error count') 46 | }) 47 | --------------------------------------------------------------------------------