├── .editorconfig
├── .gitattributes
├── .github
└── workflows
│ └── test.yml
├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── Makefile
├── README.md
├── bin
└── jslint.js
├── doc
└── jslint.md
├── jslint.conf.example
├── lib
├── collectorstream.js
├── color.js
├── fileopener.js
├── jslint-2012-02-03.js
├── jslint-2013-02-03.js
├── jslint-2013-08-13.js
├── jslint-2013-08-26.js
├── jslint-2013-09-22.js
├── jslint-2013-11-23.js
├── jslint-2014-01-26.js
├── jslint-2014-02-06.js
├── jslint-2014-04-21.js
├── jslint-2014-07-08.js
├── jslint-2015-05-08.js
├── jslint-2016-05-13.js
├── jslint-2016-07-13.js
├── jslint-2017-07-01.js
├── jslint-2018-01-26.js
├── jslint-2018-11-28.js
├── jslint-es5.js
├── jslint-es6.js
├── jslint-latest.js
├── jslint.js
├── jsonreportstream.js
├── linter.js
├── lintstream.js
├── main.js
├── nodelint.js
├── options.js
├── reporter.js
├── reportstream.js
└── stream.js
├── package-lock.json
├── package.json
└── test
├── color.js
├── fileopener.js
├── fixtures
├── bad.js
└── good.js
├── linter.js
├── lintstream.js
├── main.js
├── nodelint.js
├── options.js
├── regression.js
├── reporter.js
└── reportstream.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | end_of_line = lf
5 | insert_final_newline = true
6 | trim_trailing_whitespace = true
7 |
8 | [*.js, **/*.js]
9 | indent_size = 4
10 | indent_style = space
11 |
12 | [{package.json,.travis.yml}]
13 | indent_size = 2
14 | indent_style = space
15 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 | *.js text eol=lf
4 | *.json test eol=lf
5 |
6 | # Custom for Visual Studio
7 | *.cs diff=csharp
8 | *.sln merge=union
9 | *.csproj merge=union
10 | *.vbproj merge=union
11 | *.fsproj merge=union
12 | *.dbproj merge=union
13 |
14 | # Standard to msysgit
15 | *.doc diff=astextplain
16 | *.DOC diff=astextplain
17 | *.docx diff=astextplain
18 | *.DOCX diff=astextplain
19 | *.dot diff=astextplain
20 | *.DOT diff=astextplain
21 | *.pdf diff=astextplain
22 | *.PDF diff=astextplain
23 | *.rtf diff=astextplain
24 | *.RTF diff=astextplain
25 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Test
2 | on:
3 | push:
4 | branches:
5 | - master
6 | pull_request:
7 | jobs:
8 | main:
9 | runs-on: ubuntu-latest
10 | strategy:
11 | matrix:
12 | node: [8, 10, 12]
13 | steps:
14 | - uses: actions/checkout@v1
15 | - uses: actions/setup-node@v1
16 | with:
17 | node-version: ${{ matrix.node }}
18 | - name: Install and test
19 | run: |
20 | npm ci
21 | npm test
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.log
2 | **.sw*
3 | .DS_Store*
4 | node_modules
5 | doc/jslint.html
6 | man/jslint.1
7 | coverage
8 | **/*~
9 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "0.8"
4 | - "0.10"
5 | - "0.12"
6 | - "4"
7 | - "5"
8 | - "6"
9 | before_install:
10 | - "npm install -g npm@latest"
11 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4 |
5 |
6 | ## [0.12.1](https://github.com/reid/node-jslint/compare/v0.12.0...v0.12.1) (2019-01-28)
7 |
8 | ### Update to es6 latest (2018-11-28)
9 | Node doesn't like the 'export default' syntax, so I hacked it to use 'var'.
10 |
11 | ### Update dependencies
12 | * mocha => 5.2.0
13 | * glob => 7.1.3
14 | * nopt => 4.0.1
15 | * marked-man => 0.2.1
16 |
17 |
18 | ## [0.12.0](https://github.com/reid/node-jslint/compare/v0.10.3...v0.12.0) (2018-02-03)
19 |
20 | ### Update to es6 latest (2018-01-27)
21 |
22 |
23 | ## [0.10.3](https://github.com/reid/node-jslint/compare/v0.10.1...v0.10.3) (2016-08-03)
24 |
25 |
26 | ### Bug Fixes
27 |
28 | * **lib/jslint-es6:** update jslint-es6 to latest upstream, 2016-07-13 ([7ec74b6](https://github.com/reid/node-jslint/commit/7ec74b6))
29 | * **package.json:** add license, update deps ([55baa7b](https://github.com/reid/node-jslint/commit/55baa7b))
30 |
31 |
32 |
33 |
34 | ## [0.10.2](https://github.com/reid/node-jslint/compare/v0.10.0...v0.10.2) (2016-07-30)
35 |
36 |
37 | ### Bug Fixes
38 |
39 | * **package.json:** add license, update deps ([55baa7b](https://github.com/reid/node-jslint/commit/55baa7b))
40 |
41 | ## Before 2016-07-30
42 |
43 | Version 0.9.0 contains the new BETA version of jslint for EcmaScript 6,
44 | which is a ground-up rewrite by Douglas Crockford. The `latest` alias
45 | still points to the last `es5` version of jslint; you can also use
46 | `--edition=es5` to get the (old) es5 version. To get the `es6` version
47 | you must use `--edition=es6`.
48 |
49 | 2015-07-29 Sam Mikes
50 | * lib/jslint-es6.js: latest jslint from upstream
51 | * lib/nodelint.js, test/regression.js: correctly report edition for post-es6 jslints,
52 | thanks to @bryanjhv for the bug report and fix
53 |
54 | 2015-02-19 Sam Mikes
55 | * lib/main.js, test/main.js: new option --no-filter to allow linting paths containing 'node_modules'
56 |
57 | 2014-12-16 Sam Mikes
58 | * lib/collector.js: new programmatic interface for collecting lint
59 | * lib/main.js, lib/nodelint.js: add callback to `runMain`, publicize
60 |
61 | 2014-10-22 Sam Mikes
62 | * test/regression.js: add file for misc github issues tests
63 | * package.json: avoid using prepublish
64 |
65 | 2014-09-10 Marshall Thompson
66 | * update jslint-latest to upstream edition 2014-07-08
67 |
68 | 2104-04-13 Sam Mikes
69 |
70 | * lib/linter.js: Fix issue #88 - support user-specified config file, support
71 | jslint.conf and .jslint.conf in addition to jslintrc, .jslintrc
72 |
73 | 2014-01-30 Sam Mikes
74 |
75 | * lib/linter.js: Fix Issue #80 - crash on empty jslintrc
76 | Underlying issue was test-then-read rather than just attempting to
77 | read and parse config, catching exceptions.
78 |
79 | 2014-01-27 Sam Mikes
80 |
81 | * Version 0.2.8 - update jslint-latest to upstream edition 2014-01-26
82 |
83 | 2013-12-18 Sam Mikes
84 |
85 | * Version 0.2.6 - move code from src/jslint.js to lib/main.js
86 | Update list of options in jslint.md
87 | Remove incorrect options from jslintrc.example (https://github.com/reid/node-jslint/issues/76)
88 | Document & enable use of --todo flag (https://github.com/reid/node-jslint/issues/76)
89 |
90 | Version 0.7.0 creates a new programmatic interface which is used by
91 | https://github.com/hapijs/lab
92 |
93 | Version 0.5.1 fixes a regression which crashes jslint when more than
94 | maxerr errors are in a single file. Thanks to Vasil Velichkov
95 | (@velichkov) for pointing this out.
96 |
97 | Version 0.5.0 reorganizes the loading interface, making it easier for
98 | other projects to use node-jslint to load a specific jslint edition.
99 |
100 | Version 0.4.0 exposes a stream interface to jslint.
101 |
102 | Version 0.3.4 supports globbing with * and ** expressions.
103 |
104 | Versions 0.2+ provide multiple editions of jslint to
105 | address backwards and forwards compatibility.
106 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2011 Yahoo! Inc.
2 | All rights reserved.
3 |
4 | Redistribution and use of this software in source and binary forms,
5 | with or without modification, are permitted provided that the following
6 | conditions are met:
7 |
8 | * Redistributions of source code must retain the above
9 | copyright notice, this list of conditions and the
10 | following disclaimer.
11 |
12 | * Redistributions in binary form must reproduce the above
13 | copyright notice, this list of conditions and the
14 | following disclaimer in the documentation and/or other
15 | materials provided with the distribution.
16 |
17 | * Neither the name of Yahoo! Inc. nor the names of its
18 | contributors may be used to endorse or promote products
19 | derived from this software without specific prior
20 | written permission of Yahoo! Inc.
21 |
22 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
23 | IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 |
34 | ===
35 |
36 | This license applies to everything except JSLint.
37 | JSLint, located at lib/jslint.js, is copyright Douglas Crockford.
38 | JSLint is provided under a customized MIT license, which is
39 | included in the header of lib/jslint.js.
40 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | BIN=bin/jslint.js
2 | SOURCES=$(shell find bin lib -name '*.js' ! -name 'jslint*.js' -print)
3 |
4 | install:
5 | npm i .
6 |
7 | # omit 'test' because running all tests is side-effect of asking for coverage
8 | prepublish: lint doc no-dos-endings check-coverage
9 |
10 | lint: $(SOURCES)
11 | node ./bin/jslint.js --edition=latest --this --terse $(SOURCES); echo
12 |
13 | test:
14 | ./node_modules/.bin/mocha -u tdd
15 |
16 | doc: man/jslint.1 doc/jslint.html
17 |
18 | man/jslint.1: doc/jslint.md
19 | mkdir -p man
20 | ./node_modules/.bin/marked-man $< > $@
21 |
22 | doc/jslint.html: doc/jslint.md
23 | ./node_modules/.bin/marked-man --html $< > $@
24 |
25 | no-dos-endings:
26 | file $(SOURCES) | grep -v CRLF >/dev/null
27 |
28 | cover: $(SOURCES)
29 | ./node_modules/.bin/istanbul cover -x "lib/jslint-*.js" --print=both ./node_modules/mocha/bin/_mocha -- -u tdd
30 |
31 | check-coverage: cover
32 | ./node_modules/.bin/istanbul check-coverage --statements 90 --branches 90 --functions 90 --lines 90
33 |
34 | .PHONY: install lint test doc no-dos-endings check-coverage
35 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## node-jslint
2 |
3 | Easily use [JSLint][] from the command line.
4 |
5 | jslint bin/jslint.js
6 |
7 | ## What's New
8 |
9 | Added latest jslint, 2018-01-27.
10 |
11 | Version 0.12.0 contains the latest jslint-es6
12 |
13 | See CHANGELOG.md for detailed change history
14 |
15 | ## Use the command-line client
16 |
17 | ### Install (both local and global are supported)
18 |
19 | npm i jslint
20 |
21 | ### Use the default jslint
22 |
23 | jslint lib/color.js
24 |
25 | ### Always use the latest jslint
26 |
27 | jslint --edition=latest lib/color.js
28 |
29 | ### Use a specific edition
30 |
31 | For example, edition 2013-02-03 which shipped with node-jslint 0.1.9:
32 |
33 | jslint --edition=2013-02-03 lib/color.js
34 |
35 | ## Use node-jslint programmatically
36 |
37 | ### Streams interface
38 |
39 | As of node-jslint 0.4.0, a streams interface is exposed. You can use it in client code like this:
40 |
41 | Install as a dependency:
42 |
43 | $ npm install --save jslint
44 |
45 | Pull it into your code with require:
46 |
47 | var LintStream = require('jslint').LintStream;
48 |
49 | Create and configure the stream linter:
50 |
51 | var options = {
52 | "edition": "latest",
53 | "length": 100
54 | },
55 | l = new LintStream(options);
56 |
57 | Send files to the linter:
58 |
59 | var fileName, fileContents;
60 | l.write({file: fileName, body: fileContents});
61 |
62 | Receive lint from the linter:
63 |
64 | l.on('data', function (chunk, encoding, callback) {
65 | // chunk is an object
66 |
67 | // chunk.file is whatever you supplied to write (see above)
68 | assert.deepEqual(chunk.file, fileName);
69 |
70 | // chunk.linted is an object holding the result from running JSLint
71 | // chunk.linted.ok is the boolean return code from JSLINT()
72 | // chunk.linted.errors is the array of errors, etc.
73 | // see JSLINT for the complete contents of the object
74 |
75 | callback();
76 | });
77 |
78 | You can only pass options to the LintStream when creating it. The `edition` option can be
79 | used to select different editions of JSLint.
80 |
81 | The LintStream is in object mode (objectMode: true). It expects an
82 | object with two properties: `file` and `body`. The `file` property
83 | can be used to pass metadata along with the file. The `body` property
84 | contains the file to be linted; it can be either a string or a Buffer.
85 |
86 | The LintStream emits `'data'` events containing an object with two properties.
87 | The `file` property is copied from the `file` property that is passed in. The
88 | `linted` property contains the results of running JSLINT.
89 |
90 | ### Simple interface
91 |
92 | The simple interface provides an edition-aware loader. This can be used as a frontend to
93 | node-jslint's collection of editions of the JSLINT code.
94 |
95 | var node_jslint = require('jslint'),
96 | JSLINT = node_jslint.load(edition);
97 |
98 | This exposes the same loading interface used in node-jslint, so it supports the special
99 | edition names `default` and `latest` as well as date-based edition names such as `2013-08-26`
100 |
101 | As of version 0.5.0, the `load` function also accepts filenames. To be recognized as a filename,
102 | the argument to load must contain a path-separator character (`/` or `\`) or end with the extension
103 | `.js`.
104 |
105 |
106 | ## Usage examples
107 |
108 | Multiple files
109 |
110 | jslint lib/color.js lib/reporter.js
111 |
112 | All JSLint options supported
113 |
114 | jslint --white --vars --regexp lib/color.js
115 |
116 | Defaults to true, but you can specify false
117 |
118 | jslint --bitwise false lib/color.js
119 |
120 | Pass arrays
121 |
122 | jslint --predef $ --predef Backbone lib/color.js
123 |
124 | JSLint your entire project
125 |
126 | jslint '**/*.js'
127 |
128 | ## Using JSLint with a config file
129 |
130 | Start with the included `jslint.conf.example` file, name it `jslint.conf` and customize your options
131 | per project or copy it to `$HOME/.jslint.conf` to apply your setting globally
132 |
133 | ## License
134 |
135 | See LICENSE file.
136 |
137 | [JSLint]: http://jslint.com/
138 |
--------------------------------------------------------------------------------
/bin/jslint.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | var main = require("../lib/main.js");
4 |
5 | main.runMain(main.parseArgs());
6 |
--------------------------------------------------------------------------------
/doc/jslint.md:
--------------------------------------------------------------------------------
1 | jslint(1) -- a code quality tool
2 | ================================
3 | ## SYNOPSIS
4 |
5 | jslint.js [--anon] [--ass] [--bitwise] [--browser] [--closure] [--color] [--continue] [--debug] [--devel] [--edition] [--eqeq] [--es5] [--evil] [--forin] [--indent] [--json] [--maxerr] [--maxlen] [--newcap] [--node] [--nomen] [--on] [--passfail] [--plusplus] [--predef] [--properties] [--regexp] [--rhino] [--sloppy] [--stupid] [--sub] [--terse] [--todo] [--undef] [--unparam] [--vars] [--white] [--] ...
6 |
7 | ## DESCRIPTION
8 |
9 | JSLint is a static analysis tool to locate and correct style problems in Javascript (ECMAScript etc.) source code.
10 |
11 | ## META OPTIONS
12 | `--color` write output in color
13 |
14 | `--terse` report one error per line with parseable source file/line
15 |
16 | `--json` output in JSON format
17 |
18 | `--edition` specify which edition of jslint to use
19 |
20 | `--no-filter` allow linting files containing pattern `node_modules`
21 |
22 | ## LINTING OPTIONS
23 | `--ass` Tolerate assignment expressions
24 |
25 | `--bitwise` Tolerate bitwise operators
26 |
27 | `--browser` Assume a browser
28 |
29 | `--closure` Tolerate Google Closure idioms
30 |
31 | `--continue` Tolerate continue
32 |
33 | `--debug` Tolerate debugger statements
34 |
35 | `--devel` Assume console,alert, ...
36 |
37 | `--eqeq` Tolerate == and !=
38 |
39 | `--evil` Tolerate eval
40 |
41 | `--forin` Tolerate unfiltered for in
42 |
43 | `--indent` Strict white space indentation
44 |
45 | `--maxerr` Maximum number of errors
46 |
47 | `--maxlen` Maximum line length
48 |
49 | `--newcap` Tolerate uncapitalized constructors
50 |
51 | `--node` Assume Node.js
52 |
53 | `--nomen` Tolerate dangling underscore in identifiers
54 |
55 | `--passfail` Stop on first error
56 |
57 | `--plusplus` Tolerate ++ and --
58 |
59 | `--predef` Declare additional predefined globals
60 |
61 | `--properties` Require all property names to be declared with /*properties*/
62 |
63 | `--regexp` Tolerate . and [^...]. in /RegExp/
64 |
65 | `--rhino` Assume Rhino
66 |
67 | `--sloppy` Tolerate missing 'use strict' pragma
68 |
69 | `--stupid` Tolerate stupidity (typically, use of sync functions)
70 |
71 | `--sub` Tolerate inefficient subscripting
72 |
73 | `--todo` Tolerate TODO comments
74 |
75 | `--unparam` Tolerate unused parameters
76 |
77 | `--vars` Tolerate many var statements per function
78 |
79 | `--white` Tolerate messy white space
80 |
81 | ## DEPRECATED OPTIONS
82 |
83 | `--anon` Tolerate no space in anonymous function definition
84 |
85 | `--es5` Tolerate ECMAScript 5 syntax
86 |
87 | `--undef` Tolerate variables used before declaration
88 |
89 | `--on` Tolerate HTML event handlers
90 |
91 | `--windows` Assume existence of Windows globals
92 |
93 | ##EXAMPLES
94 |
95 | *Multiple files:*
96 |
97 | jslint lib/color.js lib/reporter.js
98 |
99 | *All JSLint options supported*
100 |
101 | jslint --white --vars --regexp lib/color.js
102 |
103 | *Defaults to true, but you can specify false*
104 |
105 | jslint --bitwise false lib/color.js
106 |
107 | *Pass arrays*
108 |
109 | jslint --predef $ --predef Backbone lib/color.js
110 |
111 | *JSLint your entire project*
112 |
113 | find . -name "*.js" -print0 | xargs -0 jslint
114 |
115 | *Using JSLint with a config file*
116 |
117 | Start with the included example jslintrc file and customize your options per project
118 | or copy it to $HOME/.jslintrc to apply your setting globally
119 |
120 | ##INSTALLATION
121 |
122 | To install jslint globally, use
123 | npm install jslint -g
124 |
125 | To install jslint locally, use
126 | npm install jslint
127 |
128 | When installed locally, jslint can be run as
129 | ./node_modules/.bin/jslint
130 |
131 | ##FILES
132 |
133 | jslint looks for the following config files at startup:
134 |
135 | $HOME/.jslintrc
136 | ./jslintrc
137 | ./.jslintrc
138 |
139 | The format of a jslint options file is a JSON file containing a single object
140 | where the keys are jslint option names and the values are the option argument;
141 | use `true` to enable and `false` to disable boolean options. An example of a
142 | valid option file is:
143 |
144 | {
145 | "vars": true,
146 | "white": true,
147 | "maxlen": 100,
148 | "predef": "foo,bar,baz"
149 | }
150 |
151 | Comments are not allowed in option files.
152 |
153 | ##PRECEDENCE
154 |
155 | The order of precedence for options is as follows:
156 |
157 | 1. in the $HOME/.jslintrc
158 | 1. in ./jslintrc or ./.jslintrc
159 | 1. on the command line
160 | 1. in a /\*jslint\*/ comment
161 |
162 | A higher number indicates a higher precedence, i.e. command line options
163 | override options specified by an options file, and /\*jslint\*/ comments
164 | in the file being examined have the highest precedence.
165 |
166 | ##EDITIONS
167 |
168 | You can now specify the edition of jslint with the *--edition* option.
169 |
170 | Future versions of this package may include newer editions of jslint;
171 | to always use the latest edition of jslint, specify --edition=latest:
172 |
173 | jslint --edition=latest lib/*.js
174 |
175 | The default edition of jslint will remain stable as long as the leading
176 | two components of the version number are the same. New minor editions
177 | may have a different default edition.
178 |
179 | The previous version of this package (0.1.9) shipped an older edition
180 | (2013-02-03) of jslint. To revert to that behavior but still have the
181 | new config file features, upgrade to 0.2.1 of this package and specify
182 | `edition: '2012-02-03'` in your jslintrc file or `--edition=2013-02-03`
183 | on the command line.
184 |
185 | We recommend the following practices:
186 |
187 | ###If your project is in maintenance mode
188 |
189 | Choose an edition of jslint and hardcode it into your project's lint config files, e.g.,
190 | `edition: '2012-02-03'`. Specify a fixed version of jslint (e.g., "0.2.1") as a
191 | devDependency in package.json
192 |
193 | ###If your project needs temporary stability (e.g., release phase)
194 |
195 | Use the default edition of jslint (no `--edition` argument needed) and specify
196 | a fixed minor version (e.g, "~0.2") as a devDependency in package.json
197 |
198 | ###If you want the bleeding-edge version
199 |
200 | Specify `edition: 'latest'` and use any 'latest version' behavior in package.json,
201 | e.g., "*" or ">0.2.1"
202 |
203 | ##RETURN VALUES
204 |
205 | jslint returns 1 if it found any problems, 0 otherwise.
206 |
207 | ##AUTHOR
208 |
209 | jslint is written and maintained by Douglas Crockford [https://github.com/douglascrockford/JSLint](https://github.com/douglascrockford/JSLint)
210 |
211 | This package is node-jslint, which provides a command-line interface for
212 | running jslint using the nodejs platform. node-jslint was written by Reid Burke
213 | and is maintained by Reid Burke, Ryuichi Okumura, and Sam Mikes.
214 |
215 | ##BUGS
216 |
217 | There are no known bugs. Submit bugs to [https://github.com/reid/node-jslint/issues](https://github.com/reid/node-jslint/issues)
218 |
219 | Note that if you are reporting a problem with the way jslint works rather than the way
220 | the command-line tools work, we will probably refer you to the JSLint community [https://plus.google.com/communities/104441363299760713736](https://plus.google.com/communities/104441363299760713736) or the issue tracker at
221 | [https://github.com/douglascrockford/JSLint/issues](https://github.com/douglascrockford/JSLint/issues)
222 |
--------------------------------------------------------------------------------
/jslint.conf.example:
--------------------------------------------------------------------------------
1 | {
2 | "evil":false,
3 | "indent":2,
4 | "vars":true,
5 | "passfail":false,
6 | "plusplus":false,
7 | "predef": "module,require"
8 | }
9 |
--------------------------------------------------------------------------------
/lib/collectorstream.js:
--------------------------------------------------------------------------------
1 | // this file is lib/collectorstream.js
2 | // provides a stream interface to JSLint
3 | //
4 | // Copyright 2014 Cubane Canada Inc.
5 | //
6 | // Released under modified MIT/BSD 3-clause license
7 | // See LICENSE for details.
8 |
9 | 'use strict';
10 |
11 | var util = require('util'),
12 | Transform = require('./stream').Transform,
13 | CollectorStream;
14 |
15 | CollectorStream = function CollectorStream_constructor(options) {
16 | if (!(this instanceof CollectorStream)) {
17 | return new CollectorStream(options);
18 | }
19 |
20 | Transform.call(this, {objectMode: true});
21 |
22 | this.lint = [];
23 |
24 | this.allOK = true;
25 | };
26 | util.inherits(CollectorStream, Transform);
27 |
28 | function CollectorStream_transform(chunk, ignore, callback) {
29 | // chunk: a package of lint data from JSLint
30 | this.lint.push([chunk.file, chunk.linted.errors]);
31 |
32 | this.allOK = this.allOK && chunk.linted.ok;
33 |
34 | callback();
35 | }
36 |
37 | CollectorStream.prototype._transform = CollectorStream_transform;
38 |
39 | module.exports = CollectorStream;
40 |
--------------------------------------------------------------------------------
/lib/color.js:
--------------------------------------------------------------------------------
1 | function color(code, string) {
2 | 'use strict';
3 | return "\u001b[" + code + "m" + string + "\u001b[0m";
4 | }
5 |
6 | function factory(code) {
7 | 'use strict';
8 | return function (string) {
9 | return color(code, string);
10 | };
11 | }
12 |
13 | module.exports = {
14 | bold: factory(1),
15 | red: factory(31),
16 | green: factory(32),
17 | yellow: factory(33),
18 | blue: factory(34),
19 | grey: factory(90)
20 | };
21 |
--------------------------------------------------------------------------------
/lib/fileopener.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var util = require('util'),
4 | Transform = require('./stream').Transform,
5 | fs = require('fs');
6 |
7 | function FileOpener() {
8 | Transform.call(this, {objectMode: true});
9 | }
10 |
11 | util.inherits(FileOpener, Transform);
12 |
13 | function FileOpener_transform(file, ignore, callback) {
14 | var stream = this;
15 | fs.readFile(file, 'utf8', function (err, data) {
16 | if (err) {
17 | stream.emit('error', err);
18 | return;
19 | }
20 |
21 | stream.push({file: file, body: data});
22 | callback();
23 | });
24 | }
25 |
26 | FileOpener.prototype._transform = FileOpener_transform;
27 |
28 | module.exports = FileOpener;
29 |
30 |
--------------------------------------------------------------------------------
/lib/jsonreportstream.js:
--------------------------------------------------------------------------------
1 | // this file is lib/reportstream.js
2 | // provides a stream interface to JSLint
3 | //
4 | // Copyright 2014 Cubane Canada Inc.
5 | //
6 | // Released under modified MIT/BSD 3-clause license
7 | // See LICENSE for details.
8 |
9 | (function () {
10 | 'use strict';
11 |
12 | var util = require('util'),
13 | Transform = require('./stream').Transform,
14 | JSONReportStream;
15 |
16 | JSONReportStream = function JSONReportStream_constructor(options) {
17 | if (!(this instanceof JSONReportStream)) {
18 | return new JSONReportStream(options);
19 | }
20 |
21 | Transform.call(this, {objectMode: true});
22 |
23 | this.allOK = true;
24 | };
25 | util.inherits(JSONReportStream, Transform);
26 |
27 | function JSONReportStream_transform(chunk, ignore, callback) {
28 | // chunk: a package of lint data from JSLint
29 | this.emit('data', JSON.stringify([chunk.file, chunk.linted.errors]));
30 |
31 | this.allOK = this.allOK && chunk.linted.ok;
32 |
33 | callback();
34 | }
35 |
36 | JSONReportStream.prototype._transform = JSONReportStream_transform;
37 |
38 | module.exports = JSONReportStream;
39 |
40 | }());
41 |
--------------------------------------------------------------------------------
/lib/linter.js:
--------------------------------------------------------------------------------
1 | function merge(source, add) {
2 | 'use strict';
3 |
4 | var result = source || {};
5 |
6 | if (!add) {
7 | return result;
8 | }
9 |
10 | Object.keys(add).forEach(function (prop) {
11 | if (!result.hasOwnProperty(prop)) {
12 | result[prop] = add[prop];
13 | }
14 | });
15 |
16 | return result;
17 | }
18 | exports.merge = merge;
19 |
20 | function preprocessScript(script) {
21 | 'use strict';
22 |
23 | // Fix UTF8 with BOM
24 | if (script.charCodeAt(0) === 0xFEFF) {
25 | script = script.slice(1);
26 | }
27 |
28 | // remove shebang: replace it with empty line
29 | script = script.replace(/^#!.*/, "");
30 |
31 | return script;
32 | }
33 | exports.preprocessScript = preprocessScript;
34 |
35 | exports.doLint = function (jslint, script, options) {
36 | 'use strict';
37 | var ok,
38 | result;
39 |
40 | script = preprocessScript(script);
41 |
42 | ok = jslint(script, options);
43 |
44 | result = jslint.data();
45 | if (result.ok === undefined) {
46 | result.ok = ok;
47 | }
48 | result.options = options;
49 |
50 | // es6
51 | result.errors = result.errors || result.warnings;
52 |
53 | return result;
54 | };
55 |
--------------------------------------------------------------------------------
/lib/lintstream.js:
--------------------------------------------------------------------------------
1 | // this file is lib/lintstream.js
2 | // provides a stream interface to JSLint
3 | //
4 | // Copyright 2014 Cubane Canada Inc.
5 | //
6 | // Released under modified MIT/BSD 3-clause license
7 | // See LICENSE for details.
8 |
9 | (function () {
10 | 'use strict';
11 |
12 | var util = require('util'),
13 | Transform = require('./stream').Transform,
14 | nodelint = require('./nodelint'),
15 | optModule = require('./options'),
16 | linter = require('./linter'),
17 | LintStream;
18 |
19 | LintStream = function LintStream_constructor(options) {
20 | if (!(this instanceof LintStream)) {
21 | return new LintStream(options);
22 | }
23 | Transform.call(this, {objectMode: true});
24 |
25 | // shallow copy options
26 | options = optModule.merge({}, options);
27 | this.JSlint = nodelint.load(options.edition);
28 |
29 | // initialize members
30 | this.options = options;
31 | this.linter = linter;
32 | };
33 | util.inherits(LintStream, Transform);
34 |
35 | function LintStream_transform(chunk, ignore, callback) {
36 | var fileName = chunk.file,
37 | body = chunk.body,
38 | linted = this.linter.doLint(this.JSlint, body, this.options);
39 |
40 | this.push({file: fileName, linted: linted});
41 |
42 | callback();
43 | }
44 |
45 | LintStream.prototype._transform = LintStream_transform;
46 |
47 | module.exports = LintStream;
48 |
49 | }());
50 |
--------------------------------------------------------------------------------
/lib/main.js:
--------------------------------------------------------------------------------
1 | var nodelint = require('./nodelint');
2 | var optModule = require('./options');
3 | var nopt = require("nopt");
4 | var exit = require('exit'),
5 | glob = require('glob');
6 |
7 | var LintStream = require('./lintstream.js'),
8 | ReportStream = require('./reportstream.js'),
9 | CollectorStream = require('./collectorstream.js'),
10 | JSONReportStream = require('./jsonreportstream.js'),
11 | FileOpener = require('./fileopener.js');
12 |
13 | var con = console;
14 | var pro = process;
15 |
16 | exports.setConsole = function (c) {
17 | 'use strict';
18 | con = c;
19 | };
20 |
21 | exports.setProcess = function (p) {
22 | 'use strict';
23 | pro = p;
24 | exit = pro.exit.bind(pro);
25 | };
26 |
27 | function commandOptions() {
28 | 'use strict';
29 |
30 | var commandOpts = {
31 | 'indent': Number,
32 | 'maxerr': Number,
33 | 'maxlen': Number,
34 | 'predef': [String, Array],
35 | 'edition': String,
36 | 'config': String
37 | },
38 | /* flags defined in jslint-latest.js */
39 | jslintFlags = [
40 | 'ass', 'bitwise', 'browser', 'closure', 'continue',
41 | 'debug', 'devel', 'eqeq', 'evil', 'forin', 'newcap',
42 | 'node', 'nomen', 'passfail', 'plusplus', 'properties',
43 | 'regexp', 'rhino', 'unparam', 'sloppy', 'stupid', 'sub',
44 | 'todo', 'vars', 'white'
45 | ],
46 | /* flags used by node-jslint to control output */
47 | cliFlags = [
48 | 'json', 'color', 'terse', 'version', 'filter'
49 | ],
50 | /* not used by jslint-latest.js */
51 | deprecatedFlags = [
52 | 'anon', 'es5', 'on', 'undef', 'windows'
53 | ],
54 | allFlags = jslintFlags.concat(cliFlags).concat(deprecatedFlags);
55 |
56 | allFlags.forEach(function (option) {
57 | commandOpts[option] = Boolean;
58 | });
59 |
60 | return commandOpts;
61 | }
62 | exports.commandOptions = commandOptions;
63 |
64 | function die(why) {
65 | 'use strict';
66 | var o = commandOptions();
67 | con.warn(why);
68 | con.warn("Usage: " + pro.argv[1] +
69 | " [--" + Object.keys(o).sort().join("] [--") +
70 | "] [--] ...");
71 | exit(1);
72 | }
73 |
74 | function parseArgs(argv) {
75 | 'use strict';
76 | var args = nopt(commandOptions(), {}, argv);
77 |
78 | if (args.filter === undefined) {
79 | args.filter = true;
80 | }
81 |
82 | return args;
83 | }
84 | exports.parseArgs = parseArgs;
85 |
86 | exports.reportVersion = function reportVersion(callback, options) {
87 | 'use strict';
88 | process.nextTick(function () {
89 | var package_data = require('../package.json'),
90 | version = package_data.version,
91 | edition = nodelint.load(options.edition).edition;
92 |
93 | callback("node-jslint version: " + version + " JSLint edition " + edition);
94 | });
95 |
96 | };
97 |
98 | function expandGlob(glob) {
99 | 'use strict';
100 |
101 | return function (pattern) {
102 | return glob.sync(pattern);
103 | };
104 | }
105 | exports.expandGlob = expandGlob;
106 |
107 | function noNodeModules(file) {
108 | 'use strict';
109 | return file.indexOf('node_modules') === -1;
110 | }
111 | exports.noNodeModules = noNodeModules;
112 |
113 | function flatten(a, b) {
114 | 'use strict';
115 |
116 | return a.concat(b);
117 | }
118 |
119 | function globFiles(list, glob, filter) {
120 | 'use strict';
121 | var remain = [];
122 |
123 | remain = list.map(expandGlob(glob))
124 | .reduce(flatten, []);
125 |
126 | if (filter) {
127 | remain = remain.filter(noNodeModules);
128 | }
129 |
130 | return remain;
131 | }
132 | exports.globFiles = globFiles;
133 |
134 | function makeReporter(parsed) {
135 | 'use strict';
136 | var reporter;
137 |
138 | if (parsed.json) {
139 | reporter = new JSONReportStream(parsed);
140 | } else if (parsed.collector) {
141 | reporter = new CollectorStream(parsed);
142 | } else {
143 | reporter = new ReportStream(parsed);
144 | }
145 |
146 | reporter.on('data', function (chunk) {
147 | if (chunk === '.') {
148 | pro.stderr.write(chunk);
149 | } else {
150 | con.log(chunk);
151 | }
152 | });
153 |
154 | return reporter;
155 | }
156 | exports.makeReporter = makeReporter;
157 |
158 | exports.runMain = function (options, cb) {
159 | 'use strict';
160 |
161 | if (options.version) {
162 | exports.reportVersion(con.log, options);
163 | return;
164 | }
165 |
166 | if (!options.argv.remain.length) {
167 | die("No files specified.");
168 | }
169 |
170 | var procOptions = optModule.getOptions(process.env.HOME, options),
171 | files = globFiles(options.argv.remain, glob, options.filter),
172 | opener = new FileOpener(),
173 | linter = new LintStream(procOptions),
174 | reporter = makeReporter(procOptions);
175 |
176 | opener.pipe(linter);
177 | linter.pipe(reporter);
178 |
179 | reporter.on('finish', function () {
180 | if (cb) {
181 | return cb(null, reporter.lint);
182 | }
183 |
184 | if (reporter.allOK) {
185 | return exit(0);
186 | }
187 | exit(1);
188 | });
189 |
190 | files.forEach(function (file) {
191 | opener.write(file);
192 | });
193 | opener.end();
194 | };
195 |
--------------------------------------------------------------------------------
/lib/nodelint.js:
--------------------------------------------------------------------------------
1 | var con = console,
2 | vm = require("vm"),
3 | fs = require("fs"),
4 | path = require('path'),
5 | linter = require('./linter.js'),
6 | main = require('./main.js'),
7 | LintStream = require('./lintstream.js');
8 |
9 | exports.LintStream = LintStream;
10 |
11 | exports.linter = linter;
12 |
13 | exports.runMain = main.runMain;
14 |
15 | exports.setConsole = function (c) {
16 | 'use strict';
17 | con = c;
18 | };
19 |
20 | function looksLikeFileName(edition) {
21 | 'use strict';
22 |
23 | // contains .js or a path separator character '/' or '\'
24 | return (/\.js|\/|\\/).test(edition);
25 | }
26 | exports.looksLikeFileName = looksLikeFileName;
27 |
28 | exports.load = function (edition) {
29 | 'use strict';
30 |
31 | var ctx = vm.createContext(),
32 | fileName,
33 | jslintSource;
34 |
35 | function makePathFromName(name) {
36 | return path.join(__dirname, name) + ".js";
37 | }
38 |
39 | function makePathFromEdition(edition) {
40 | return makePathFromName("jslint-" + edition);
41 | }
42 |
43 | function read(name) {
44 | return fs.readFileSync(name);
45 | }
46 |
47 |
48 | if (edition) {
49 | if (looksLikeFileName(edition)) {
50 | fileName = edition;
51 | } else {
52 | fileName = makePathFromEdition(edition);
53 | }
54 |
55 | try {
56 | jslintSource = read(fileName);
57 | } catch (err) {
58 | con.warn("Unable to load edition " + edition + ", reverting to default. " + err);
59 | }
60 | }
61 |
62 | if (!jslintSource) {
63 | jslintSource = read(makePathFromName("jslint"));
64 | }
65 |
66 | vm.runInContext(jslintSource, ctx);
67 |
68 | if (!ctx.JSLINT) {
69 | ctx.JSLINT = function JSLINT(script, options) {
70 | var data = ctx.jslint(script, options, options.predef);
71 | ctx.JSLINT.data = function () {
72 | return data;
73 | };
74 | };
75 | ctx.JSLINT.edition = ctx.jslint('').edition;
76 | }
77 |
78 | return ctx.JSLINT;
79 |
80 | };
81 |
--------------------------------------------------------------------------------
/lib/options.js:
--------------------------------------------------------------------------------
1 | (function () {
2 | 'use strict';
3 |
4 | var path = require('path'),
5 | fs = require('fs'),
6 | con = console;
7 |
8 | exports.setConsole = function (c) {
9 | con = c;
10 | };
11 |
12 | function merge(source, add) {
13 | var result = source || {};
14 |
15 | if (!add) {
16 | return result;
17 | }
18 |
19 | Object.keys(add).forEach(function (prop) {
20 | if (!result.hasOwnProperty(prop)) {
21 | result[prop] = add[prop];
22 | }
23 | });
24 |
25 | return result;
26 | }
27 | exports.merge = merge;
28 |
29 | function loadAndParseConfig(filePath) {
30 | try {
31 | return JSON.parse(fs.readFileSync(filePath, "utf-8"));
32 | } catch (err) {
33 | if (filePath && err.code !== "ENOENT") {
34 | con.warn('Error reading config file "' + filePath + '": ' + err);
35 | }
36 | }
37 | }
38 | exports.loadAndParseConfig = loadAndParseConfig;
39 |
40 | function addDefaults(options) {
41 |
42 | options = merge(options, {node: true, es5: true});
43 |
44 | return options;
45 | }
46 |
47 | function notFalsy(n) {
48 | return n;
49 | }
50 |
51 | function splitPredefs(options) {
52 | if (!options.predef) {
53 | return options;
54 | }
55 | if (Array.isArray(options.predef)) {
56 | return options;
57 | }
58 |
59 | options.predef = options.predef.split(',').filter(notFalsy);
60 |
61 | return options;
62 | }
63 |
64 | function preprocessOptions(options, config) {
65 | options = merge({}, options);
66 |
67 | options = merge(options, config);
68 |
69 | options = addDefaults(options);
70 |
71 | options = splitPredefs(options);
72 |
73 | return options;
74 | }
75 |
76 | function mergeConfigs(home, project) {
77 | var homeConfig,
78 | cwdConfig,
79 | config;
80 |
81 | home.some(function (file) {
82 | homeConfig = loadAndParseConfig(file);
83 | return homeConfig;
84 | });
85 |
86 | project.some(function (file) {
87 | cwdConfig = loadAndParseConfig(file);
88 | return cwdConfig;
89 | });
90 |
91 | config = merge(cwdConfig, homeConfig);
92 |
93 | return config;
94 | }
95 | exports.mergeConfigs = mergeConfigs;
96 |
97 | function loadConfig(h, configFile) {
98 | var home = h || '',
99 | homeConfigs = ['.jslint.conf', '.jslintrc'],
100 | projectConfigs = ['jslint.conf', '.jslint.conf', 'jslintrc', '.jslintrc'];
101 |
102 | if (configFile) {
103 | // explicitly specified config file overrides default config file name, path
104 | homeConfigs = [configFile];
105 | } else {
106 | homeConfigs = homeConfigs.map(function (file) {
107 | return path.join(home, file);
108 | });
109 | }
110 |
111 | projectConfigs = projectConfigs.map(function (file) {
112 | return path.join(process.cwd(), file);
113 | });
114 |
115 | return mergeConfigs(homeConfigs, projectConfigs);
116 | }
117 | exports.loadConfig = loadConfig;
118 |
119 | function options_getOptions(homedir, options) {
120 | var config = loadConfig(homedir, options.config);
121 |
122 | return preprocessOptions(options, config);
123 | }
124 |
125 | exports.preprocessOptions = preprocessOptions;
126 | exports.getOptions = options_getOptions;
127 | exports.splitPredefs = splitPredefs;
128 | exports.addDefaults = addDefaults;
129 |
130 | }());
131 |
--------------------------------------------------------------------------------
/lib/reporter.js:
--------------------------------------------------------------------------------
1 | (function () {
2 | 'use strict';
3 |
4 | var color = require("./color");
5 |
6 | exports.logger = {
7 | log: (console.log).bind(console),
8 | err: (process.stderr.write).bind(process.stderr)
9 | };
10 |
11 | exports.setLogger = function (l) {
12 | this.logger = l;
13 | };
14 |
15 | exports.makeReporter = function (logger, colorize, terse) {
16 | return {
17 | logger: logger,
18 | colorize: colorize,
19 | terse: terse,
20 | report: function (file, lint) {
21 | return exports.report.call(this, file, lint, this.colorize, this.terse);
22 | }
23 | };
24 | };
25 |
26 | exports.report = function (file, lint, colorize, terse) {
27 | var line,
28 | pad,
29 | errors,
30 | fudge = Number(lint.option && lint.option.fudge) || 0,
31 | logger = this.logger,
32 | fileMessage;
33 |
34 | function c(format, str) {
35 | if (colorize) {
36 | return color[format](str);
37 | }
38 | return str;
39 | }
40 |
41 | fileMessage = "\n" + c('bold', file);
42 |
43 | function row(e) {
44 | return e.line + fudge;
45 | }
46 | function col(e) {
47 | return (e.character || e.column) + fudge;
48 | }
49 | function evidence(e) {
50 | return e.evidence || (lint.lines && lint.lines[e.line]) || '';
51 | }
52 | function message(e) {
53 | return e.reason || e.message;
54 | }
55 |
56 | if (!lint.ok) {
57 | // remove nulls
58 | errors = lint.errors;// || lint.warnings;
59 | errors = errors.filter(function (e) {
60 | return e;
61 | });
62 |
63 | if (terse) {
64 | errors.forEach(function (e) {
65 | logger.log(file + ':' + row(e) + ':' + col(e) + ': ' + message(e));
66 | });
67 | } else {
68 | logger.log(fileMessage);
69 | errors.forEach(function (e, i) {
70 | pad = "#" + String(i + 1);
71 | while (pad.length < 3) {
72 | pad = ' ' + pad;
73 | }
74 | line = ' // Line ' + row(e) + ', Pos ' + col(e);
75 |
76 | logger.log(pad + ' ' + c('yellow', message(e)));
77 | logger.log(' ' + evidence(e).trim() + c('grey', line));
78 | });
79 | }
80 | } else {
81 | if (terse) {
82 | logger.err(".");
83 | } else {
84 | logger.log(fileMessage + " is " + c('green', 'OK') + ".");
85 | }
86 | }
87 |
88 | return lint.ok;
89 | };
90 |
91 | }());
92 |
--------------------------------------------------------------------------------
/lib/reportstream.js:
--------------------------------------------------------------------------------
1 | // this file is lib/reportstream.js
2 | // provides a stream interface to JSLint
3 | //
4 | // Copyright 2014 Cubane Canada Inc.
5 | //
6 | // Released under modified MIT/BSD 3-clause license
7 | // See LICENSE for details.
8 |
9 | (function () {
10 | 'use strict';
11 |
12 | var util = require('util'),
13 | Transform = require('./stream').Transform,
14 | reporter = require('./reporter'),
15 | ReportStream;
16 |
17 |
18 | ReportStream = function ReportStream_constructor(options) {
19 | var stream = this;
20 |
21 | if (!(this instanceof ReportStream)) {
22 | return new ReportStream(options);
23 | }
24 |
25 | options = options || {};
26 | options.objectMode = true;
27 | Transform.call(this, options);
28 |
29 | this.reporter = reporter.makeReporter(
30 | {
31 | log: function (s) {
32 | stream.emit('data', s);
33 | },
34 | err: function (s) {
35 | stream.emit('data', s);
36 | }
37 | },
38 | options.color,
39 | options.terse
40 | );
41 |
42 | this.allOK = true;
43 |
44 | };
45 | util.inherits(ReportStream, Transform);
46 |
47 | function ReportStream_transform(chunk, ignore, callback) {
48 | // chunk: a package of lint data from JSLint
49 |
50 | this.reporter.report(chunk.file, chunk.linted);
51 |
52 | this.allOK = this.allOK && chunk.linted.ok;
53 |
54 | callback();
55 | }
56 |
57 | ReportStream.prototype._transform = ReportStream_transform;
58 |
59 | module.exports = ReportStream;
60 |
61 | }());
62 |
--------------------------------------------------------------------------------
/lib/stream.js:
--------------------------------------------------------------------------------
1 | module.exports = require('readable-stream');
2 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jslint",
3 | "version": "0.12.1",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "abbrev": {
8 | "version": "1.0.7",
9 | "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.7.tgz",
10 | "integrity": "sha1-W2A1su6dT7XPhZ8Iqb6BsghJGEM="
11 | },
12 | "amdefine": {
13 | "version": "1.0.1",
14 | "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
15 | "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
16 | "dev": true,
17 | "optional": true
18 | },
19 | "argparse": {
20 | "version": "1.0.9",
21 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz",
22 | "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=",
23 | "dev": true,
24 | "requires": {
25 | "sprintf-js": "~1.0.2"
26 | }
27 | },
28 | "async": {
29 | "version": "1.5.2",
30 | "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
31 | "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
32 | "dev": true
33 | },
34 | "balanced-match": {
35 | "version": "1.0.0",
36 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
37 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
38 | },
39 | "brace-expansion": {
40 | "version": "1.1.8",
41 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
42 | "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
43 | "requires": {
44 | "balanced-match": "^1.0.0",
45 | "concat-map": "0.0.1"
46 | }
47 | },
48 | "browser-stdout": {
49 | "version": "1.3.1",
50 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
51 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
52 | "dev": true
53 | },
54 | "buffer-shims": {
55 | "version": "1.0.0",
56 | "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz",
57 | "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E="
58 | },
59 | "commander": {
60 | "version": "2.15.1",
61 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
62 | "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
63 | "dev": true
64 | },
65 | "concat-map": {
66 | "version": "0.0.1",
67 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
68 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
69 | },
70 | "core-util-is": {
71 | "version": "1.0.2",
72 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
73 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
74 | },
75 | "debug": {
76 | "version": "3.1.0",
77 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
78 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
79 | "dev": true,
80 | "requires": {
81 | "ms": "2.0.0"
82 | }
83 | },
84 | "deep-is": {
85 | "version": "0.1.3",
86 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
87 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
88 | "dev": true
89 | },
90 | "diff": {
91 | "version": "3.5.0",
92 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
93 | "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
94 | "dev": true
95 | },
96 | "escape-string-regexp": {
97 | "version": "1.0.5",
98 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
99 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
100 | "dev": true
101 | },
102 | "escodegen": {
103 | "version": "1.8.0",
104 | "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.0.tgz",
105 | "integrity": "sha1-skaq6CnOc9WeLFVyc1nt0cEwqBs=",
106 | "dev": true,
107 | "requires": {
108 | "esprima": "^2.7.1",
109 | "estraverse": "^1.9.1",
110 | "esutils": "^2.0.2",
111 | "optionator": "^0.8.1",
112 | "source-map": "~0.2.0"
113 | }
114 | },
115 | "esprima": {
116 | "version": "2.7.3",
117 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
118 | "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
119 | "dev": true
120 | },
121 | "estraverse": {
122 | "version": "1.9.3",
123 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz",
124 | "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=",
125 | "dev": true
126 | },
127 | "esutils": {
128 | "version": "2.0.2",
129 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
130 | "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
131 | "dev": true
132 | },
133 | "exit": {
134 | "version": "0.1.2",
135 | "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
136 | "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw="
137 | },
138 | "fast-levenshtein": {
139 | "version": "2.0.6",
140 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
141 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
142 | "dev": true
143 | },
144 | "fs.extra": {
145 | "version": "1.3.2",
146 | "resolved": "https://registry.npmjs.org/fs.extra/-/fs.extra-1.3.2.tgz",
147 | "integrity": "sha1-3QI/kwE77iRTHxszUUw3sg/ZM0k=",
148 | "dev": true,
149 | "requires": {
150 | "fs-extra": "~0.6.1",
151 | "mkdirp": "~0.3.5",
152 | "walk": "^2.3.9"
153 | },
154 | "dependencies": {
155 | "fs-extra": {
156 | "version": "0.6.4",
157 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.6.4.tgz",
158 | "integrity": "sha1-9G8MdbeEH40gCzNIzU1pHVoJnRU=",
159 | "dev": true,
160 | "requires": {
161 | "jsonfile": "~1.0.1",
162 | "mkdirp": "0.3.x",
163 | "ncp": "~0.4.2",
164 | "rimraf": "~2.2.0"
165 | },
166 | "dependencies": {
167 | "jsonfile": {
168 | "version": "1.0.1",
169 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-1.0.1.tgz",
170 | "integrity": "sha1-6l7+QLg2kLmGZ2FKc5L8YOhCwN0=",
171 | "dev": true
172 | },
173 | "ncp": {
174 | "version": "0.4.2",
175 | "resolved": "https://registry.npmjs.org/ncp/-/ncp-0.4.2.tgz",
176 | "integrity": "sha1-q8xsvT7C7Spyn/bnwfqPAXhKhXQ=",
177 | "dev": true
178 | },
179 | "rimraf": {
180 | "version": "2.2.8",
181 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz",
182 | "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=",
183 | "dev": true
184 | }
185 | }
186 | },
187 | "mkdirp": {
188 | "version": "0.3.5",
189 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz",
190 | "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=",
191 | "dev": true
192 | },
193 | "walk": {
194 | "version": "2.3.9",
195 | "resolved": "https://registry.npmjs.org/walk/-/walk-2.3.9.tgz",
196 | "integrity": "sha1-MbTbZnjyrgHDnqn7hyWpAx5Vins=",
197 | "dev": true,
198 | "requires": {
199 | "foreachasync": "^3.0.0"
200 | },
201 | "dependencies": {
202 | "foreachasync": {
203 | "version": "3.0.0",
204 | "resolved": "https://registry.npmjs.org/foreachasync/-/foreachasync-3.0.0.tgz",
205 | "integrity": "sha1-VQKYfchxS+M5IJfzLgBxyd7gfPY=",
206 | "dev": true
207 | }
208 | }
209 | }
210 | }
211 | },
212 | "fs.realpath": {
213 | "version": "1.0.0",
214 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
215 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
216 | },
217 | "glob": {
218 | "version": "7.1.3",
219 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
220 | "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
221 | "requires": {
222 | "fs.realpath": "^1.0.0",
223 | "inflight": "^1.0.4",
224 | "inherits": "2",
225 | "minimatch": "^3.0.4",
226 | "once": "^1.3.0",
227 | "path-is-absolute": "^1.0.0"
228 | }
229 | },
230 | "growl": {
231 | "version": "1.10.5",
232 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
233 | "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
234 | "dev": true
235 | },
236 | "handlebars": {
237 | "version": "4.7.6",
238 | "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz",
239 | "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==",
240 | "dev": true,
241 | "requires": {
242 | "minimist": "^1.2.5",
243 | "neo-async": "^2.6.0",
244 | "source-map": "^0.6.1",
245 | "uglify-js": "^3.1.4",
246 | "wordwrap": "^1.0.0"
247 | },
248 | "dependencies": {
249 | "minimist": {
250 | "version": "1.2.5",
251 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
252 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
253 | "dev": true
254 | },
255 | "source-map": {
256 | "version": "0.6.1",
257 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
258 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
259 | "dev": true
260 | }
261 | }
262 | },
263 | "has-flag": {
264 | "version": "1.0.0",
265 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
266 | "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
267 | "dev": true
268 | },
269 | "he": {
270 | "version": "1.1.1",
271 | "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
272 | "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
273 | "dev": true
274 | },
275 | "inflight": {
276 | "version": "1.0.6",
277 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
278 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
279 | "requires": {
280 | "once": "^1.3.0",
281 | "wrappy": "1"
282 | }
283 | },
284 | "inherits": {
285 | "version": "2.0.3",
286 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
287 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
288 | },
289 | "isarray": {
290 | "version": "1.0.0",
291 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
292 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
293 | },
294 | "isexe": {
295 | "version": "2.0.0",
296 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
297 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
298 | "dev": true
299 | },
300 | "istanbul": {
301 | "version": "0.4.5",
302 | "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz",
303 | "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=",
304 | "dev": true,
305 | "requires": {
306 | "abbrev": "1.0.x",
307 | "async": "1.x",
308 | "escodegen": "1.8.x",
309 | "esprima": "2.7.x",
310 | "glob": "^5.0.15",
311 | "handlebars": "^4.0.1",
312 | "js-yaml": "3.x",
313 | "mkdirp": "0.5.x",
314 | "nopt": "3.x",
315 | "once": "1.x",
316 | "resolve": "1.1.x",
317 | "supports-color": "^3.1.0",
318 | "which": "^1.1.1",
319 | "wordwrap": "^1.0.0"
320 | },
321 | "dependencies": {
322 | "glob": {
323 | "version": "5.0.15",
324 | "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
325 | "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
326 | "dev": true,
327 | "requires": {
328 | "inflight": "^1.0.4",
329 | "inherits": "2",
330 | "minimatch": "2 || 3",
331 | "once": "^1.3.0",
332 | "path-is-absolute": "^1.0.0"
333 | }
334 | },
335 | "nopt": {
336 | "version": "3.0.6",
337 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
338 | "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
339 | "dev": true,
340 | "requires": {
341 | "abbrev": "1"
342 | }
343 | }
344 | }
345 | },
346 | "js-yaml": {
347 | "version": "3.13.1",
348 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
349 | "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
350 | "dev": true,
351 | "requires": {
352 | "argparse": "^1.0.7",
353 | "esprima": "^4.0.0"
354 | },
355 | "dependencies": {
356 | "esprima": {
357 | "version": "4.0.1",
358 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
359 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
360 | "dev": true
361 | }
362 | }
363 | },
364 | "levn": {
365 | "version": "0.3.0",
366 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
367 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
368 | "dev": true,
369 | "requires": {
370 | "prelude-ls": "~1.1.2",
371 | "type-check": "~0.3.2"
372 | }
373 | },
374 | "marked": {
375 | "version": "0.3.19",
376 | "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.19.tgz",
377 | "integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==",
378 | "dev": true
379 | },
380 | "marked-man": {
381 | "version": "0.2.1",
382 | "resolved": "https://registry.npmjs.org/marked-man/-/marked-man-0.2.1.tgz",
383 | "integrity": "sha1-8lknFIHeO1ByY0ifUiG3xaz9I4M=",
384 | "dev": true,
385 | "requires": {
386 | "marked": "^0.3.2"
387 | }
388 | },
389 | "minimatch": {
390 | "version": "3.0.4",
391 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
392 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
393 | "requires": {
394 | "brace-expansion": "^1.1.7"
395 | }
396 | },
397 | "mkdirp": {
398 | "version": "0.5.1",
399 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
400 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
401 | "dev": true,
402 | "requires": {
403 | "minimist": "0.0.8"
404 | },
405 | "dependencies": {
406 | "minimist": {
407 | "version": "0.0.8",
408 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
409 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
410 | "dev": true
411 | }
412 | }
413 | },
414 | "mocha": {
415 | "version": "5.2.0",
416 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz",
417 | "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==",
418 | "dev": true,
419 | "requires": {
420 | "browser-stdout": "1.3.1",
421 | "commander": "2.15.1",
422 | "debug": "3.1.0",
423 | "diff": "3.5.0",
424 | "escape-string-regexp": "1.0.5",
425 | "glob": "7.1.2",
426 | "growl": "1.10.5",
427 | "he": "1.1.1",
428 | "minimatch": "3.0.4",
429 | "mkdirp": "0.5.1",
430 | "supports-color": "5.4.0"
431 | },
432 | "dependencies": {
433 | "glob": {
434 | "version": "7.1.2",
435 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
436 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
437 | "dev": true,
438 | "requires": {
439 | "fs.realpath": "^1.0.0",
440 | "inflight": "^1.0.4",
441 | "inherits": "2",
442 | "minimatch": "^3.0.4",
443 | "once": "^1.3.0",
444 | "path-is-absolute": "^1.0.0"
445 | }
446 | },
447 | "has-flag": {
448 | "version": "3.0.0",
449 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
450 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
451 | "dev": true
452 | },
453 | "supports-color": {
454 | "version": "5.4.0",
455 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
456 | "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
457 | "dev": true,
458 | "requires": {
459 | "has-flag": "^3.0.0"
460 | }
461 | }
462 | }
463 | },
464 | "ms": {
465 | "version": "2.0.0",
466 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
467 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
468 | "dev": true
469 | },
470 | "neo-async": {
471 | "version": "2.6.1",
472 | "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz",
473 | "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==",
474 | "dev": true
475 | },
476 | "nopt": {
477 | "version": "4.0.1",
478 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz",
479 | "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=",
480 | "requires": {
481 | "abbrev": "1",
482 | "osenv": "^0.1.4"
483 | }
484 | },
485 | "once": {
486 | "version": "1.4.0",
487 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
488 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
489 | "requires": {
490 | "wrappy": "1"
491 | }
492 | },
493 | "optionator": {
494 | "version": "0.8.2",
495 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
496 | "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
497 | "dev": true,
498 | "requires": {
499 | "deep-is": "~0.1.3",
500 | "fast-levenshtein": "~2.0.4",
501 | "levn": "~0.3.0",
502 | "prelude-ls": "~1.1.2",
503 | "type-check": "~0.3.2",
504 | "wordwrap": "~1.0.0"
505 | }
506 | },
507 | "os-homedir": {
508 | "version": "1.0.2",
509 | "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
510 | "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
511 | },
512 | "os-tmpdir": {
513 | "version": "1.0.2",
514 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
515 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
516 | },
517 | "osenv": {
518 | "version": "0.1.5",
519 | "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
520 | "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
521 | "requires": {
522 | "os-homedir": "^1.0.0",
523 | "os-tmpdir": "^1.0.0"
524 | }
525 | },
526 | "path-is-absolute": {
527 | "version": "1.0.1",
528 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
529 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
530 | },
531 | "prelude-ls": {
532 | "version": "1.1.2",
533 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
534 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
535 | "dev": true
536 | },
537 | "process-nextick-args": {
538 | "version": "1.0.7",
539 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
540 | "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
541 | },
542 | "readable-stream": {
543 | "version": "2.1.5",
544 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz",
545 | "integrity": "sha1-ZvqLcg4UOLNkaB8q0aY8YYRIydA=",
546 | "requires": {
547 | "buffer-shims": "^1.0.0",
548 | "core-util-is": "~1.0.0",
549 | "inherits": "~2.0.1",
550 | "isarray": "~1.0.0",
551 | "process-nextick-args": "~1.0.6",
552 | "string_decoder": "~0.10.x",
553 | "util-deprecate": "~1.0.1"
554 | }
555 | },
556 | "resolve": {
557 | "version": "1.1.7",
558 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
559 | "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
560 | "dev": true
561 | },
562 | "source-map": {
563 | "version": "0.2.0",
564 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz",
565 | "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=",
566 | "dev": true,
567 | "optional": true,
568 | "requires": {
569 | "amdefine": ">=0.0.4"
570 | }
571 | },
572 | "sprintf-js": {
573 | "version": "1.0.3",
574 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
575 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
576 | "dev": true
577 | },
578 | "string_decoder": {
579 | "version": "0.10.31",
580 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
581 | "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
582 | },
583 | "supports-color": {
584 | "version": "3.2.3",
585 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
586 | "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
587 | "dev": true,
588 | "requires": {
589 | "has-flag": "^1.0.0"
590 | }
591 | },
592 | "type-check": {
593 | "version": "0.3.2",
594 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
595 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
596 | "dev": true,
597 | "requires": {
598 | "prelude-ls": "~1.1.2"
599 | }
600 | },
601 | "uglify-js": {
602 | "version": "3.10.3",
603 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.10.3.tgz",
604 | "integrity": "sha512-Lh00i69Uf6G74mvYpHCI9KVVXLcHW/xu79YTvH7Mkc9zyKUeSPz0owW0dguj0Scavns3ZOh3wY63J0Zb97Za2g==",
605 | "dev": true,
606 | "optional": true
607 | },
608 | "util-deprecate": {
609 | "version": "1.0.2",
610 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
611 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
612 | },
613 | "which": {
614 | "version": "1.2.14",
615 | "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz",
616 | "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=",
617 | "dev": true,
618 | "requires": {
619 | "isexe": "^2.0.0"
620 | }
621 | },
622 | "wordwrap": {
623 | "version": "1.0.0",
624 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
625 | "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
626 | "dev": true
627 | },
628 | "wrappy": {
629 | "version": "1.0.2",
630 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
631 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
632 | }
633 | }
634 | }
635 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jslint",
3 | "description": "The JavaScript Code Quality Tool",
4 | "homepage": "https://github.com/reid/node-jslint",
5 | "keywords": [
6 | "lint",
7 | "jslint",
8 | "code-quality",
9 | "static-analysis",
10 | "jshint",
11 | "eslint"
12 | ],
13 | "version": "0.12.1",
14 | "author": "Reid Burke ",
15 | "contributors": [
16 | "Douglas Crockford ",
17 | "Mikeal Rogers ",
18 | "Adam Moore",
19 | "Luke Smith ",
20 | "Anders Conbere ",
21 | "Ryuichi OKUMURA ",
22 | "Sam Mikes ",
23 | "Dylan Lloyd",
24 | "Andreas Hindborg",
25 | "Andrew Pennebaker",
26 | "Bnaya",
27 | "Maximilian Antoni ",
28 | "Vasil Velichkov",
29 | "Rasmus Paetau",
30 | "Bryan Horna"
31 | ],
32 | "bin": {
33 | "jslint": "./bin/jslint.js"
34 | },
35 | "main": "./lib/nodelint.js",
36 | "dependencies": {
37 | "exit": "~0.1.2",
38 | "glob": "~7.1.3",
39 | "nopt": "~4.0.1",
40 | "readable-stream": "~2.1.5"
41 | },
42 | "devDependencies": {
43 | "fs.extra": "^1.3.2",
44 | "istanbul": "~0.4.5",
45 | "marked-man": "~0.2.1",
46 | "mocha": "~5.2.0"
47 | },
48 | "engines": {
49 | "node": ">=0.8.0"
50 | },
51 | "files": [
52 | "man/jslint.1",
53 | "doc/jslint.md",
54 | "doc/jslint.html",
55 | "lib",
56 | "bin",
57 | "jslint.conf.example",
58 | "Makefile"
59 | ],
60 | "directories": {
61 | "lib": "./lib",
62 | "man": "./man",
63 | "doc": "./doc"
64 | },
65 | "man": "man/jslint.1",
66 | "repository": {
67 | "type": "git",
68 | "url": "git://github.com/reid/node-jslint.git"
69 | },
70 | "bugs": {
71 | "url": "https://github.com/reid/node-jslint/issues"
72 | },
73 | "license": "BSD-3-Clause",
74 | "licenses": [
75 | {
76 | "type": "Modified MIT / BSD",
77 | "url": "https://github.com/reid/node-jslint/blob/master/LICENSE"
78 | }
79 | ],
80 | "scripts": {
81 | "test": "make test",
82 | "mypublish": "make prepublish; npm publish"
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/test/color.js:
--------------------------------------------------------------------------------
1 | var assert = require('assert'),
2 | color = require('../lib/color');
3 |
4 | suite('text colors', function () {
5 | test('bold text', function () {
6 | assert.equal('\x1b[1mbold\x1b[0m', color.bold('bold'));
7 | });
8 | });
9 |
--------------------------------------------------------------------------------
/test/fileopener.js:
--------------------------------------------------------------------------------
1 | var assert = require('assert'),
2 | stream = require('stream'),
3 | FileOpener = require('../lib/fileopener.js');
4 |
5 | suite('fileopener', function () {
6 | test('can create object', function () {
7 | var f = new FileOpener();
8 | });
9 |
10 | test('can open file', function (done) {
11 | var f = new FileOpener();
12 |
13 | f.on('data', function(chunk) {
14 | done();
15 | });
16 |
17 | f.write('./README.md');
18 | f.end();
19 | });
20 |
21 | test('error on nonexistent file', function (done) {
22 | var f = new FileOpener();
23 |
24 | f.on('error', function(chunk) {
25 | done();
26 | });
27 |
28 | f.write('./NONEXISTENT-FILE.not-here');
29 | f.end();
30 | });
31 | });
32 |
--------------------------------------------------------------------------------
/test/fixtures/bad.js:
--------------------------------------------------------------------------------
1 | var __evil = eval( "3" );
2 |
--------------------------------------------------------------------------------
/test/fixtures/good.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | function a(b) {
4 | return b + 1;
5 | }
6 | a(1);
7 |
--------------------------------------------------------------------------------
/test/linter.js:
--------------------------------------------------------------------------------
1 | var assert = require('assert'),
2 | nodelint = require('../lib/nodelint'),
3 | linter = require('../lib/linter');
4 |
5 | suite('merge', function () {
6 | test('can merge when no conflict', function () {
7 | assert.deepEqual({a: 1, b: 2}, linter.merge({a: 1}, {b: 2}));
8 | });
9 |
10 | test('left side wins on merge', function () {
11 | assert.deepEqual({a: 1}, linter.merge({a: 1}, {a: 2}));
12 | });
13 |
14 | test('merge where one or more args is undefined', function () {
15 | assert.deepEqual({a: 1}, linter.merge({a: 1}, undefined));
16 |
17 | assert.deepEqual({a: 1}, linter.merge(undefined, {a: 1}));
18 | });
19 |
20 | test('merge where one object has inherited properties', function () {
21 | var util = require('util');
22 |
23 | function A() {
24 | this.parent = 'overridden';
25 | }
26 |
27 | function B() {
28 | this.own = 'overridden'
29 | }
30 | var c = { parent: 'orig', own: 'orig' };
31 |
32 | util.inherits(B, A);
33 |
34 | assert.deepEqual({ parent: 'orig', own: 'overridden' },
35 | linter.merge(new B(), c));
36 | });
37 | });
38 |
39 | suite('preprocessScript', function () {
40 | test('removes leading BOM', function () {
41 |
42 | assert.equal('var x=1;', linter.preprocessScript('var x=1;'));
43 |
44 | assert.equal('var x=1;', linter.preprocessScript('\uFEFFvar x=1;'));
45 |
46 | });
47 | test('removes shebang', function () {
48 |
49 | assert.equal('\nvar x=1;', linter.preprocessScript('#!/usr/bin/env node\nvar x=1;'));
50 |
51 | });
52 | });
53 |
54 | suite('lint', function () {
55 | var oldHome = process.env.HOME;
56 | teardown(function () {
57 | process.env.HOME = oldHome;
58 | });
59 |
60 | test('basic lint step', function () {
61 |
62 | var script = "// only a comment\n",
63 | options = {edition: 'latest'},
64 | JSLINT = nodelint.load(options.edition),
65 | result;
66 |
67 | // don't let user's config interfere with our test
68 | process.env.HOME = '';
69 |
70 | result = linter.doLint(JSLINT, script, options);
71 |
72 | assert.deepEqual(result.errors, []);
73 | assert.ok(result.ok);
74 | });
75 |
76 | test('lint finds error', function () {
77 |
78 | var script = "//TODO: remove this\n",
79 | options = {edition: '2013-09-22'},
80 | JSLINT = nodelint.load(options.edition),
81 | result;
82 |
83 | // don't let user's config interfere with our test
84 | process.env.HOME = '';
85 |
86 | result = linter.doLint(JSLINT, script, options);
87 |
88 | assert.strictEqual(1, result.errors.length);
89 | assert.strictEqual("Unexpected TODO comment.",
90 | result.errors[0].raw);
91 |
92 | });
93 |
94 | test('maxerr causes null error', function () {
95 | var JSLINT = nodelint.load('lib/jslint-2013-09-22.js'),
96 | script = "var __evil = eval('3')",
97 | options = {maxerr: 1},
98 | result;
99 |
100 | result = linter.doLint(JSLINT, script, options);
101 |
102 | assert.equal(result.ok, false);
103 | assert.equal(result.errors.length, 3);
104 | assert.equal(result.errors[2], null);
105 |
106 | });
107 |
108 |
109 | });
110 |
--------------------------------------------------------------------------------
/test/lintstream.js:
--------------------------------------------------------------------------------
1 | // this file is test/lintstream.js
2 | // tests for stream interface to JSLint
3 | //
4 | // Copyright 2014 Cubane Canada Inc.
5 | //
6 | // Released under modified MIT/BSD 3-clause license
7 | // See LICENSE for details.
8 |
9 | var assert = require('assert'),
10 | stream = require('../lib/stream'),
11 | LintStream = require('../lib/lintstream.js');
12 |
13 | suite('lintstream', function () {
14 | test('can create object', function () {
15 | var l = new LintStream();
16 |
17 | assert.ok(l instanceof LintStream);
18 | assert.ok(l instanceof stream.Transform);
19 | });
20 |
21 | test('can create object incorrectly', function () {
22 | var l = LintStream();
23 |
24 | assert.ok(l instanceof LintStream);
25 | assert.ok(l instanceof stream.Transform);
26 | });
27 |
28 | test('can lint a file', function (done) {
29 | var l = new LintStream();
30 |
31 | l.on('data', function (chunk) {
32 | assert.equal(chunk.file, 'example.js');
33 |
34 | assert.ok(chunk.linted.ok);
35 | assert.deepEqual(chunk.linted.errors, []);
36 | assert.deepEqual(chunk.linted.options, {});
37 |
38 | done();
39 | });
40 |
41 | l.write({file: 'example.js', body: ''});
42 | });
43 | });
44 |
--------------------------------------------------------------------------------
/test/main.js:
--------------------------------------------------------------------------------
1 | var assert = require('assert'),
2 | main;
3 |
4 | function mockConsole() {
5 | var c ={
6 | warnings: [],
7 | warn: function(str) {
8 | c.warnings.push(str);
9 | },
10 | loggings: [],
11 | log: function(str) {
12 | c.loggings.push(str);
13 | }
14 | };
15 |
16 | return c;
17 | }
18 |
19 | function mockProcess() {
20 | var p = {
21 | argv: ['jslint'],
22 | exit: function (c) {
23 | this.exitCode = c;
24 | this.events.exit.forEach(function (f) {
25 | f();
26 | });
27 | },
28 | doDrain: function() {
29 | this.events.drain.forEach(function (f) {
30 | f();
31 | });
32 | },
33 | events: { exit: [],
34 | drain: [] },
35 | on: function (event,f) {
36 | this.events[event].push(f);
37 | },
38 | stdout: {
39 | isTTY: true,
40 |
41 | /* mock: call callback right away */
42 | on: function (event, fn) {
43 | process.nextTick(function () {
44 | fn();
45 | p.doDrain();
46 | });
47 | },
48 | callbacks: {
49 | drain: []
50 | }
51 | },
52 | stderrWritings: [],
53 | stderr: {
54 | isTTY: true,
55 |
56 | /* mock: call callback right away */
57 | write: function (string) {
58 | p.stderrWritings.push(string);
59 | }
60 | }
61 | };
62 | return p;
63 | }
64 |
65 | function mockParsed() {
66 | return {
67 | argv: {
68 | remain: []
69 | }
70 | };
71 | }
72 |
73 | suite('jslint main', function () {
74 | var pro, con;
75 |
76 | setup(function () {
77 | main = require('../lib/main');
78 |
79 | con = mockConsole();
80 | pro = mockProcess();
81 |
82 | main.setConsole(con);
83 | main.setProcess(pro);
84 | });
85 |
86 | test('main - no args', function () {
87 | var parsed = mockParsed();
88 |
89 | main.runMain(parsed);
90 |
91 | assert.ok(main);
92 | assert.strictEqual(1, pro.exitCode);
93 | assert.strictEqual(2, con.warnings.length);
94 | });
95 |
96 | test('main - bad lint', function (done) {
97 | var parsed = mockParsed();
98 |
99 | parsed.argv.remain.push('test/fixtures/bad.js');
100 |
101 | main.runMain(parsed);
102 |
103 | pro.on('exit', function () {
104 | assert.equal(1, pro.exitCode);
105 | done();
106 | });
107 | });
108 |
109 |
110 | test('main - glob files', function (done) {
111 | // bail if glob not installed
112 | if (!main.glob) {
113 | assert.ok(true);
114 | done();
115 | return;
116 | }
117 |
118 | var parsed = mockParsed();
119 |
120 | parsed.argv.remain.push('lib/mai*.js');
121 |
122 | pro.on('exit', done);
123 |
124 | parsed.terse = true;
125 |
126 | main.runMain(parsed);
127 |
128 | assert.ok(main);
129 | });
130 |
131 | test('main - glob ignore node_modules', function (done) {
132 | var parsed = mockParsed();
133 |
134 | parsed.argv.remain.push('./lib/main.js');
135 | parsed.argv.remain.push('./node_modules/glob/*');
136 |
137 | parsed.filter = true;
138 |
139 | pro.on('exit', done);
140 |
141 | parsed.terse = true;
142 |
143 | main.runMain(parsed);
144 |
145 | assert.ok(main);
146 | });
147 |
148 | test('main - glob --no-filter includes node_modules', function (done) {
149 | var parsed = mockParsed();
150 |
151 | parsed.argv.remain.push('./lib/main.js');
152 | parsed.argv.remain.push('./node_modules/glob/*.js');
153 |
154 | parsed.filter = false;
155 |
156 | pro.on('exit', done);
157 |
158 | parsed.terse = true;
159 |
160 | main.runMain(parsed);
161 |
162 | assert.ok(main);
163 | });
164 |
165 | test('main - one file, not tty, json output', function (done) {
166 | var parsed = mockParsed();
167 |
168 | parsed.argv.remain.push('test/fixtures/good.js');
169 |
170 | parsed.json = true;
171 |
172 | pro.stdout.isTTY = false;
173 |
174 | pro.on('exit', function () {
175 | assert.strictEqual(0, pro.exitCode);
176 | done();
177 | });
178 |
179 | main.runMain(parsed);
180 |
181 | assert.ok(main);
182 |
183 | // expect process.exit(0) to be as yet uncalled
184 | assert.strictEqual(undefined, pro.exitCode);
185 | });
186 |
187 | test('todo in command-line options', function () {
188 | var o = main.commandOptions();
189 |
190 | assert.strictEqual(Boolean, o.todo);
191 | });
192 |
193 | function isBasicType(type, value) {
194 | return type(value).valueOf() === value;
195 | }
196 |
197 | test('isBasicType works', function () {
198 |
199 | assert.ok(isBasicType(Boolean, true));
200 | assert.ok(isBasicType(Boolean, false));
201 | assert.ok(isBasicType(Number, 1));
202 |
203 | assert.ok(!isBasicType(Boolean, 0));
204 | assert.ok(!isBasicType(Boolean, 1));
205 | assert.ok(!isBasicType(Number, false));
206 | assert.ok(!isBasicType(String, 1));
207 | assert.ok(!isBasicType(Number, '1'));
208 | });
209 |
210 | test('example jslint.conf contains only valid options', function (done) {
211 |
212 | var options = main.commandOptions(),
213 | fs = require('fs');
214 |
215 | fs.readFile("jslint.conf.example", function (err, file) {
216 | if (err) {
217 | throw err;
218 | }
219 |
220 | var example = JSON.parse(file),
221 | keys = Object.keys(example);
222 |
223 | keys.forEach(function(opt) {
224 | assert.ok(options.hasOwnProperty(opt));
225 |
226 | var type = options[opt],
227 | value = example[opt];
228 |
229 | // skip predef because arrays are hard
230 | if (opt !== "predef") {
231 | assert.ok(isBasicType(type, value));
232 | }
233 | });
234 |
235 | done();
236 | });
237 | });
238 |
239 | test('edition is a string (not Boolean) option', function () {
240 | var options = main.commandOptions();
241 |
242 | assert.equal(String, options.edition);
243 | });
244 |
245 | test('returns a version', function (done) {
246 |
247 | main.reportVersion(function (version) {
248 |
249 | assert.ok(/^node-jslint version:/.test(version));
250 | assert.ok(/ JSLint edition/.test(version));
251 | done();
252 | }, {} );
253 | });
254 |
255 | test('argument parsing: edition is a string', function () {
256 | var options = main.parseArgs(['node', 'jslint', '--edition=latest']);
257 |
258 | assert.equal('latest', options.edition);
259 | });
260 |
261 | test('argument parsing: can disable filter', function () {
262 | var options = main.parseArgs(['node', 'jslint', '--no-filter']);
263 |
264 | assert.equal(false, options.filter);
265 | });
266 |
267 | test('main -- report version', function (done) {
268 | main.runMain({version: true});
269 |
270 | done();
271 | });
272 |
273 | test('most data goes to console.log', function (done) {
274 | var rep = main.makeReporter({});
275 | rep.on('finish', function () {
276 | assert.equal(con.loggings.length, 1);
277 | assert.equal(con.loggings[0], 'log message');
278 | done();
279 | });
280 | rep.emit('data', 'log message');
281 | rep.end();
282 | });
283 |
284 | test('dots go to process.stderr', function (done) {
285 | var rep = main.makeReporter({});
286 | rep.on('finish', function () {
287 | assert.equal(pro.stderrWritings.length, 1);
288 | assert.equal(pro.stderrWritings[0], '.');
289 | done();
290 | });
291 | rep.emit('data', '.');
292 | rep.end();
293 | });
294 |
295 | test('quasi-programmatic interface', function (done) {
296 | var parsed = mockParsed();
297 |
298 | parsed.argv.remain.push('test/fixtures/bad.js');
299 | parsed.collector = true;
300 |
301 | main.runMain(parsed, function (err, report) {
302 | assert(report);
303 | done();
304 | });
305 |
306 | });
307 | });
308 |
--------------------------------------------------------------------------------
/test/nodelint.js:
--------------------------------------------------------------------------------
1 | var assert = require('assert'),
2 | nodelint = require('../lib/nodelint');
3 |
4 | suite('jslint loader', function () {
5 | test('load implicit jslint', function () {
6 | var JSLINT = nodelint.load();
7 | assert.ok(JSLINT);
8 | });
9 |
10 | test('load explicit jslint', function () {
11 | var JSLINT = nodelint.load('latest');
12 | assert.ok(JSLINT);
13 | });
14 |
15 | test('load nonexistent jslint', function () {
16 | // mock console object
17 | var con = { warnings: [],
18 | warn: function(str) {
19 | this.warnings.push(str);
20 | }
21 | };
22 | nodelint.setConsole(con);
23 |
24 | var JSLINT = nodelint.load('nonexistent');
25 | assert.ok(JSLINT);
26 |
27 | // expect console warning
28 | assert.strictEqual(1, con.warnings.length);
29 | });
30 |
31 | test('load by filename', function () {
32 | var JSLINT = nodelint.load('lib/jslint-2013-09-22.js');
33 |
34 | assert.ok(JSLINT);
35 | assert.equal('2013-09-22', JSLINT.edition);
36 | });
37 |
38 | test('looks like a filename', function () {
39 | var names = {
40 | 'foo': false,
41 | 'foo.js': true,
42 | 'foo/bar': true,
43 | 'foo\\bar': true
44 | };
45 |
46 | Object.keys(names).forEach(function (n) {
47 | assert.equal(names[n], nodelint.looksLikeFileName(n));
48 | });
49 | });
50 |
51 | });
52 |
--------------------------------------------------------------------------------
/test/options.js:
--------------------------------------------------------------------------------
1 | var assert = require('assert'),
2 | options = require('../lib/options');
3 |
4 | suite('addDefaults', function () {
5 | test('set node, es5 if unset', function () {
6 | assert.deepEqual({white: false, color: true, node: true, es5: true},
7 | options.addDefaults({white: false, color: true}));
8 | });
9 |
10 | test('explicit set prevents override', function () {
11 | assert.deepEqual({node: false, es5: false},
12 | options.addDefaults({es5: false, node: false}));
13 | });
14 | });
15 |
16 | suite('splitPredefs', function () {
17 | test('can split predefs', function () {
18 | assert.deepEqual({predef: ['foo', 'bar', 'baz']},
19 | options.splitPredefs({predef: "foo,bar,baz"}));
20 | });
21 | test('doesnt re-split predefs', function () {
22 | assert.deepEqual({predef: ['foo', 'bar', 'baz']},
23 | options.splitPredefs({predef: ['foo', 'bar', 'baz']}));
24 | });
25 | });
26 |
27 | suite('preprocessOptions', function() {
28 | test('accepts falsy options', function () {
29 | assert.deepEqual(options.preprocessOptions(undefined), options.preprocessOptions({}));
30 | });
31 | });
32 |
33 | suite('current dir config file', function () {
34 | var oldDir = process.cwd(),
35 | fs = require('fs.extra'),
36 | con;
37 |
38 | function mockConsole() {
39 | return {
40 | warnings: [],
41 | warn: function(str) {
42 | this.warnings.push(str);
43 | }
44 | };
45 | }
46 |
47 | suiteSetup(function (done) {
48 | // mock console object
49 | con = mockConsole();
50 | options.setConsole(con);
51 |
52 | fs.mkdir('test_config', function (err) {
53 | if (err) return done(err);
54 | process.chdir('test_config');
55 | done();
56 | });
57 | });
58 |
59 | suiteTeardown(function (done) {
60 | process.chdir(oldDir);
61 | fs.rmrf('test_config', function (err) {
62 | if (err) return done(err);
63 | done();
64 | });
65 | });
66 |
67 | test('read jslintrc when present', function () {
68 | fs.writeFileSync('jslintrc', '{"foo": 1}');
69 |
70 | assert.deepEqual({foo: 1}, options.loadAndParseConfig('jslintrc'));
71 | });
72 |
73 | test('no crash when empty jslintrc', function () {
74 | fs.writeFileSync('jslintrc', '');
75 |
76 | assert.deepEqual(undefined, options.loadAndParseConfig('jslintrc'));
77 |
78 | assert(/Error reading config file "jslintrc": SyntaxError: Unexpected end of /.test(con.warnings[0]));
79 | });
80 |
81 | test('no crash when malformed jslintrc', function () {
82 | fs.writeFileSync('jslintrc', "{ 'invalid json': true");
83 |
84 | assert.deepEqual(undefined, options.loadAndParseConfig('jslintrc'));
85 |
86 | assert(/Error reading config file "jslintrc": SyntaxError: Unexpected end of /.test(con.warnings[0]));
87 | });
88 |
89 | test('nonexistent .jslintrc => undefined', function () {
90 | assert.deepEqual(undefined, options.loadAndParseConfig('.jslintrc'));
91 | });
92 |
93 | test('merge global and local config correctly', function () {
94 | fs.writeFileSync('home', '{"foo": 1}');
95 | fs.writeFileSync('local', '{"foo": 2}');
96 |
97 | // no local = use home
98 | assert.deepEqual({foo: 1}, options.mergeConfigs(['home'], []));
99 |
100 | // local overrides home
101 | assert.deepEqual({foo: 2}, options.mergeConfigs(['home'], ['local']));
102 |
103 | // either branch of local overrides home
104 | assert.deepEqual({foo: 2}, options.mergeConfigs(['home'], ['filenotfound', 'local']));
105 | });
106 |
107 | test('load specific-named config files', function () {
108 | fs.writeFileSync('.jslintrc', '{"foo": "home"}');
109 | fs.writeFileSync('jslintrc', '{"foo": "local"}');
110 |
111 | // pretend current directory is home
112 | assert.deepEqual({foo: "local"}, options.loadConfig('.'));
113 |
114 | // Windows: process.env.HOME can be unset (undefined)
115 | assert.deepEqual({foo: "local"}, options.loadConfig(undefined));
116 | });
117 |
118 | test('load user-named config files', function () {
119 | fs.writeFileSync('user.jslint.conf', '{"bar": "user"}');
120 |
121 | // pretend current directory is home
122 | var conf = options.loadConfig('.', './user.jslint.conf');
123 |
124 | assert.equal("user", conf.bar);
125 |
126 | });
127 | });
128 |
--------------------------------------------------------------------------------
/test/regression.js:
--------------------------------------------------------------------------------
1 | var assert = require('assert'),
2 | nodelint = require('../lib/nodelint'),
3 | linter = require('../lib/linter');
4 |
5 | suite('case #101', function () {
6 | // https://github.com/reid/node-jslint/issues/101
7 | test('has warning with default options', function () {
8 |
9 | var options = {edition: 'latest'},
10 | JSLINT = nodelint.load(options.edition),
11 | script = "console.log('a');\n",
12 | result = linter.doLint(JSLINT, script, options);
13 |
14 | assert.ok(!result.ok);
15 | });
16 |
17 | test('no warning with node option', function () {
18 |
19 | var options = {edition: 'latest', node: true},
20 | JSLINT = nodelint.load(options.edition),
21 | script = "console.log('a');\n",
22 | result = linter.doLint(JSLINT, script, options);
23 |
24 | assert.ok(result.ok);
25 | });
26 |
27 | test('use es6 linter', function () {
28 |
29 | var options = {edition: 'es6', node: true},
30 | JSLINT = nodelint.load(options.edition),
31 | script = "console.log('a');\n",
32 | result = linter.doLint(JSLINT, script, options);
33 |
34 | assert.ok(result);
35 | });
36 |
37 | test('post-es6 versions report edition', function (done) {
38 | var options = {edition: '2015-05-08'},
39 | main = require('../lib/main');
40 |
41 | main.reportVersion(function (version) {
42 | assert.ok(/^node-jslint version:/.test(version));
43 | assert.ok(/ JSLint edition 2015-05-08/.test(version));
44 | done();
45 | }, options );
46 | });
47 | });
48 |
--------------------------------------------------------------------------------
/test/reporter.js:
--------------------------------------------------------------------------------
1 | var reporter = require('../lib/reporter'),
2 | assert = require('assert');
3 |
4 | suite('reporter', function () {
5 | 'use strict';
6 | var log,
7 | errorLint = {
8 | ok: false,
9 | errors: [
10 | err(1, 1, "Fake error 1."),
11 | err(2, 3, "Fake error 2.", "Fake evidence")
12 | ]
13 | },
14 | es6ErrorLint = {
15 | ok: false,
16 | errors: [ { line: 0,
17 | column: 3,
18 | message: "foo" } ],
19 | lines: [ "this is an evidence line" ]
20 | },
21 | es6Fudged = {
22 | ok: false,
23 | errors: [ { line: 0,
24 | column: 3,
25 | message: "foo" } ],
26 | option: { fudge: 1 },
27 | lines: [ "this is an evidence line" ]
28 | };
29 |
30 |
31 |
32 |
33 | function err(l, c, r, e) {
34 | var err = {
35 | line: l,
36 | character: c,
37 | reason: r
38 | };
39 | if(e) {
40 | err.evidence=e;
41 | }
42 | return err;
43 | };
44 |
45 | function newLog() {
46 | var o = {
47 | outLines: [],
48 | errLines: []
49 | };
50 |
51 | o.log = o.outLines.push.bind(o.outLines);
52 | o.err = o.errLines.push.bind(o.errLines);
53 |
54 | return o;
55 | }
56 |
57 | setup(function () {
58 | log = newLog();
59 | reporter.setLogger(log);
60 | });
61 |
62 | test('lint OK, no color, no terse', function () {
63 | reporter.report('example.js', {ok: true}, false, false);
64 |
65 | assert.deepEqual(1, log.outLines.length);
66 | assert.deepEqual("\nexample.js is OK.", log.outLines[0]);
67 | });
68 |
69 | test('lint OK, no color, terse', function () {
70 | reporter.report('example.js', {ok: true}, false, true);
71 |
72 | assert.deepEqual(1, log.errLines.length);
73 | assert.deepEqual(".", log.errLines[0]);
74 | });
75 |
76 | test('lint OK, color, no terse', function () {
77 | reporter.report('example.js', {ok: true}, true, false);
78 |
79 | assert.deepEqual(1, log.outLines.length);
80 | assert.notEqual(-1, log.outLines[0].search(/OK/));
81 | });
82 |
83 | test('lint bad, no color, no terse', function () {
84 | reporter.report('example.js', errorLint, false, false);
85 |
86 | assert.deepEqual(5, log.outLines.length);
87 | assert.equal(-1, log.outLines[0].search(/OK/));
88 |
89 | assert.deepEqual([
90 | '\nexample.js',
91 | ' #1 Fake error 1.',
92 | ' // Line 1, Pos 1',
93 | ' #2 Fake error 2.',
94 | ' Fake evidence // Line 2, Pos 3'
95 | ], log.outLines);
96 |
97 | });
98 |
99 | test('lint bad, no color, terse', function () {
100 | reporter.report('example.js', errorLint, false, true);
101 |
102 | assert.deepEqual(2, log.outLines.length);
103 | assert.equal(-1, log.outLines[0].search(/OK/));
104 |
105 | assert.deepEqual([
106 | 'example.js:1:1: Fake error 1.',
107 | 'example.js:2:3: Fake error 2.'
108 | ], log.outLines);
109 |
110 | });
111 |
112 | test('lint bad, color, no terse', function () {
113 | reporter.report('example.js', errorLint, true, false);
114 |
115 | assert.deepEqual(5, log.outLines.length);
116 | assert.equal(-1, log.outLines[0].search(/OK/));
117 |
118 | // no assertion re content: just force exercise of color branch
119 | });
120 |
121 | test('lint bad, es6 format', function () {
122 | reporter.report('example.js', es6ErrorLint, true, false);
123 | });
124 |
125 | test('fudge fudges output', function (done) {
126 | var reporter = require('../lib/reporter.js');
127 |
128 | reporter.report('example.js', es6Fudged, false, true);
129 |
130 | assert.deepEqual(1, log.outLines.length);
131 | assert.equal(log.outLines[0], 'example.js:1:4: foo');
132 | done();
133 | });
134 |
135 | });
136 |
--------------------------------------------------------------------------------
/test/reportstream.js:
--------------------------------------------------------------------------------
1 | var assert = require('assert'),
2 | stream = require('../lib/stream'),
3 | ReportStream = require('../lib/reportstream.js'),
4 | JSONReportStream = require('../lib/jsonreportstream.js'),
5 | CollectorStream = require('../lib/collectorstream.js');
6 |
7 | suite('reportstream', function () {
8 | test('can create object', function () {
9 | var r = new ReportStream();
10 |
11 | assert.ok(r instanceof ReportStream);
12 | assert.ok(r instanceof stream.Transform);
13 | });
14 |
15 | test('can create object incorrectly', function () {
16 | var r = ReportStream();
17 |
18 | assert.ok(r instanceof ReportStream);
19 | assert.ok(r instanceof stream.Transform);
20 | });
21 |
22 | test('can async', function (done) {
23 | var r = new ReportStream();
24 |
25 | r.on('data', function(chunk) {
26 | assert.deepEqual(chunk, '\nexample.js is OK.');
27 | done();
28 | });
29 |
30 | r.write({file: 'example.js', linted: {ok: true}});
31 | r.end();
32 | });
33 |
34 | test('can make a colorized reporter', function (done) {
35 | var r = new ReportStream({color: true});
36 |
37 | r.on('data', function(chunk) {
38 | assert.deepEqual(chunk, '\n\x1b[1mexample.js\x1b[0m is \x1b[32mOK\x1b[0m.');
39 | done();
40 | });
41 |
42 | r.write({file: 'example.js', linted: {ok: true}});
43 | r.end();
44 | });
45 |
46 | test('can make a terse reporter', function (done) {
47 | var r = new ReportStream({terse: true});
48 |
49 | r.on('data', function(chunk) {
50 | assert.deepEqual(chunk, '.');
51 | done();
52 | });
53 |
54 | r.write({file: 'example.js', linted: {ok: true}});
55 | r.end();
56 | });
57 |
58 | test('can make two reporters with diff. behavior', function (done) {
59 | var r1 = new ReportStream(),
60 | r2 = new ReportStream({terse: true});
61 |
62 | r1.on('data', function (chunk) {
63 | r2.write({file: 'example.js', linted: {ok: true}});
64 | r2.end();
65 | });
66 | r2.on('data', function (chunk) {
67 | assert.equal(chunk, '.');
68 | done();
69 | });
70 |
71 | r1.write({file: 'example.js', linted: {ok: true}});
72 | r1.end();
73 | });
74 |
75 | test('how about a JSONReportStream', function (done) {
76 | var r = new JSONReportStream();
77 |
78 | r.on('data', function (chunk) {
79 | assert.deepEqual(chunk, JSON.stringify(['example.js', null]));
80 | done();
81 | });
82 |
83 | r.write({file: 'example.js', linted: {ok: true}});
84 | r.end();
85 | });
86 |
87 | test('incorrectly construct a JSONReportStream', function (done) {
88 | var r = JSONReportStream();
89 |
90 | assert.ok(r instanceof JSONReportStream);
91 | assert.ok(r instanceof stream.Transform);
92 | done();
93 | });
94 | });
95 |
96 | suite('collectorstream', function () {
97 | test('can create object', function () {
98 | var r = new CollectorStream();
99 |
100 | assert.ok(r instanceof CollectorStream);
101 | assert.ok(r instanceof stream.Transform);
102 | });
103 |
104 | test('can create object incorrectly', function () {
105 | var r = CollectorStream();
106 |
107 | assert.ok(r instanceof CollectorStream);
108 | assert.ok(r instanceof stream.Transform);
109 | });
110 | });
111 |
--------------------------------------------------------------------------------