├── .github
└── workflows
│ └── main.yml
├── .gitignore
├── .nlint.json
├── LICENSE
├── README.md
├── build
├── lint.js
└── test.js
├── demo
├── .nlint.json
├── index.html
├── jquery-1.4.2.js
├── jquery-linedtextarea.css
├── jquery-linedtextarea.js
├── js.js
└── styles.css
├── jsonlint.js
├── package-lock.json
├── package.json
└── test
├── .nlint.json
├── files
├── json
│ ├── .nlint.json
│ ├── .nodelint.json
│ ├── Numeric.json
│ ├── comments.json
│ ├── empty.json
│ ├── endofarray.json
│ ├── multi-comment.json
│ ├── multi-object.json
│ ├── nested.json
│ ├── nocomments.json
│ ├── nomulticomment.json
│ ├── pit.json
│ ├── string.json
│ └── strings.json
└── test-files.js
├── munit.js
├── test-clean.js
└── test-invalid.js
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: Test
2 |
3 | on:
4 | push:
5 | branches: [main]
6 | pull_request:
7 | branches: [main]
8 |
9 | jobs:
10 | test:
11 | runs-on: ubuntu-latest
12 | strategy:
13 | matrix:
14 | node-version: [16.x, 18.x, 19.x]
15 | steps:
16 | - uses: actions/checkout@v3
17 | - name: Node.js ${{ matrix.node-version }}
18 | uses: actions/setup-node@v3
19 | with:
20 | node-version: ${{ matrix.node-version }}
21 | - run: yarn install
22 | - run: yarn test
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | build/results/
3 |
--------------------------------------------------------------------------------
/.nlint.json:
--------------------------------------------------------------------------------
1 | {
2 | "ignore": [
3 | ".git/",
4 | "node_modules/",
5 | "bin/",
6 | "demo/jquery-linedtextarea.js",
7 | "demo/jquery-1.4.2.js"
8 | ],
9 | "linters": {
10 | "jshint": {
11 | "boss": true,
12 | "node": true,
13 | "undef": true
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2011-present Corey Hart
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](http://badge.fury.io/js/jsonlint)  [](https://codeclimate.com/github/codenothing/jsonlint)
2 |
3 | # JSONLint
4 |
5 | JSONLint is a JSON Linter that allows for comments in your JSON Files.
6 |
7 | ## Installation
8 |
9 | For use with NodeJS, use NPM
10 |
11 | ```bash
12 | $ npm install -g json-lint
13 | ```
14 |
15 | For use in browser environments, include the script tag
16 |
17 | ```html
18 |
19 | ```
20 |
21 | ## Usage
22 |
23 | ```js
24 | // Require it for NodeJS environment
25 | var JSONLint = require("json-lint");
26 |
27 | // Run the JSON string through the linter
28 | var lint = JSONLint(json, options);
29 |
30 | // Do something with the error
31 | if (lint.error) {
32 | lint.error; // Error Message
33 | lint.line; // Line number in json file where error was found
34 | lint.character; // Character of line in json file where error was found
35 | }
36 | ```
37 |
38 | JSONLint takes two arguments, and throws an error if found.
39 |
40 | - _string_ **json**: JSON String to be linted
41 |
42 | - _object_ **options**: Object of options.
43 |
44 | ## Options
45 |
46 | There is currently only 1 option that is handled: **comments**, which defaults to true if not set.
47 |
--------------------------------------------------------------------------------
/build/lint.js:
--------------------------------------------------------------------------------
1 | require( 'nlint' ).render( __dirname + '/../' );
2 |
--------------------------------------------------------------------------------
/build/test.js:
--------------------------------------------------------------------------------
1 | var munit = global.munit = require( 'munit' );
2 |
3 | // Only stop test suite when running make test
4 | if ( ! process.env.NODE_TEST_NO_SKIP ) {
5 | munit.defaults.settings.stopOnFail = true;
6 | }
7 |
8 | munit.render( __dirname + '/../test/', {
9 | results: __dirname + '/results/'
10 | });
11 |
--------------------------------------------------------------------------------
/demo/.nlint.json:
--------------------------------------------------------------------------------
1 | {
2 | "linters": {
3 | "jshint": {
4 | "node": false,
5 | "browser": true,
6 | "predef": {
7 | "jQuery": false
8 | }
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/demo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | JSONLint 0.1.0: JSON Lint with comments
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
JSONLint 0.1.0
16 |
17 |
18 |
Allow Comments
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/demo/jquery-linedtextarea.css:
--------------------------------------------------------------------------------
1 | /**
2 | * jQuery Lined Textarea Plugin
3 | * http://alan.blog-city.com/jquerylinedtextarea.htm
4 | *
5 | * Copyright (c) 2010 Alan Williamson
6 | *
7 | * Released under the MIT License:
8 | * http://www.opensource.org/licenses/mit-license.php
9 | *
10 | * Usage:
11 | * Displays a line number count column to the left of the textarea
12 | *
13 | * Class up your textarea with a given class, or target it directly
14 | * with JQuery Selectors
15 | *
16 | * $(".lined").linedtextarea({
17 | * selectedLine: 10,
18 | * selectedClass: 'lineselect'
19 | * });
20 | *
21 | */
22 |
23 | .linedwrap {
24 | border: 1px solid #c0c0c0;
25 | padding: 3px;
26 | }
27 |
28 | .linedtextarea {
29 | padding: 0px;
30 | margin: 0px;
31 | }
32 |
33 | .linedtextarea textarea, .linedwrap .codelines .lineno {
34 | font-size: 9pt;
35 | font-family: monospace;
36 | line-height: normal !important;
37 | }
38 |
39 | .linedtextarea textarea {
40 | padding-right:0.3em;
41 | padding-top:0.3em;
42 | border: 0;
43 | }
44 |
45 | .linedwrap .lines {
46 | margin-top: 0px;
47 | width: 50px;
48 | float: left;
49 | overflow: hidden;
50 | border-right: 1px solid #c0c0c0;
51 | margin-right: 10px;
52 | }
53 |
54 | .linedwrap .codelines {
55 | padding-top: 5px;
56 | }
57 |
58 | .linedwrap .codelines .lineno {
59 | color:#AAAAAA;
60 | padding-right: 0.5em;
61 | padding-top: 0.0em;
62 | text-align: right;
63 | white-space: nowrap;
64 | }
65 |
66 | .linedwrap .codelines .lineselect {
67 | color: red;
68 | }
69 |
--------------------------------------------------------------------------------
/demo/jquery-linedtextarea.js:
--------------------------------------------------------------------------------
1 | /**
2 | * jQuery Lined Textarea Plugin
3 | * http://alan.blog-city.com/jquerylinedtextarea.htm
4 | *
5 | * Copyright (c) 2010 Alan Williamson
6 | *
7 | * Version:
8 | * $Id: jquery-linedtextarea.js 464 2010-01-08 10:36:33Z alan $
9 | *
10 | * Released under the MIT License:
11 | * http://www.opensource.org/licenses/mit-license.php
12 | *
13 | * Usage:
14 | * Displays a line number count column to the left of the textarea
15 | *
16 | * Class up your textarea with a given class, or target it directly
17 | * with JQuery Selectors
18 | *
19 | * $(".lined").linedtextarea({
20 | * selectedLine: 10,
21 | * selectedClass: 'lineselect'
22 | * });
23 | *
24 | * History:
25 | * - 2010.01.08: Fixed a Google Chrome layout problem
26 | * - 2010.01.07: Refactored code for speed/readability; Fixed horizontal sizing
27 | * - 2010.01.06: Initial Release
28 | *
29 | */
30 | (function($) {
31 |
32 | $.fn.linedtextarea = function(options) {
33 |
34 | // Get the Options
35 | var opts = $.extend({}, $.fn.linedtextarea.defaults, options);
36 |
37 |
38 | /*
39 | * Helper function to make sure the line numbers are always
40 | * kept up to the current system
41 | */
42 | var fillOutLines = function(codeLines, h, lineNo){
43 | while ( (codeLines.height() - h ) <= 0 ){
44 | if ( lineNo == opts.selectedLine )
45 | codeLines.append("" + lineNo + "
");
46 | else
47 | codeLines.append("" + lineNo + "
");
48 |
49 | lineNo++;
50 | }
51 | return lineNo;
52 | };
53 |
54 |
55 | /*
56 | * Iterate through each of the elements are to be applied to
57 | */
58 | return this.each(function() {
59 | var lineNo = 1;
60 | var textarea = $(this);
61 |
62 | /* Turn off the wrapping of as we don't want to screw up the line numbers */
63 | textarea.attr("wrap", "off");
64 | textarea.css({resize:'none'});
65 | var originalTextAreaWidth = textarea.outerWidth();
66 |
67 | /* Wrap the text area in the elements we need */
68 | textarea.wrap("");
69 | var linedTextAreaDiv = textarea.parent().wrap("");
70 | var linedWrapDiv = linedTextAreaDiv.parent();
71 |
72 | linedWrapDiv.prepend("");
73 |
74 | var linesDiv = linedWrapDiv.find(".lines");
75 | linesDiv.height( textarea.height() + 6 );
76 |
77 |
78 | /* Draw the number bar; filling it out where necessary */
79 | linesDiv.append( "" );
80 | var codeLinesDiv = linesDiv.find(".codelines");
81 | lineNo = fillOutLines( codeLinesDiv, linesDiv.height(), 1 );
82 |
83 | /* Move the textarea to the selected line */
84 | if ( opts.selectedLine != -1 && !isNaN(opts.selectedLine) ){
85 | var fontSize = parseInt( textarea.height() / (lineNo-2) );
86 | var position = parseInt( fontSize * opts.selectedLine ) - (textarea.height()/2);
87 | textarea[0].scrollTop = position;
88 | }
89 |
90 |
91 | /* Set the width */
92 | var sidebarWidth = linesDiv.outerWidth();
93 | var paddingHorizontal = parseInt( linedWrapDiv.css("border-left-width"), 10 ) +
94 | parseInt( linedWrapDiv.css("border-right-width"), 10 ) +
95 | parseInt( linedWrapDiv.css("padding-left"), 10 ) +
96 | parseInt( linedWrapDiv.css("padding-right"), 10 );
97 | var linedWrapDivNewWidth = originalTextAreaWidth - paddingHorizontal;
98 | var textareaNewWidth = originalTextAreaWidth - sidebarWidth - paddingHorizontal - 20;
99 |
100 | textarea.width( textareaNewWidth );
101 | linedWrapDiv.width( linedWrapDivNewWidth );
102 |
103 |
104 |
105 | /* React to the scroll event */
106 | textarea.scroll( function(tn){
107 | var domTextArea = $(this)[0];
108 | var scrollTop = domTextArea.scrollTop;
109 | var clientHeight = domTextArea.clientHeight;
110 | codeLinesDiv.css( {'margin-top': (-1*scrollTop) + "px"} );
111 | lineNo = fillOutLines( codeLinesDiv, scrollTop + clientHeight, lineNo );
112 | });
113 |
114 |
115 | /* Should the textarea get resized outside of our control */
116 | textarea.resize( function(tn){
117 | var domTextArea = $(this)[0];
118 | linesDiv.height( domTextArea.clientHeight + 6 );
119 | });
120 | });
121 | };
122 |
123 | // default options
124 | $.fn.linedtextarea.defaults = {
125 | selectedLine: -1,
126 | selectedClass: 'lineselect'
127 | };
128 | })(jQuery);
129 |
--------------------------------------------------------------------------------
/demo/js.js:
--------------------------------------------------------------------------------
1 | jQuery(function(){
2 | var textarea = jQuery('textarea').linedtextarea(),
3 | wrapper = jQuery('.linedwrap'),
4 | results = jQuery('#results'),
5 | comments = jQuery('input[type=checkbox]')[ 0 ],
6 | lint;
7 |
8 | jQuery('button').click(function(){
9 | wrapper.removeClass('error').removeClass('success');
10 | results.removeClass('error').removeClass('success');
11 | lint = window.JSONLint( textarea.val(), { comments: comments.checked } );
12 |
13 | if ( ! lint.error ) {
14 | wrapper.addClass('success');
15 | results.addClass('success').html( 'Valid JSON.' );
16 | }
17 | else {
18 | wrapper.addClass('error');
19 | results.addClass('error').html([
20 | lint.error + "
" +
21 | "Evidence: " + lint.evidence + "
" +
22 | "Line: " + lint.line + "
" +
23 | "Character: " + lint.character
24 | ].join(''));
25 | }
26 | });
27 | });
28 |
--------------------------------------------------------------------------------
/demo/styles.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-size: 12pt;
3 | }
4 |
5 | #content {
6 | width: 950px;
7 | margin: 20px auto;
8 | }
9 |
10 | .linedwrap.success {
11 | border: 2px solid green;
12 | }
13 |
14 | .linedwrap.error {
15 | border: 2px solid red;
16 | }
17 |
18 | textarea {
19 | width: 950px;
20 | height: 400px;
21 | font-size: 10pt;
22 | }
23 |
24 | button {
25 | padding: 5px 9px;
26 | margin: 5px 0;
27 | border: 1px solid #e1e1e1;
28 | background: #f5f5f5;
29 | }
30 |
31 | #results {
32 | padding: 10px;
33 | margin: 10px 0;
34 | }
35 |
36 | #results.success {
37 | background: #c9ffc7;
38 | }
39 |
40 | #results.error {
41 | background: #ffc7c7;
42 | }
43 |
--------------------------------------------------------------------------------
/jsonlint.js:
--------------------------------------------------------------------------------
1 | (function( glob, undefined ) {
2 |
3 | var rnumber = /[0-9]/,
4 | rnewline = /(\r\n|\r|\n)/,
5 | revidence = /\r\n|\r|\n/,
6 | rwhitespace = /(\s|\t)/,
7 | rvalidsolidus = /\\("|\\|\/|b|f|n|r|t|u[0-9]{4})/,
8 | rE = /^(\-|\+)?[0-9]/;
9 |
10 |
11 | // Leeeeeeerrrrroooyy Jennkkkiiinnnss
12 | function JSONLint( json, options ) {
13 | var self = this;
14 |
15 | if ( ! ( self instanceof JSONLint ) ) {
16 | return new JSONLint( json, options );
17 | }
18 |
19 | // Argument handling
20 | self.json = json || '';
21 | self.options = options || {};
22 | self.lower = self.json.toLowerCase();
23 |
24 | // Allow comments by default
25 | if ( ! self.options.hasOwnProperty( 'comments' ) ) {
26 | self.options.comments = true;
27 | }
28 |
29 | // Internals
30 | self.c = '';
31 | self.i = -1;
32 | self.length = self.json.length;
33 | self.line = 1;
34 | self.character = 0;
35 | self._evidence = self.json.split( revidence );
36 | self.endblock = '';
37 | self.commabreak = false;
38 |
39 | try {
40 | self.render();
41 | } catch ( e ) {
42 | if ( typeof e != 'string' ) {
43 | throw e;
44 | }
45 | self.error = e;
46 | self.setEvidence();
47 | }
48 | }
49 |
50 |
51 | // Meta (Please change contact info for republishing with changes)
52 | JSONLint.contact = "Corey Hart (corey@codenothing.com)";
53 | JSONLint.version = '0.1.1';
54 |
55 |
56 | // Methods
57 | JSONLint.prototype = {
58 |
59 | // Rendering Start
60 | render: function(){
61 | var self = this, peek = '', content = false;
62 |
63 | for ( ; ++self.i < self.length; ) {
64 | self.c = self.json[ self.i ];
65 | self.character++;
66 |
67 | if ( self.options.comments && self.c == '/' ) {
68 | peek = self.json[ self.i + 1 ];
69 | if ( peek == '*' ) {
70 | self.multicomment();
71 | }
72 | else if ( peek == '/' ) {
73 | self.comment();
74 | }
75 | else {
76 | throw "Unknown character '/', maybe a comment?";
77 | }
78 | }
79 | else if ( rnewline.exec( self.c ) ) {
80 | self.line++;
81 | self.character = 0;
82 | }
83 | else if ( rwhitespace.exec( self.c ) ) {
84 | continue;
85 | }
86 | else if ( content ) {
87 | throw "Unknown character '" + self.c + "', expecting end of file.";
88 | }
89 | else if ( self.c == '[' ) {
90 | content = true;
91 | self.array();
92 | }
93 | else if ( self.c == '{' ) {
94 | content = true;
95 | self.object();
96 | }
97 | else {
98 | throw "Unknown character '" + self.c + "', expecting opening block '{' or '[', or maybe a comment";
99 | }
100 | }
101 |
102 | // Check for pure whitespace
103 | if ( ! content ) {
104 | throw "Invalid JSON, no content.";
105 | }
106 | },
107 |
108 | // Multi line comment
109 | multicomment: function(){
110 | var self = this;
111 |
112 | for ( ; ++self.i < self.length; ) {
113 | self.c = self.json[ self.i ];
114 | self.character++;
115 |
116 | if ( self.c == "*" && self.json[ self.i + 1 ] == "/" ) {
117 | self.i++;
118 | self.character++;
119 | break;
120 | }
121 | else if ( rnewline.exec( self.c ) ) {
122 | self.line++;
123 | self.character = 0;
124 | }
125 | }
126 | },
127 |
128 | // Single line comment
129 | comment: function(){
130 | var self = this;
131 |
132 | for ( ; ++self.i < self.length; ) {
133 | self.c = self.json[ self.i ];
134 | self.character++;
135 |
136 | if ( rnewline.exec( self.c ) ) {
137 | self.line++;
138 | self.character = 0;
139 | break;
140 | }
141 | }
142 | },
143 |
144 | // Array Block
145 | array: function(){
146 | // Keep reference of current endblock
147 | var self = this,
148 | _endblock = self.endblock,
149 | _commabreak = self.commabreak,
150 | ended = false;
151 |
152 | self.endblock = ']';
153 | self.commabreak = false;
154 | while ( ( ended = self.value() ) !== true && self.i < self.length ) {
155 | // Do nothing, just wait for array values to finish
156 | }
157 |
158 | if ( ! ended ) {
159 | throw "EOF Error. Expecting closing ']'";
160 | }
161 |
162 | // Reset previous endblock
163 | self.endblock = _endblock;
164 | self.commabreak = _commabreak;
165 | },
166 |
167 | // Object Block
168 | object: function(){
169 | // Keep reference of current endblock
170 | var self = this,
171 | _endblock = self.endblock,
172 | _commabreak = self.commabreak,
173 | found = false, peek = '', empty = true;
174 |
175 | self.endblock = '}';
176 | self.commabreak = false;
177 | for ( ; ++self.i < self.length; ) {
178 | self.c = self.json[ self.i ];
179 | self.character++;
180 |
181 | if ( self.options.comments && self.c == '/' ) {
182 | peek = self.json[ self.i + 1 ];
183 | if ( peek == '*' ) {
184 | self.multicomment();
185 | }
186 | else if ( peek == '/' ) {
187 | self.comment();
188 | }
189 | else {
190 | throw "Unknown character '/', maybe a comment?";
191 | }
192 | }
193 | else if ( rnewline.exec( self.c ) ) {
194 | self.line++;
195 | self.character = 0;
196 | }
197 | else if ( rwhitespace.exec( self.c ) ) {
198 | continue;
199 | }
200 | else if ( self.c == '"' ) {
201 | empty = false;
202 | if ( self.key() === true ) {
203 | // Reset old endblock
204 | self.endblock = _endblock;
205 | self.commabreak = _commabreak;
206 | found = true;
207 | break;
208 | }
209 | }
210 | else if ( empty && self.c == '}' ) {
211 | self.endblock = _endblock;
212 | self.commabreak = _commabreak;
213 | found = true;
214 | break;
215 | }
216 | else {
217 | throw "Unknown Character '" + self.c + "', expecting a string for key statement.";
218 | }
219 | }
220 |
221 | if ( ! found ) {
222 | throw "EOF Error, expecting closing '}'.";
223 | }
224 | },
225 |
226 | // Key Statement
227 | key: function(){
228 | var self = this;
229 | self.string();
230 |
231 | for ( var peek = ''; ++self.i < self.length; ) {
232 | self.c = self.json[ self.i ];
233 | self.character++;
234 |
235 | if ( self.options.comments && self.c == '/' ) {
236 | peek = self.json[ self.i + 1 ];
237 | if ( peek == '*' ) {
238 | self.multicomment();
239 | }
240 | else if ( peek == '/' ) {
241 | self.comment();
242 | }
243 | else {
244 | throw "Unknown character '/', maybe a comment?";
245 | }
246 | }
247 | else if ( rnewline.exec( self.c ) ) {
248 | self.line++;
249 | self.character = 0;
250 | }
251 | else if ( rwhitespace.exec( self.c ) ) {
252 | continue;
253 | }
254 | else if ( self.c == ":" ) {
255 | return self.value();
256 | }
257 | else {
258 | throw "Unknown Character '" + self.c + "', expecting a semicolon.";
259 | }
260 | }
261 | },
262 |
263 | // Value statement
264 | value: function(){
265 | var self = this, peek = '';
266 |
267 | for ( ; ++self.i < self.length; ) {
268 | self.c = self.json[ self.i ];
269 | self.character++;
270 |
271 | if ( self.options.comments && self.c == '/' ) {
272 | peek = self.json[ self.i + 1 ];
273 | if ( peek == '*' ) {
274 | self.multicomment();
275 | }
276 | else if ( peek == '/' ) {
277 | self.comment();
278 | }
279 | else {
280 | throw "Unknown character '/', maybe a comment?";
281 | }
282 | }
283 | else if ( rnewline.exec( self.c ) ) {
284 | self.line++;
285 | self.character = 0;
286 | }
287 | else if ( rwhitespace.exec( self.c ) ) {
288 | continue;
289 | }
290 | else if ( self.c == '{' ) {
291 | self.object();
292 | return self.endval();
293 | }
294 | else if ( self.c == '[' ) {
295 | self.array();
296 | return self.endval();
297 | }
298 | else if ( self.c == '"' ) {
299 | self.string();
300 | return self.endval();
301 | }
302 | else if ( self.json.indexOf( 'true', self.i ) === self.i ) {
303 | self.i += 3;
304 | self.character += 3;
305 | return self.endval();
306 | }
307 | else if ( self.json.indexOf( 'false', self.i ) === self.i ) {
308 | self.i += 4;
309 | self.character += 4;
310 | return self.endval();
311 | }
312 | else if ( self.json.indexOf( 'null', self.i ) === self.i ) {
313 | self.i += 3;
314 | self.character += 3;
315 | return self.endval();
316 | }
317 | else if ( self.c == '-' || rnumber.exec( self.c ) ) {
318 | return self.numeric();
319 | }
320 | else if ( self.c == ']' && self.endblock == ']' ) {
321 | if ( self.commabreak ) {
322 | throw "Unexpected End Of Array Error. Expecting a value statement.";
323 | }
324 | return true;
325 | }
326 | else {
327 | throw "Unknown Character '" + self.c + "', expecting a value.";
328 | }
329 | }
330 | },
331 |
332 | // String statement
333 | string: function(){
334 | var self = this, found = false, m;
335 |
336 | for ( ; ++self.i < self.length; ) {
337 | self.c = self.json[ self.i ];
338 | self.character++;
339 |
340 | if ( self.c == "\\" ) {
341 | if ( ( m = rvalidsolidus.exec( self.json.substr( self.i ) ) ) && m.index === 0 ) {
342 | self.i += m[ 1 ].length;
343 | self.character += m[ 1 ].length;
344 | }
345 | else {
346 | throw "Invalid Reverse Solidus '\\' declaration.";
347 | }
348 | }
349 | else if ( rnewline.exec( self.c ) ) {
350 | self.line++;
351 | self.character = 0;
352 | }
353 | else if ( self.c == '"' ) {
354 | found = true;
355 | break;
356 | }
357 | }
358 |
359 | // Make sure close string is found
360 | if ( ! found ) {
361 | throw "EOF: No close string '\"' found.";
362 | }
363 | },
364 |
365 | // Numeric Value
366 | numeric: function(){
367 | var self = this,
368 | negative = true,
369 | decimal = null,
370 | e = null,
371 | peek = '';
372 |
373 | // We need to jump back a character to catch the whole number
374 | self.i--;
375 | self.character--;
376 | for ( ; ++self.i < self.length; ) {
377 | self.c = self.json[ self.i ];
378 | self.character++;
379 |
380 | // Handle initial negative sign
381 | if ( negative ) {
382 | negative = false;
383 | if ( self.c == '-' ) {
384 | if ( ! rnumber.exec( self.json[ self.i + 1 ] ) ) {
385 | throw "Unknown Character '" + self.c + "' following a negative, expecting a numeric value.";
386 | }
387 | continue;
388 | }
389 | }
390 |
391 | // Only a single decimal is allowed in a numeric value
392 | if ( decimal && self.c == '.' ) {
393 | decimal = false;
394 | e = true;
395 | continue;
396 | }
397 | // Only a single e notation is allowed in a numeric value
398 | else if ( e && self.c.toLowerCase() == 'e' ) {
399 | e = false;
400 | negative = true;
401 | if ( rE.exec( self.json.substr( self.i + 1, 2 ) ) ) {
402 | self.character++;
403 | self.i++;
404 | }
405 | else {
406 | self.character++;
407 | throw "Unknown Character '" + self.json[ self.i + 1 ] + "' following e notation, expecting a numeric value.";
408 | }
409 | }
410 | // Normal Digit
411 | else if ( rnumber.exec( self.c ) ) {
412 | if ( decimal === null ) {
413 | decimal = true;
414 | }
415 | }
416 | // Assume end of number, and allow endval to handle it
417 | else {
418 | // Jump back a character to include the current one
419 | self.i--;
420 | self.character--;
421 | return self.endval();
422 | }
423 | }
424 | },
425 |
426 | // Ending a value statement
427 | endval: function(){
428 | var self = this, peek = '';
429 | self.commabreak = false;
430 |
431 | for ( ; ++self.i < self.length; ) {
432 | self.c = self.json[ self.i ];
433 | self.character++;
434 |
435 | if ( self.options.comments && self.c == '/' ) {
436 | peek = self.json[ self.i + 1 ];
437 | if ( peek == '*' ) {
438 | self.multicomment();
439 | }
440 | else if ( peek == '/' ) {
441 | self.comment();
442 | }
443 | else {
444 | throw "Unknown character '/', maybe a comment?";
445 | }
446 | }
447 | else if ( rnewline.exec( self.c ) ) {
448 | self.line++;
449 | self.character = 0;
450 | }
451 | else if ( rwhitespace.exec( self.c ) ) {
452 | continue;
453 | }
454 | else if ( self.c == ',' ) {
455 | self.commabreak = true;
456 | break;
457 | }
458 | else if ( self.c == self.endblock ) {
459 | return true;
460 | }
461 | else {
462 | throw "Unknown Character '" + self.c + "', expecting a comma or a closing '" + self.endblock + "'";
463 | }
464 | }
465 | },
466 |
467 | // Expose line of the error
468 | setEvidence: function(){
469 | var self = this, start = self.line - 5, end = start + 8, evidence = '';
470 |
471 | // Min start
472 | if ( start < 0 ) {
473 | start = 0;
474 | end = 8;
475 | }
476 |
477 | // Max end
478 | if ( end >= self._evidence.length ) {
479 | end = self._evidence.length;
480 | }
481 |
482 | // Evidence display
483 | for ( ; start < end; start++ ) {
484 | evidence += ( start === ( self.line - 1 ) ? "-> " : " " ) +
485 | ( start + 1 ) + '| ' +
486 | self._evidence[ start ] + "\n";
487 | }
488 |
489 | // Set the evidence display
490 | self.evidence = evidence;
491 | }
492 | };
493 |
494 |
495 | // Check for nodejs module system
496 | if ( typeof exports == 'object' && typeof module == 'object' ) {
497 | module.exports = JSONLint;
498 | }
499 | // In a browser
500 | else {
501 | glob.JSONLint = JSONLint;
502 | }
503 |
504 | })( this );
505 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "json-lint",
3 | "version": "0.1.1",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "json-lint",
9 | "version": "0.1.1",
10 | "devDependencies": {
11 | "munit": "0.0.8",
12 | "nlint": "0.0.7"
13 | },
14 | "engines": {
15 | "node": ">=0.5"
16 | }
17 | },
18 | "node_modules/argv": {
19 | "version": "0.0.2",
20 | "resolved": "https://registry.npmjs.org/argv/-/argv-0.0.2.tgz",
21 | "integrity": "sha512-dEamhpPEwRUBpLNHeuCm/v+g0anFByHahxodVO/BbAarHVBBg2MccCwf9K+o1Pof+2btdnkJelYVUWjW/VrATw==",
22 | "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
23 | "dev": true,
24 | "engines": {
25 | "node": ">=0.6.10"
26 | }
27 | },
28 | "node_modules/async": {
29 | "version": "0.2.9",
30 | "resolved": "https://registry.npmjs.org/async/-/async-0.2.9.tgz",
31 | "integrity": "sha512-OAtM6mexGteNKdU29wcUfRW+VuBr94A3hx9h9yzBnPaQAbKoW1ORd68XM4CCAOpdL5wlNFgO29hsY1TKv2vAKw==",
32 | "dev": true
33 | },
34 | "node_modules/cli": {
35 | "version": "0.4.5",
36 | "resolved": "https://registry.npmjs.org/cli/-/cli-0.4.5.tgz",
37 | "integrity": "sha512-dbn5HyeJWSOU58RwOEiF1VWrl7HRvDsKLpu0uiI/vExH6iNoyUzjB5Mr3IJY5DVUfnbpe9793xw4DFJVzC9nWQ==",
38 | "dev": true,
39 | "dependencies": {
40 | "glob": ">= 3.1.4"
41 | },
42 | "engines": {
43 | "node": ">=0.2.5"
44 | }
45 | },
46 | "node_modules/colors": {
47 | "version": "0.6.0-1",
48 | "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.0-1.tgz",
49 | "integrity": "sha512-ZaQtySU44lmZRP6M+CovFWnu7QnxLTsr/3wURb7BCOV1/gKjUb/3uu3NsLR+fvA2Jfs6sNfwcVq0Tp2mWYbuxg==",
50 | "dev": true,
51 | "engines": {
52 | "node": ">=0.1.90"
53 | }
54 | },
55 | "node_modules/commander": {
56 | "version": "1.2.0",
57 | "resolved": "https://registry.npmjs.org/commander/-/commander-1.2.0.tgz",
58 | "integrity": "sha512-4AzfHvT/zLkvp+LVOHxZ02sHTuNrtoTnu8qEoJbpcL3nTnFhoNmAml1UV+96k9y5Tgz7jIjsom546WIi2iif0g==",
59 | "dev": true,
60 | "dependencies": {
61 | "keypress": "0.1.x"
62 | },
63 | "engines": {
64 | "node": ">= 0.6.x"
65 | }
66 | },
67 | "node_modules/console-browserify": {
68 | "version": "0.1.6",
69 | "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-0.1.6.tgz",
70 | "integrity": "sha512-FJahZyF+dLKrC7h4DOq5JsHA+f0cLJD3TR1+0CK3n6phtdrVAPsZZKq+PZRmo2RYSOHvvs8kNhU4uRiSZUbSbA==",
71 | "dev": true
72 | },
73 | "node_modules/core-util-is": {
74 | "version": "1.0.3",
75 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
76 | "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
77 | "dev": true
78 | },
79 | "node_modules/csslint": {
80 | "version": "0.10.0",
81 | "resolved": "https://registry.npmjs.org/csslint/-/csslint-0.10.0.tgz",
82 | "integrity": "sha512-mlD1oDw0juzD4dOthyAytPC4NsXqVZeIYAScIbgoYGY+Q7vcrhOQrH7js4JVZXcrOyKxi8ytC42ENMwO9CdnMQ==",
83 | "dev": true,
84 | "dependencies": {
85 | "parserlib": "~0.2.2"
86 | },
87 | "bin": {
88 | "csslint": "cli.js"
89 | },
90 | "engines": {
91 | "node": ">=0.8.0"
92 | }
93 | },
94 | "node_modules/domelementtype": {
95 | "version": "1.3.1",
96 | "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
97 | "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
98 | "dev": true
99 | },
100 | "node_modules/domhandler": {
101 | "version": "2.1.0",
102 | "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.1.0.tgz",
103 | "integrity": "sha512-4Qr6GTzdsnKVGdYferZT3na5zkswztvfsoyprP/j2bLf1l3pUTamwYvNVldkEYFG6Ll+3eV5mVk0zgRr6iI+SA==",
104 | "dev": true,
105 | "dependencies": {
106 | "domelementtype": "1"
107 | }
108 | },
109 | "node_modules/domutils": {
110 | "version": "1.1.6",
111 | "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.1.6.tgz",
112 | "integrity": "sha512-ZeagMzMKyk9GSFMqV3x3uHgRN36hLpSOF6LIRXmftce0UUqFsAx/azJAJ4Jc+9DYKmwROH5HLOcOu1OPARWwNg==",
113 | "dev": true,
114 | "dependencies": {
115 | "domelementtype": "1"
116 | }
117 | },
118 | "node_modules/esprima": {
119 | "version": "1.0.3",
120 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.3.tgz",
121 | "integrity": "sha512-Cc9SOu665lwATZT2tzVgeiZlqpnN6wKs2BvWrJ5nQSzGaivjL1MBYxyy951anmdsgMZNTssPXBRJq8W5vgRNcQ==",
122 | "dev": true,
123 | "bin": {
124 | "esparse": "bin/esparse.js",
125 | "esvalidate": "bin/esvalidate.js"
126 | },
127 | "engines": {
128 | "node": ">=0.4.0"
129 | }
130 | },
131 | "node_modules/glob": {
132 | "version": "3.2.7",
133 | "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.7.tgz",
134 | "integrity": "sha512-DaADhstzS42quruVnBdaZUrbSv3I+8K+7QQ5WrKQ1oFcBYJR9iuDNoz4MVxJlOhL4b8ETTAFZA6x755SiaUx2A==",
135 | "dev": true,
136 | "dependencies": {
137 | "inherits": "2",
138 | "minimatch": "~0.2.11"
139 | },
140 | "engines": {
141 | "node": "*"
142 | }
143 | },
144 | "node_modules/graceful-fs": {
145 | "version": "2.0.3",
146 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-2.0.3.tgz",
147 | "integrity": "sha512-hcj/NTUWv+C3MbqrVb9F+aH6lvTwEHJdx2foBxlrVq5h6zE8Bfu4pv4CAAqbDcZrw/9Ak5lsRXlY9Ao8/F0Tuw==",
148 | "deprecated": "please upgrade to graceful-fs 4 for compatibility with current and future versions of Node.js",
149 | "dev": true,
150 | "engines": {
151 | "node": ">=0.4.0"
152 | }
153 | },
154 | "node_modules/htmlparser2": {
155 | "version": "3.3.0",
156 | "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.3.0.tgz",
157 | "integrity": "sha512-Z8i63n7seuPvRe1PQyrjmoVStv7bjMa0skrOl/k6tnT/5WpPNrzWLB1Hg/dJxBXH/M6KZvm25JQGVCiQGxURLQ==",
158 | "dev": true,
159 | "dependencies": {
160 | "domelementtype": "1",
161 | "domhandler": "2.1",
162 | "domutils": "1.1",
163 | "readable-stream": "1.0"
164 | }
165 | },
166 | "node_modules/inherits": {
167 | "version": "2.0.4",
168 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
169 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
170 | "dev": true
171 | },
172 | "node_modules/isarray": {
173 | "version": "0.0.1",
174 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
175 | "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==",
176 | "dev": true
177 | },
178 | "node_modules/jscs": {
179 | "version": "1.2.4",
180 | "resolved": "https://registry.npmjs.org/jscs/-/jscs-1.2.4.tgz",
181 | "integrity": "sha512-9UqO78RWOajGBICUV8/FdCL/883uYrkioJ7fBR6rs4W0Uiu0m2EAhQO9ByPh/4Qvx/atRVWHmwHreOiuFFeMgg==",
182 | "deprecated": "JSCS has merged with ESLint! See - https://medium.com/@markelog/jscs-end-of-the-line-bc9bf0b3fdb2",
183 | "dev": true,
184 | "dependencies": {
185 | "colors": "0.6.0-1",
186 | "commander": "1.2.0",
187 | "esprima": "1.0.3",
188 | "glob": "3.2.7",
189 | "minimatch": "0.2.12",
190 | "vow": "0.3.9",
191 | "vow-fs": "0.2.3",
192 | "xmlbuilder": "1.1.2"
193 | },
194 | "bin": {
195 | "jscs": "bin/jscs"
196 | },
197 | "engines": {
198 | "node": ">= 0.8.0"
199 | }
200 | },
201 | "node_modules/jshint": {
202 | "version": "2.4.3",
203 | "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.4.3.tgz",
204 | "integrity": "sha512-bmwlrJCItW3tFoN70MivI2I0DCnIAp0xNrHtPq5bJ6aHu3dVVR51aVDP76LjmiS12SPRRGS0eVSbELT5zjtOPA==",
205 | "dev": true,
206 | "dependencies": {
207 | "cli": "0.4.x",
208 | "console-browserify": "0.1.x",
209 | "htmlparser2": "3.3.x",
210 | "minimatch": "0.x.x",
211 | "shelljs": "0.1.x",
212 | "underscore": "1.4.x"
213 | },
214 | "bin": {
215 | "jshint": "bin/jshint"
216 | }
217 | },
218 | "node_modules/json-lint": {
219 | "version": "0.1.0",
220 | "resolved": "https://registry.npmjs.org/json-lint/-/json-lint-0.1.0.tgz",
221 | "integrity": "sha512-QoBMCAo3sFnAl2nvCcrt5NmjqMRejlghhMvZ0ykhgfNpp7ukp1te7dP6q2o4fkvl03t08t75njni+y6S7jiHLg==",
222 | "dev": true,
223 | "engines": {
224 | "node": ">=0.5"
225 | }
226 | },
227 | "node_modules/json5": {
228 | "version": "0.2.0",
229 | "resolved": "https://registry.npmjs.org/json5/-/json5-0.2.0.tgz",
230 | "integrity": "sha512-jzu3hxGhztAzldgKTbsW240mtPIgR6foddu9HqQgpv0ML2RcjE0mjyLro0XE92YAQYpTpcByY80vVzlKOM64xA==",
231 | "dev": true,
232 | "bin": {
233 | "json5": "lib/cli.js"
234 | },
235 | "engines": {
236 | "node": "*"
237 | }
238 | },
239 | "node_modules/keypress": {
240 | "version": "0.1.0",
241 | "resolved": "https://registry.npmjs.org/keypress/-/keypress-0.1.0.tgz",
242 | "integrity": "sha512-x0yf9PL/nx9Nw9oLL8ZVErFAk85/lslwEP7Vz7s5SI1ODXZIgit3C5qyWjw4DxOuO/3Hb4866SQh28a1V1d+WA==",
243 | "dev": true
244 | },
245 | "node_modules/lru-cache": {
246 | "version": "2.7.3",
247 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz",
248 | "integrity": "sha512-WpibWJ60c3AgAz8a2iYErDrcT2C7OmKnsWhIcHOjkUHFjkXncJhtLxNSqUmxRxRunpb5I8Vprd7aNSd2NtksJQ==",
249 | "dev": true
250 | },
251 | "node_modules/minimatch": {
252 | "version": "0.2.12",
253 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.12.tgz",
254 | "integrity": "sha512-jeVdfKmlomLerf8ecetSr6gLS0OXnLRluhnv9Rf2yj70NsD8uVGqrpwTqJGKpIF8VTRR9fQAl62CZ1eNIEMk3A==",
255 | "deprecated": "Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue",
256 | "dev": true,
257 | "dependencies": {
258 | "lru-cache": "2",
259 | "sigmund": "~1.0.0"
260 | },
261 | "engines": {
262 | "node": "*"
263 | }
264 | },
265 | "node_modules/munit": {
266 | "version": "0.0.8",
267 | "resolved": "https://registry.npmjs.org/munit/-/munit-0.0.8.tgz",
268 | "integrity": "sha512-V95XdHT6lPE03Av2rz6S0r4WuPsUjXhHfqB7Q6nMO3WDtCw8YPB2TvY1HX2urG0/a4tiUNUgLywne+HaIS7Z8g==",
269 | "dev": true,
270 | "dependencies": {
271 | "argv": "0.0.2",
272 | "async": "0.2.9",
273 | "graceful-fs": "2.0.3"
274 | },
275 | "bin": {
276 | "munit": "bin/munit"
277 | },
278 | "engines": {
279 | "node": ">=0.8"
280 | }
281 | },
282 | "node_modules/nlint": {
283 | "version": "0.0.7",
284 | "resolved": "https://registry.npmjs.org/nlint/-/nlint-0.0.7.tgz",
285 | "integrity": "sha512-XvhJkl4nBbYLJGmiDv5Ga3A9TsvF/HZawXXfrMKp1GZg+j+WKabWT7NePY2ohW1fUASfSl+iIENuodFvCVb1LA==",
286 | "dev": true,
287 | "dependencies": {
288 | "argv": "0.0.2",
289 | "async": "0.2.10",
290 | "csslint": "0.10.0",
291 | "jscs": "1.2.4",
292 | "jshint": "2.4.3",
293 | "json-lint": "0.1.0",
294 | "json5": "0.2.0"
295 | },
296 | "bin": {
297 | "nlint": "bin/nlint"
298 | },
299 | "engines": {
300 | "node": ">=0.6.10"
301 | }
302 | },
303 | "node_modules/nlint/node_modules/async": {
304 | "version": "0.2.10",
305 | "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
306 | "integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==",
307 | "dev": true
308 | },
309 | "node_modules/node-uuid": {
310 | "version": "1.4.0",
311 | "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.0.tgz",
312 | "integrity": "sha512-Vns3Mj1WBYNwPchf2T/pt9q2GUpM97JvLekAkAwWYX1H2kIxYQ+jUb3GWmaNRboP5XoS3p3nxptIv00I+cOtLg==",
313 | "deprecated": "Use uuid module instead",
314 | "dev": true
315 | },
316 | "node_modules/parserlib": {
317 | "version": "0.2.5",
318 | "resolved": "https://registry.npmjs.org/parserlib/-/parserlib-0.2.5.tgz",
319 | "integrity": "sha512-SNu7MNq2Lp5aHXM1HZLyXEHpSAVpHU1y3pvPpxnq6jVK/5WIpKv9aA11PyMeiW9Y+EORem2J7XhiEIaOKizUHA==",
320 | "dev": true
321 | },
322 | "node_modules/readable-stream": {
323 | "version": "1.0.34",
324 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
325 | "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==",
326 | "dev": true,
327 | "dependencies": {
328 | "core-util-is": "~1.0.0",
329 | "inherits": "~2.0.1",
330 | "isarray": "0.0.1",
331 | "string_decoder": "~0.10.x"
332 | }
333 | },
334 | "node_modules/shelljs": {
335 | "version": "0.1.4",
336 | "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.1.4.tgz",
337 | "integrity": "sha512-UkXLBuUzAJwkal/0eYnQs8LpXQ4grKL5kPtA0RkUzhj1khUvw5Z2d717GRTRclDWQ+Y14yWkiM9cJX2CwSHxpw==",
338 | "dev": true,
339 | "bin": {
340 | "shjs": "bin/shjs"
341 | },
342 | "engines": {
343 | "node": "*"
344 | }
345 | },
346 | "node_modules/sigmund": {
347 | "version": "1.0.1",
348 | "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
349 | "integrity": "sha512-fCvEXfh6NWpm+YSuY2bpXb/VIihqWA6hLsgboC+0nl71Q7N7o2eaCW8mJa/NLvQhs6jpd3VZV4UiUQlV6+lc8g==",
350 | "dev": true
351 | },
352 | "node_modules/string_decoder": {
353 | "version": "0.10.31",
354 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
355 | "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==",
356 | "dev": true
357 | },
358 | "node_modules/underscore": {
359 | "version": "1.4.4",
360 | "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.4.4.tgz",
361 | "integrity": "sha512-ZqGrAgaqqZM7LGRzNjLnw5elevWb5M8LEoDMadxIW3OWbcv72wMMgKdwOKpd5Fqxe8choLD8HN3iSj3TUh/giQ==",
362 | "dev": true
363 | },
364 | "node_modules/vow": {
365 | "version": "0.3.9",
366 | "resolved": "https://registry.npmjs.org/vow/-/vow-0.3.9.tgz",
367 | "integrity": "sha512-fc9eU77ORvSDGa4qAcs9WLZkvH3TrAlGwhEGDPiPeGzRjrZ9BU5BlkrKAvyZUdCNOezG5BkZ8m30h/XvWuDYXQ==",
368 | "dev": true,
369 | "engines": {
370 | "node": ">= 0.4.0"
371 | }
372 | },
373 | "node_modules/vow-fs": {
374 | "version": "0.2.3",
375 | "resolved": "https://registry.npmjs.org/vow-fs/-/vow-fs-0.2.3.tgz",
376 | "integrity": "sha512-v4nH+/0tzAFxZzPJJv/0IvoNkAVlzs9DSy1kYMRgyGHaPwvvpFgFbg2uHmX80Kyuq493+jEhx9eHX4pcVLeB+g==",
377 | "dev": true,
378 | "dependencies": {
379 | "node-uuid": "1.4.0",
380 | "vow-queue": "0.0.2"
381 | },
382 | "engines": {
383 | "node": ">= 0.6.0"
384 | },
385 | "peerDependencies": {
386 | "vow": ">= 0.3.9"
387 | }
388 | },
389 | "node_modules/vow-queue": {
390 | "version": "0.0.2",
391 | "resolved": "https://registry.npmjs.org/vow-queue/-/vow-queue-0.0.2.tgz",
392 | "integrity": "sha512-k5FUzXd0fZGThIzkMCpgunxOEzZZu9V08Bomrgfu37qlHJAjF7G4Qa5ATcd1Kl0fiuDAltAFyQK0kescFUDz4w==",
393 | "dev": true,
394 | "engines": {
395 | "node": ">= 0.8.0"
396 | },
397 | "peerDependencies": {
398 | "vow": "~0.3.9"
399 | }
400 | },
401 | "node_modules/xmlbuilder": {
402 | "version": "1.1.2",
403 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-1.1.2.tgz",
404 | "integrity": "sha512-gspXU5NGrWif4BFbSGHuojHkGzzFABcODPZfOogi5twMIVNNxDpxkzem7B/vlzIyCT49I1xa2apzsGttVMaT9g==",
405 | "dev": true,
406 | "dependencies": {
407 | "underscore": ">=1.5.x"
408 | },
409 | "engines": {
410 | "node": ">=0.2.0"
411 | }
412 | },
413 | "node_modules/xmlbuilder/node_modules/underscore": {
414 | "version": "1.13.6",
415 | "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz",
416 | "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==",
417 | "dev": true
418 | }
419 | },
420 | "dependencies": {
421 | "argv": {
422 | "version": "0.0.2",
423 | "resolved": "https://registry.npmjs.org/argv/-/argv-0.0.2.tgz",
424 | "integrity": "sha512-dEamhpPEwRUBpLNHeuCm/v+g0anFByHahxodVO/BbAarHVBBg2MccCwf9K+o1Pof+2btdnkJelYVUWjW/VrATw==",
425 | "dev": true
426 | },
427 | "async": {
428 | "version": "0.2.9",
429 | "resolved": "https://registry.npmjs.org/async/-/async-0.2.9.tgz",
430 | "integrity": "sha512-OAtM6mexGteNKdU29wcUfRW+VuBr94A3hx9h9yzBnPaQAbKoW1ORd68XM4CCAOpdL5wlNFgO29hsY1TKv2vAKw==",
431 | "dev": true
432 | },
433 | "cli": {
434 | "version": "0.4.5",
435 | "resolved": "https://registry.npmjs.org/cli/-/cli-0.4.5.tgz",
436 | "integrity": "sha512-dbn5HyeJWSOU58RwOEiF1VWrl7HRvDsKLpu0uiI/vExH6iNoyUzjB5Mr3IJY5DVUfnbpe9793xw4DFJVzC9nWQ==",
437 | "dev": true,
438 | "requires": {
439 | "glob": ">= 3.1.4"
440 | }
441 | },
442 | "colors": {
443 | "version": "0.6.0-1",
444 | "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.0-1.tgz",
445 | "integrity": "sha512-ZaQtySU44lmZRP6M+CovFWnu7QnxLTsr/3wURb7BCOV1/gKjUb/3uu3NsLR+fvA2Jfs6sNfwcVq0Tp2mWYbuxg==",
446 | "dev": true
447 | },
448 | "commander": {
449 | "version": "1.2.0",
450 | "resolved": "https://registry.npmjs.org/commander/-/commander-1.2.0.tgz",
451 | "integrity": "sha512-4AzfHvT/zLkvp+LVOHxZ02sHTuNrtoTnu8qEoJbpcL3nTnFhoNmAml1UV+96k9y5Tgz7jIjsom546WIi2iif0g==",
452 | "dev": true,
453 | "requires": {
454 | "keypress": "0.1.x"
455 | }
456 | },
457 | "console-browserify": {
458 | "version": "0.1.6",
459 | "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-0.1.6.tgz",
460 | "integrity": "sha512-FJahZyF+dLKrC7h4DOq5JsHA+f0cLJD3TR1+0CK3n6phtdrVAPsZZKq+PZRmo2RYSOHvvs8kNhU4uRiSZUbSbA==",
461 | "dev": true
462 | },
463 | "core-util-is": {
464 | "version": "1.0.3",
465 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
466 | "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
467 | "dev": true
468 | },
469 | "csslint": {
470 | "version": "0.10.0",
471 | "resolved": "https://registry.npmjs.org/csslint/-/csslint-0.10.0.tgz",
472 | "integrity": "sha512-mlD1oDw0juzD4dOthyAytPC4NsXqVZeIYAScIbgoYGY+Q7vcrhOQrH7js4JVZXcrOyKxi8ytC42ENMwO9CdnMQ==",
473 | "dev": true,
474 | "requires": {
475 | "parserlib": "~0.2.2"
476 | }
477 | },
478 | "domelementtype": {
479 | "version": "1.3.1",
480 | "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
481 | "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
482 | "dev": true
483 | },
484 | "domhandler": {
485 | "version": "2.1.0",
486 | "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.1.0.tgz",
487 | "integrity": "sha512-4Qr6GTzdsnKVGdYferZT3na5zkswztvfsoyprP/j2bLf1l3pUTamwYvNVldkEYFG6Ll+3eV5mVk0zgRr6iI+SA==",
488 | "dev": true,
489 | "requires": {
490 | "domelementtype": "1"
491 | }
492 | },
493 | "domutils": {
494 | "version": "1.1.6",
495 | "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.1.6.tgz",
496 | "integrity": "sha512-ZeagMzMKyk9GSFMqV3x3uHgRN36hLpSOF6LIRXmftce0UUqFsAx/azJAJ4Jc+9DYKmwROH5HLOcOu1OPARWwNg==",
497 | "dev": true,
498 | "requires": {
499 | "domelementtype": "1"
500 | }
501 | },
502 | "esprima": {
503 | "version": "1.0.3",
504 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.3.tgz",
505 | "integrity": "sha512-Cc9SOu665lwATZT2tzVgeiZlqpnN6wKs2BvWrJ5nQSzGaivjL1MBYxyy951anmdsgMZNTssPXBRJq8W5vgRNcQ==",
506 | "dev": true
507 | },
508 | "glob": {
509 | "version": "3.2.7",
510 | "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.7.tgz",
511 | "integrity": "sha512-DaADhstzS42quruVnBdaZUrbSv3I+8K+7QQ5WrKQ1oFcBYJR9iuDNoz4MVxJlOhL4b8ETTAFZA6x755SiaUx2A==",
512 | "dev": true,
513 | "requires": {
514 | "inherits": "2",
515 | "minimatch": "~0.2.11"
516 | }
517 | },
518 | "graceful-fs": {
519 | "version": "2.0.3",
520 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-2.0.3.tgz",
521 | "integrity": "sha512-hcj/NTUWv+C3MbqrVb9F+aH6lvTwEHJdx2foBxlrVq5h6zE8Bfu4pv4CAAqbDcZrw/9Ak5lsRXlY9Ao8/F0Tuw==",
522 | "dev": true
523 | },
524 | "htmlparser2": {
525 | "version": "3.3.0",
526 | "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.3.0.tgz",
527 | "integrity": "sha512-Z8i63n7seuPvRe1PQyrjmoVStv7bjMa0skrOl/k6tnT/5WpPNrzWLB1Hg/dJxBXH/M6KZvm25JQGVCiQGxURLQ==",
528 | "dev": true,
529 | "requires": {
530 | "domelementtype": "1",
531 | "domhandler": "2.1",
532 | "domutils": "1.1",
533 | "readable-stream": "1.0"
534 | }
535 | },
536 | "inherits": {
537 | "version": "2.0.4",
538 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
539 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
540 | "dev": true
541 | },
542 | "isarray": {
543 | "version": "0.0.1",
544 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
545 | "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==",
546 | "dev": true
547 | },
548 | "jscs": {
549 | "version": "1.2.4",
550 | "resolved": "https://registry.npmjs.org/jscs/-/jscs-1.2.4.tgz",
551 | "integrity": "sha512-9UqO78RWOajGBICUV8/FdCL/883uYrkioJ7fBR6rs4W0Uiu0m2EAhQO9ByPh/4Qvx/atRVWHmwHreOiuFFeMgg==",
552 | "dev": true,
553 | "requires": {
554 | "colors": "0.6.0-1",
555 | "commander": "1.2.0",
556 | "esprima": "1.0.3",
557 | "glob": "3.2.7",
558 | "minimatch": "0.2.12",
559 | "vow": "0.3.9",
560 | "vow-fs": "0.2.3",
561 | "xmlbuilder": "1.1.2"
562 | }
563 | },
564 | "jshint": {
565 | "version": "2.4.3",
566 | "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.4.3.tgz",
567 | "integrity": "sha512-bmwlrJCItW3tFoN70MivI2I0DCnIAp0xNrHtPq5bJ6aHu3dVVR51aVDP76LjmiS12SPRRGS0eVSbELT5zjtOPA==",
568 | "dev": true,
569 | "requires": {
570 | "cli": "0.4.x",
571 | "console-browserify": "0.1.x",
572 | "htmlparser2": "3.3.x",
573 | "minimatch": "0.x.x",
574 | "shelljs": "0.1.x",
575 | "underscore": "1.4.x"
576 | }
577 | },
578 | "json-lint": {
579 | "version": "0.1.0",
580 | "resolved": "https://registry.npmjs.org/json-lint/-/json-lint-0.1.0.tgz",
581 | "integrity": "sha512-QoBMCAo3sFnAl2nvCcrt5NmjqMRejlghhMvZ0ykhgfNpp7ukp1te7dP6q2o4fkvl03t08t75njni+y6S7jiHLg==",
582 | "dev": true
583 | },
584 | "json5": {
585 | "version": "0.2.0",
586 | "resolved": "https://registry.npmjs.org/json5/-/json5-0.2.0.tgz",
587 | "integrity": "sha512-jzu3hxGhztAzldgKTbsW240mtPIgR6foddu9HqQgpv0ML2RcjE0mjyLro0XE92YAQYpTpcByY80vVzlKOM64xA==",
588 | "dev": true
589 | },
590 | "keypress": {
591 | "version": "0.1.0",
592 | "resolved": "https://registry.npmjs.org/keypress/-/keypress-0.1.0.tgz",
593 | "integrity": "sha512-x0yf9PL/nx9Nw9oLL8ZVErFAk85/lslwEP7Vz7s5SI1ODXZIgit3C5qyWjw4DxOuO/3Hb4866SQh28a1V1d+WA==",
594 | "dev": true
595 | },
596 | "lru-cache": {
597 | "version": "2.7.3",
598 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz",
599 | "integrity": "sha512-WpibWJ60c3AgAz8a2iYErDrcT2C7OmKnsWhIcHOjkUHFjkXncJhtLxNSqUmxRxRunpb5I8Vprd7aNSd2NtksJQ==",
600 | "dev": true
601 | },
602 | "minimatch": {
603 | "version": "0.2.12",
604 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.12.tgz",
605 | "integrity": "sha512-jeVdfKmlomLerf8ecetSr6gLS0OXnLRluhnv9Rf2yj70NsD8uVGqrpwTqJGKpIF8VTRR9fQAl62CZ1eNIEMk3A==",
606 | "dev": true,
607 | "requires": {
608 | "lru-cache": "2",
609 | "sigmund": "~1.0.0"
610 | }
611 | },
612 | "munit": {
613 | "version": "0.0.8",
614 | "resolved": "https://registry.npmjs.org/munit/-/munit-0.0.8.tgz",
615 | "integrity": "sha512-V95XdHT6lPE03Av2rz6S0r4WuPsUjXhHfqB7Q6nMO3WDtCw8YPB2TvY1HX2urG0/a4tiUNUgLywne+HaIS7Z8g==",
616 | "dev": true,
617 | "requires": {
618 | "argv": "0.0.2",
619 | "async": "0.2.9",
620 | "graceful-fs": "2.0.3"
621 | }
622 | },
623 | "nlint": {
624 | "version": "0.0.7",
625 | "resolved": "https://registry.npmjs.org/nlint/-/nlint-0.0.7.tgz",
626 | "integrity": "sha512-XvhJkl4nBbYLJGmiDv5Ga3A9TsvF/HZawXXfrMKp1GZg+j+WKabWT7NePY2ohW1fUASfSl+iIENuodFvCVb1LA==",
627 | "dev": true,
628 | "requires": {
629 | "argv": "0.0.2",
630 | "async": "0.2.10",
631 | "csslint": "0.10.0",
632 | "jscs": "1.2.4",
633 | "jshint": "2.4.3",
634 | "json-lint": "0.1.0",
635 | "json5": "0.2.0"
636 | },
637 | "dependencies": {
638 | "async": {
639 | "version": "0.2.10",
640 | "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
641 | "integrity": "sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==",
642 | "dev": true
643 | }
644 | }
645 | },
646 | "node-uuid": {
647 | "version": "1.4.0",
648 | "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.0.tgz",
649 | "integrity": "sha512-Vns3Mj1WBYNwPchf2T/pt9q2GUpM97JvLekAkAwWYX1H2kIxYQ+jUb3GWmaNRboP5XoS3p3nxptIv00I+cOtLg==",
650 | "dev": true
651 | },
652 | "parserlib": {
653 | "version": "0.2.5",
654 | "resolved": "https://registry.npmjs.org/parserlib/-/parserlib-0.2.5.tgz",
655 | "integrity": "sha512-SNu7MNq2Lp5aHXM1HZLyXEHpSAVpHU1y3pvPpxnq6jVK/5WIpKv9aA11PyMeiW9Y+EORem2J7XhiEIaOKizUHA==",
656 | "dev": true
657 | },
658 | "readable-stream": {
659 | "version": "1.0.34",
660 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
661 | "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==",
662 | "dev": true,
663 | "requires": {
664 | "core-util-is": "~1.0.0",
665 | "inherits": "~2.0.1",
666 | "isarray": "0.0.1",
667 | "string_decoder": "~0.10.x"
668 | }
669 | },
670 | "shelljs": {
671 | "version": "0.1.4",
672 | "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.1.4.tgz",
673 | "integrity": "sha512-UkXLBuUzAJwkal/0eYnQs8LpXQ4grKL5kPtA0RkUzhj1khUvw5Z2d717GRTRclDWQ+Y14yWkiM9cJX2CwSHxpw==",
674 | "dev": true
675 | },
676 | "sigmund": {
677 | "version": "1.0.1",
678 | "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
679 | "integrity": "sha512-fCvEXfh6NWpm+YSuY2bpXb/VIihqWA6hLsgboC+0nl71Q7N7o2eaCW8mJa/NLvQhs6jpd3VZV4UiUQlV6+lc8g==",
680 | "dev": true
681 | },
682 | "string_decoder": {
683 | "version": "0.10.31",
684 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
685 | "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==",
686 | "dev": true
687 | },
688 | "underscore": {
689 | "version": "1.4.4",
690 | "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.4.4.tgz",
691 | "integrity": "sha512-ZqGrAgaqqZM7LGRzNjLnw5elevWb5M8LEoDMadxIW3OWbcv72wMMgKdwOKpd5Fqxe8choLD8HN3iSj3TUh/giQ==",
692 | "dev": true
693 | },
694 | "vow": {
695 | "version": "0.3.9",
696 | "resolved": "https://registry.npmjs.org/vow/-/vow-0.3.9.tgz",
697 | "integrity": "sha512-fc9eU77ORvSDGa4qAcs9WLZkvH3TrAlGwhEGDPiPeGzRjrZ9BU5BlkrKAvyZUdCNOezG5BkZ8m30h/XvWuDYXQ==",
698 | "dev": true
699 | },
700 | "vow-fs": {
701 | "version": "0.2.3",
702 | "resolved": "https://registry.npmjs.org/vow-fs/-/vow-fs-0.2.3.tgz",
703 | "integrity": "sha512-v4nH+/0tzAFxZzPJJv/0IvoNkAVlzs9DSy1kYMRgyGHaPwvvpFgFbg2uHmX80Kyuq493+jEhx9eHX4pcVLeB+g==",
704 | "dev": true,
705 | "requires": {
706 | "node-uuid": "1.4.0",
707 | "vow-queue": "0.0.2"
708 | }
709 | },
710 | "vow-queue": {
711 | "version": "0.0.2",
712 | "resolved": "https://registry.npmjs.org/vow-queue/-/vow-queue-0.0.2.tgz",
713 | "integrity": "sha512-k5FUzXd0fZGThIzkMCpgunxOEzZZu9V08Bomrgfu37qlHJAjF7G4Qa5ATcd1Kl0fiuDAltAFyQK0kescFUDz4w==",
714 | "dev": true,
715 | "requires": {}
716 | },
717 | "xmlbuilder": {
718 | "version": "1.1.2",
719 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-1.1.2.tgz",
720 | "integrity": "sha512-gspXU5NGrWif4BFbSGHuojHkGzzFABcODPZfOogi5twMIVNNxDpxkzem7B/vlzIyCT49I1xa2apzsGttVMaT9g==",
721 | "dev": true,
722 | "requires": {
723 | "underscore": ">=1.5.x"
724 | },
725 | "dependencies": {
726 | "underscore": {
727 | "version": "1.13.6",
728 | "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz",
729 | "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==",
730 | "dev": true
731 | }
732 | }
733 | }
734 | }
735 | }
736 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "json-lint",
3 | "description": "JSON Lint with comments",
4 | "url": "https://github.com/codenothing/jsonlint",
5 | "author": "Corey Hart ",
6 | "version": "0.1.1",
7 | "main": "./jsonlint.js",
8 | "homepage": "https://github.com/codenothing/jsonlint",
9 | "repository": {
10 | "type": "git",
11 | "url": "git://github.com/codenothing/jsonlint.git"
12 | },
13 | "keywords": [
14 | "json",
15 | "lint",
16 | "comments"
17 | ],
18 | "files": [
19 | "jsonlint.js",
20 | "package.json",
21 | "README.md",
22 | "LICENSE"
23 | ],
24 | "engines": {
25 | "node": ">=0.5"
26 | },
27 | "bugs": {
28 | "url": "https://github.com/codenothing/jsonlint/issues"
29 | },
30 | "scripts": {
31 | "clean": "rm -rf build/results/",
32 | "lint": "node build/lint.js",
33 | "test": "npm run clean && npm run lint && node build/test.js"
34 | },
35 | "devDependencies": {
36 | "nlint": "0.0.7",
37 | "munit": "0.0.8"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/test/.nlint.json:
--------------------------------------------------------------------------------
1 | {
2 | "linters": {
3 | "jshint": {
4 | "predef": {
5 | "JSONLint": false,
6 | "munit": false
7 | }
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/files/json/.nlint.json:
--------------------------------------------------------------------------------
1 | {
2 | "ignore": [
3 | "string.json",
4 | "multi-object.json",
5 | "endofarray.json"
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/test/files/json/.nodelint.json:
--------------------------------------------------------------------------------
1 | {
2 | "ignore": [
3 | "string.json",
4 | "multi-object.json",
5 | "endofarray.json"
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/test/files/json/Numeric.json:
--------------------------------------------------------------------------------
1 | /**
2 | * This JSON file provided by CSSCompression(http://www.codenothing.com/css-compressor/)
3 | * Real world example to test length
4 | */
5 | {
6 | // Decimal removal
7 | "decimal": {
8 | "remove": {
9 | "params": [ "1.0em" ],
10 | "expect": "1em"
11 | },
12 | "negative remove": {
13 | "params": [ "-1.0em" ],
14 | "expect": "-1em"
15 | },
16 | "positive remove": {
17 | "params": [ "+1.0em" ],
18 | "expect": "1em"
19 | },
20 | "long decimal int": {
21 | "params": [ "1.00000em" ],
22 | "expect": "1em"
23 | },
24 | "negative long decimal int": {
25 | "params": [ "-1.00000em" ],
26 | "expect": "-1em"
27 | },
28 | /*
29 | Adding nested Multi line comments
30 | Just for fun
31 | */
32 | "positive long decimal int": {
33 | "params": [ "+1.00000em" ],
34 | "expect": "1em"
35 | },
36 | "long decimal": {
37 | "params": [ "1.10000em" ],
38 | "expect": "1.1em"
39 | },
40 | "negative long decimal": {
41 | "params": [ "-1.10000em" ],
42 | "expect": "-1.1em"
43 | },
44 | "keep": {
45 | "params": [ "1.059em" ],
46 | "expect": "1.059em"
47 | },
48 | "negative keep": {
49 | "params": [ "-1.059em" ],
50 | "expect": "-1.059em"
51 | }
52 | },
53 |
54 | // Unit removal
55 | "units": {
56 | "remove": {
57 | /*
58 | Adding nested Multi line comments
59 | Just for fun
60 | */
61 | "params": [ "0px" ],
62 | "expect": "0"
63 | },
64 | "percentage": {
65 | "params": [ "0%" ],
66 | "expect": "0"
67 | },
68 | "non-zero": {
69 | "params": [ "50px" ],
70 | "expect": "50px"
71 | },
72 | "non-zero decimal": {
73 | "params": [ "50.0px" ],
74 | "expect": "50.0px"
75 | },
76 | "keep": {
77 | "params": [ "1pt" ],
78 | "expect": "1pt"
79 | }
80 | },
81 |
82 | // Zero Removal
83 | "zeroes": {
84 | "0.8px": {
85 | "params": [ "0.8px" ],
86 | /*
87 | Adding nested Multi line comments
88 | Just for fun
89 | */
90 | "expect": ".8px"
91 | },
92 | "-0.5px": {
93 | "params": [ "-0.5px" ],
94 | "expect": "-.5px"
95 | },
96 | "+0.5px": {
97 | "params": [ "+0.5px" ],
98 | "expect": ".5px"
99 | },
100 | "0.2983%": {
101 | "params": [ "0.2983%" ],
102 | "expect": ".2983%"
103 | },
104 | "-10.5px": {
105 | "params": [ "-10.5px" ],
106 | "expect": "-10.5px"
107 | },
108 | "10.2983%": {
109 | "params": [ "10.2983%" ],
110 | "expect": "10.2983%"
111 | }
112 | },
113 |
114 | // Main numeric handler, just checking that it handles
115 | // all of the above scenarios
116 | "numeric": {
117 | "0.8px": {
118 | "params": [ "0.8px" ],
119 | "expect": ".8px"
120 | },
121 | "0 pixel": {
122 | "params": [ "0px" ],
123 | /*
124 | Adding nested Multi line comments
125 | Just for fun
126 | */
127 | "expect": "0"
128 | },
129 | "decimal removal": {
130 | "params": [ "1.0em" ],
131 | "expect": "1em"
132 | },
133 | "Nothing": {
134 | "params": [ "1pt" ],
135 | "expect": "1pt"
136 | }
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/test/files/json/comments.json:
--------------------------------------------------------------------------------
1 | // Single Line Comment
2 | [
3 | // Blah
4 | true,
5 | // false,
6 | null,
7 | "string" // Nothing
8 | // Empty
9 | ]
10 |
--------------------------------------------------------------------------------
/test/files/json/empty.json:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/codenothing/jsonlint/a83b6f8b5dd37447c30c1baeb8cb287bbd2ec6c3/test/files/json/empty.json
--------------------------------------------------------------------------------
/test/files/json/endofarray.json:
--------------------------------------------------------------------------------
1 | [ null, ]
2 |
--------------------------------------------------------------------------------
/test/files/json/multi-comment.json:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Multi Line Comment
4 |
5 | */
6 | {
7 | /* Start Comment */
8 | "key": /*
9 | Inner Multi Line Comment
10 | */
11 | "value",
12 | /*
13 | Key Break
14 | */
15 | "key2": /* Same Line */ true
16 | /* End COmment */
17 | }
18 |
--------------------------------------------------------------------------------
/test/files/json/multi-object.json:
--------------------------------------------------------------------------------
1 | {
2 | "test": true,
3 | "next": false
4 | }
5 | [
6 | null
7 | ]
8 |
--------------------------------------------------------------------------------
/test/files/json/nested.json:
--------------------------------------------------------------------------------
1 | {
2 | "a": [
3 | {
4 | "b": [
5 | {
6 | "c": [
7 | true,
8 | false,
9 | null,
10 | 1001
11 | ]
12 | }
13 | ]
14 | }
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/test/files/json/nocomments.json:
--------------------------------------------------------------------------------
1 | [
2 | // This will throw errr
3 | false
4 | ]
5 |
--------------------------------------------------------------------------------
/test/files/json/nomulticomment.json:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | This will throw error on first character
4 |
5 | */
6 | {
7 | "test": null
8 | }
9 |
--------------------------------------------------------------------------------
/test/files/json/pit.json:
--------------------------------------------------------------------------------
1 | /*
2 | this file contains as many different types of data as possible
3 | */
4 | [
5 | true,
6 | false,
7 | // false,
8 | null,
9 | 10,
10 | 10.0,
11 | 10.2E1,
12 | 10.2e-1,
13 | -10.5e192,
14 | -10.5e+192,
15 | [
16 | true,
17 | false,
18 | // false,
19 | null,
20 | 10,
21 | 10.0,
22 | 10.2E1,
23 | 10.2e-1,
24 | -10.5e192,
25 | -10.5e+192
26 | ],
27 | {
28 | "test": true,
29 | "a": false,
30 | "b": null
31 | }
32 | ]
33 |
--------------------------------------------------------------------------------
/test/files/json/string.json:
--------------------------------------------------------------------------------
1 | [
2 | "\s"
3 | ]
4 |
--------------------------------------------------------------------------------
/test/files/json/strings.json:
--------------------------------------------------------------------------------
1 | // Valid escaped strings
2 | [
3 | "\"",
4 | "\\",
5 | "\/",
6 | "\b",
7 | "\f",
8 | "\n",
9 | "\r",
10 | "\t",
11 | "\u1234"
12 | ]
13 |
--------------------------------------------------------------------------------
/test/files/test-files.js:
--------------------------------------------------------------------------------
1 | var fs = require( 'fs' ),
2 | expect = 0,
3 | tests = [
4 |
5 | {
6 | file: 'Numeric.json'
7 | },
8 |
9 | {
10 | file: 'comments.json'
11 | },
12 |
13 | {
14 | file: 'multi-comment.json'
15 | },
16 |
17 | {
18 | file: 'nested.json'
19 | },
20 |
21 | {
22 | file: 'pit.json'
23 | },
24 |
25 | {
26 | file: 'strings.json'
27 | },
28 |
29 |
30 | {
31 | file: 'endofarray.json',
32 | error: true,
33 | line: 1,
34 | character: 9
35 | },
36 |
37 | {
38 | file: 'nocomments.json',
39 | error: true,
40 | line: 2,
41 | character: 2,
42 | options: {
43 | comments: false
44 | }
45 | },
46 |
47 | {
48 | file: 'nomulticomment.json',
49 | error: true,
50 | line: 1,
51 | character: 1,
52 | options: {
53 | comments: false
54 | }
55 | },
56 |
57 | {
58 | file: 'string.json',
59 | error: true,
60 | line: 2,
61 | character: 3
62 | },
63 |
64 | {
65 | file: 'empty.json',
66 | error: true,
67 | line: 1,
68 | character: 0
69 | },
70 |
71 | {
72 | file: 'multi-object.json',
73 | error: true,
74 | line: 5,
75 | character: 1
76 | }
77 |
78 | ];
79 |
80 |
81 | tests.forEach(function( test ) {
82 | expect += test.error ? 2 : 1;
83 | });
84 |
85 | munit( 'Files', { expect: expect, timeout: 3000 }, function( assert ) {
86 | tests.forEach(function( test ) {
87 | fs.readFile( __dirname + '/json/' + test.file, 'utf-8', function( e, contents ) {
88 | if ( e ) {
89 | return assert.fail( test.file );
90 | }
91 |
92 | var lint = JSONLint( contents, test.options );
93 | if ( ! lint.error ) {
94 | assert.ok( test.file, ! test.error );
95 | }
96 | else if ( ! test.error ) {
97 | assert.fail( test.file );
98 | }
99 | else {
100 | assert.equal( test.file + '-line', lint.line, test.line );
101 | assert.equal( test.file + '-character', lint.character, test.character );
102 | }
103 | });
104 | });
105 | });
106 |
--------------------------------------------------------------------------------
/test/munit.js:
--------------------------------------------------------------------------------
1 | global.JSONLint = require( '../jsonlint.js' );
2 |
--------------------------------------------------------------------------------
/test/test-clean.js:
--------------------------------------------------------------------------------
1 | var tests = [
2 | // Empties
3 | "[]",
4 | "{}",
5 | "[{}]",
6 | "[[]]",
7 | "{\"test\":[]}",
8 | "{\"test\":{}}",
9 | "{\"test\": [ ], \"test2\": [ ] }",
10 |
11 | // Null Value
12 | "{\"test\":null}",
13 |
14 | // Boolean Values
15 | "{\"test\":true}",
16 | "{\"test\":false}",
17 |
18 | // Numeric Values
19 | "{\"test\":1}",
20 | "{\"test\":-101}",
21 | "{\"test\":101.101}",
22 | "{\"test\":-101.101e1}",
23 | "{\"test\":101.101e-101}",
24 | "{\"test\":-101.101E1}",
25 | "{\"test\":101.101E-101}",
26 | "{\"test\":101.101e+101}",
27 | "{\"test\":101.101E+101}",
28 |
29 | // String Values
30 | "[\"\"]",
31 | "{\"test\":\"good\"}",
32 | "{\"test\":\"s p a c i n g \"}",
33 | "{\"test\":\"'single quote'\"}",
34 | "{\"test\":\"\\\"double quote\\\"\"}",
35 |
36 | // Valid Reverse solidus in strings
37 | "[\"\\\"\"]",
38 | "[\"\\\\\"]",
39 | "[\"\\/\"]",
40 | "[\"\\b\"]",
41 | "[\"\\f\"]",
42 | "[\"\\n\"]",
43 | "[\"\\r\"]",
44 | "[\"\\t\"]",
45 | "[\"\\u1234\"]",
46 |
47 | // Array Value
48 | "{\"test\": [ true ] }",
49 |
50 | // Array
51 | "[null]",
52 | "[true]",
53 | "[false]",
54 | "[1]",
55 | "[-101]",
56 | "[101.101E-101]",
57 | "[\"stringval\"]",
58 |
59 | // Multi Array
60 | "[ null, true, false, 1, -101, 101.101E-101, \"stringval\" ]",
61 |
62 | // Multi Object
63 | "{ \"test\": null, \"ing\": true, \"a\": false, \"b\": -101.101e-101 }"
64 | ];
65 |
66 | munit( 'Clean', tests.length, function( assert ) {
67 | tests.forEach(function( test, index ) {
68 | var lint = JSONLint( test );
69 |
70 | assert.ok( index + '', ! lint.error );
71 | });
72 | });
73 |
--------------------------------------------------------------------------------
/test/test-invalid.js:
--------------------------------------------------------------------------------
1 | var tests = {
2 | // JSON cannot be empty
3 | "Empty Test": {
4 | json: "",
5 | character: 0,
6 | line: 1
7 | },
8 |
9 | // There can only be one object/array in a json string
10 | "Multi Object": {
11 | json: "{}[]",
12 | character: 3,
13 | line: 1
14 | },
15 |
16 | // Invalid Null Value
17 | "Capital NULL": {
18 | json: "{\"test\":NULL}",
19 | character: 9,
20 | line: 1
21 | },
22 |
23 | // Invalid Boolean Value
24 | "Capital TRUE": {
25 | json: "{\"test\":TRUE}",
26 | character: 9,
27 | line: 1
28 | },
29 | "Capital FALSE": {
30 | json: "{\"test\":FALSE}",
31 | character: 9,
32 | line: 1
33 | },
34 |
35 | // Invalid Numeric Values
36 | "+1": {
37 | json: "{\"test\":+1}",
38 | character: 9,
39 | line: 1
40 | },
41 | "Double Decimal": {
42 | json: "{\"test\":-101.1.23}",
43 | character: 15,
44 | line: 1
45 | },
46 | "Non Decimal E": {
47 | json: "{\"test\":1e}",
48 | character: 10,
49 | line: 1
50 | },
51 | "Bad E": {
52 | json: "{\"test\":1.0e}",
53 | character: 13,
54 | line: 1
55 | },
56 | "Double E": {
57 | json: "{\"test\":-101.101e1e12}",
58 | character: 19,
59 | line: 1
60 | },
61 | "Double E negative": {
62 | json: "{\"test\":101.101e-101e-12}",
63 | character: 21,
64 | line: 1
65 | },
66 | "E decimal": {
67 | json: "{\"test\":-101.101E1.102}",
68 | character: 19,
69 | line: 1
70 | },
71 |
72 | // String Values (more complex in file sheets)
73 | "Bad Close Quote": {
74 | json: "{\"test\":\"go\"od\"}",
75 | character: 13,
76 | line: 1
77 | },
78 | "Bad Close Quote with spacing": {
79 | json: "{\"test\":\"s p a c \ni \r\nn \"g \"}",
80 | character: 4,
81 | line: 4
82 | },
83 | "No Close Quote": {
84 | json: "{\"test\":\"good}",
85 | character: 14,
86 | line: 1
87 | },
88 | "Invalid Reverse Solidus": {
89 | json: "[ \"\\s\" ]",
90 | character: 4,
91 | line: 1
92 | },
93 | "Invalid Reverse Solidus \\u short": {
94 | json: "[ \"\\u123\" ]",
95 | character: 4,
96 | line: 1
97 | },
98 | "Invalid Reverse Solidus \\u 1": {
99 | json: "[ \"\\ua234\" ]",
100 | character: 4,
101 | line: 1
102 | },
103 | "Invalid Reverse Solidus \\u 2": {
104 | json: "[ \"\\u1b34\" ]",
105 | character: 4,
106 | line: 1
107 | },
108 | "Invalid Reverse Solidus \\u 3": {
109 | json: "[ \"\\u12c4\" ]",
110 | character: 4,
111 | line: 1
112 | },
113 | "Invalid Reverse Solidus \\u 4": {
114 | json: "[ \"\\u123d\" ]",
115 | character: 4,
116 | line: 1
117 | },
118 |
119 | // Invalid Brace Notations
120 | "Bad Closing Array": {
121 | json: "[null}",
122 | character: 6,
123 | line: 1
124 | },
125 | "Bad Closing Object": {
126 | json: "{\"test\":null]",
127 | character: 13,
128 | line: 1
129 | },
130 |
131 | // Multiple Array Values
132 | "No Comma Array": {
133 | json: "[ null, true, false, 1, -101,\n101.101E-101 \"stringval\" ]",
134 | character: 14,
135 | line: 2
136 | },
137 | "No Comma Object": {
138 | json: "{\n\"test\": null,\n\"ing\": true,\n\"a\": false\n\"b\": -101.101e-101 }",
139 | character: 1,
140 | line: 5
141 | },
142 |
143 | // End of array errors
144 | "End of Array Error": {
145 | json: "[ null, ]",
146 | character: 9,
147 | line: 1
148 | },
149 |
150 | // End of object errors
151 | "End of Object Error": {
152 | json: "{\"test\": null, }",
153 | character: 16,
154 | line: 1
155 | },
156 |
157 | // End of file Object errors
158 | "EOF Object Nothing": {
159 | json: "{\"test\": null",
160 | character: 13,
161 | line: 1
162 | },
163 | "EOF Object Comma": {
164 | json: "{\"test\": null,",
165 | character: 14,
166 | line: 1
167 | },
168 | "EOF Object Space": {
169 | json: "{\"test\": null ",
170 | character: 14,
171 | line: 1
172 | },
173 | "EOF Object Array": {
174 | json: "{\"test\": [ null ]",
175 | character: 17,
176 | line: 1
177 | },
178 |
179 | // End of file Array errors
180 | "EOF Array Nothing": {
181 | json: "[ null",
182 | character: 6,
183 | line: 1
184 | },
185 | "EOF Array Space": {
186 | json: "[ null ",
187 | character: 7,
188 | line: 1
189 | },
190 | "EOF Array Comma": {
191 | json: "[ null,",
192 | character: 7,
193 | line: 1
194 | },
195 | "EOF Array object": {
196 | json: "[ null, { \"test\": null } ",
197 | character: 25,
198 | line: 1
199 | }
200 | };
201 |
202 | munit( 'Inavlid', Object.keys( tests ).count * 2, function( assert ) {
203 | munit.each( tests, function( object, name ) {
204 | var lint = JSONLint( object.json, object.options );
205 |
206 | if ( ! lint.error ) {
207 | assert.fail( name );
208 | }
209 | else {
210 | assert.equal( name + '-line', lint.line, object.line );
211 | assert.equal( name + '-character', lint.character, object.character );
212 | }
213 | });
214 | });
215 |
--------------------------------------------------------------------------------