neatjson 0.8.4 → 0.10.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/LICENSE.txt +2 -2
- data/README.md +58 -26
- data/lib/neatjson.rb +41 -24
- data/neatjson.gemspec +1 -1
- data/test/test_neatjson.lua +83 -0
- data/test/tests.js +43 -1
- data/test/tests.lua +225 -0
- data/test/tests.rb +43 -1
- metadata +8 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9896a4ef60379130606c3de3b7ce03ed65ce304ce7998470ecb74aaa95878f62
|
4
|
+
data.tar.gz: 7aa2196577ba6862be5bdf3811c6e2752157aa7b1520bae37697020a1d65d1cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 867bb6fa6cd5af52f708ded86d50adaf1b938e5f114c05cb9801ec40cf7ff0f08e1547400bf98f42087db2b0520eb682e85f88da9a3176f8ad61b611c8bd4944
|
7
|
+
data.tar.gz: b6b3d72a566b76b50baa82a7fde278f0b0a0c954e698c67fab36d835cf12cae7b1f9a56b5a0fd081ee94501735b6bbea439934057e91ca8f2607d1212ca70574
|
data/LICENSE.txt
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
Copyright (c) 2015-
|
1
|
+
Copyright (c) 2015-2019 Gavin Kistner
|
2
2
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
4
|
|
5
5
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
6
|
|
7
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/neatjson.svg)](http://badge.fury.io/rb/neatjson)
|
4
4
|
[![Gem Downloads](http://ruby-gem-downloads-badge.herokuapp.com/neatjson?type=total&color=brightgreen)](https://rubygems.org/gems/neatjson)
|
5
5
|
|
6
|
-
Pretty-print your JSON in Ruby or JavaScript with more power than is provided by `JSON.pretty_generate` (Ruby) or `JSON.stringify` (JS). For example, like Ruby's `pp` (pretty print), NeatJSON can keep objects on one line if they fit, but break them over multiple lines if needed.
|
6
|
+
Pretty-print your JSON in Ruby or JavaScript or Lua with more power than is provided by `JSON.pretty_generate` (Ruby) or `JSON.stringify` (JS). For example, like Ruby's `pp` (pretty print), NeatJSON can keep objects on one line if they fit, but break them over multiple lines if needed.
|
7
7
|
|
8
8
|
**Features (all optional):**
|
9
9
|
|
@@ -17,6 +17,8 @@ Pretty-print your JSON in Ruby or JavaScript with more power than is provided by
|
|
17
17
|
* Adjust number of spaces before/after commas and colons (both for single- vs. multi-line).
|
18
18
|
* Line up the values for an object across lines.
|
19
19
|
* [Online webpage](http://phrogz.net/JS/NeatJSON) for conversions and experimenting with options.
|
20
|
+
* [Lua only] Produce Lua table serialization.
|
21
|
+
|
20
22
|
|
21
23
|
## Table of Contents
|
22
24
|
|
@@ -28,6 +30,7 @@ Pretty-print your JSON in Ruby or JavaScript with more power than is provided by
|
|
28
30
|
* [TODO/Known Limitations](#todo-aka-known-limitations)
|
29
31
|
* [History](#history)
|
30
32
|
|
33
|
+
|
31
34
|
## Installation
|
32
35
|
|
33
36
|
* Ruby: `gem install neatjson`
|
@@ -44,6 +47,7 @@ require 'neatjson'
|
|
44
47
|
json = JSON.neat_generate( value, options )
|
45
48
|
~~~
|
46
49
|
|
50
|
+
|
47
51
|
**JavaScript (web)**:
|
48
52
|
|
49
53
|
~~~ html
|
@@ -61,9 +65,17 @@ const { neatJSON } = require('neatjson');
|
|
61
65
|
var json = neatJSON( value, options );
|
62
66
|
~~~
|
63
67
|
|
68
|
+
|
69
|
+
**Lua**:
|
70
|
+
|
71
|
+
~~~ lua
|
72
|
+
local neatJSON = require'neatjson'
|
73
|
+
local json = neatJSON(value, options)
|
74
|
+
~~~
|
75
|
+
|
64
76
|
## Examples
|
65
77
|
|
66
|
-
_The following are all in Ruby, but similar options apply in JavaScript._
|
78
|
+
_The following are all in Ruby, but similar options apply in JavaScript and Lua._
|
67
79
|
|
68
80
|
~~~ ruby
|
69
81
|
require 'neatjson'
|
@@ -160,7 +172,7 @@ puts JSON.neat_generate( data, opts )
|
|
160
172
|
|
161
173
|
|
162
174
|
## Options
|
163
|
-
You may pass any of the following options to `neat_generate` (Ruby) or `neatJSON` (JavaScript). **Note**: option names with underscores below use camelCase in JavaScript. For example:
|
175
|
+
You may pass any of the following options to `neat_generate` (Ruby) or `neatJSON` (JavaScript/Lua). **Note**: option names with underscores below use camelCase in JavaScript and Lua. For example:
|
164
176
|
|
165
177
|
~~~ ruby
|
166
178
|
# Ruby
|
@@ -172,28 +184,39 @@ json = JSON.neat_generate my_value, array_padding:1, after_comma:1, before_colon
|
|
172
184
|
var json = neatJSON( myValue, { arrayPadding:1, afterComma:1, beforeColonN:2, indentLast:true } );
|
173
185
|
~~~
|
174
186
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
187
|
+
~~~ lua
|
188
|
+
-- Lua
|
189
|
+
local json = neatJSON( myValue, { arrayPadding=1, afterComma=1, beforeColonN=2, indentLast=true } )
|
190
|
+
~~~
|
191
|
+
|
192
|
+
* `wrap` — Maximum line width before wrapping. Use `false` to never wrap, `true` to always wrap. default:`80`
|
193
|
+
* `indent` — Whitespace used to indent each level when wrapping. default:`" "` (two spaces)
|
194
|
+
* `indent_last` — Indent the closing bracket/brace for arrays and objects? default:`false`
|
195
|
+
* `short` — Put opening brackets on the same line as the first value, closing brackets on the same line as the last? default:`false`
|
179
196
|
* _This causes the `indent` and `indent_last` options to be ignored, instead basing indentation on array and object padding._
|
180
|
-
* `sort`
|
197
|
+
* `sort` — Sort objects' keys in alphabetical order (`true`), or supply a lambda for custom sorting. default:`false`
|
181
198
|
* If you supply a lambda to the `sort` option, it will be passed three values: the (string) name of the key, the associated value, and the object being sorted, e.g. `{ sort:->(key,value,hash){ Float(value) rescue Float::MAX } }`
|
182
|
-
* `aligned`
|
183
|
-
* `decimals`
|
184
|
-
* `
|
185
|
-
* `
|
186
|
-
* `
|
187
|
-
|
188
|
-
* `
|
189
|
-
* `
|
190
|
-
* `
|
191
|
-
* `
|
192
|
-
* `
|
193
|
-
* `
|
194
|
-
* `
|
195
|
-
* `
|
196
|
-
* `
|
199
|
+
* `aligned` — When wrapping objects, line up the colons (per object)? default:`false`
|
200
|
+
* `decimals` — Decimal precision for non-integer numbers; use `false` to keep values precise. default:`false`
|
201
|
+
* `trim_trailing_zeros` — Remove extra zeros at the end of floats, e.g. `1.2000` becomes `1.2`. default:`false`
|
202
|
+
* `force_floats` — Force every integer value written to the file to be a float, e.g. `12` becomes `12.0`. default:`false`
|
203
|
+
* `force_floats_in` — Specify an array of object key names under which all integer values are treated as floats.
|
204
|
+
For example, serializing `{a:[1, 2, {a:3, b:4}], c:{a:5, d:6}` with `force_floats_in:['a']` would produce `{"a":[1.0, 2.0, {"a":3.0, "b":4}], "c":{"a":5.0, "d":6}}`.
|
205
|
+
* `array_padding` — Number of spaces to put inside brackets for arrays. default:`0`
|
206
|
+
* `object_padding` — Number of spaces to put inside braces for objects. default:`0`
|
207
|
+
* `padding` — Shorthand to set both `array_padding` and `object_padding`. default:`0`
|
208
|
+
* `before_comma` — Number of spaces to put before commas (for both arrays and objects). default:`0`
|
209
|
+
* `after_comma` — Number of spaces to put after commas (for both arrays and objects). default:`0`
|
210
|
+
* `around_comma` — Shorthand to set both `before_comma` and `after_comma`. default:`0`
|
211
|
+
* `before_colon_1` — Number of spaces before a colon when the object is on one line. default:`0`
|
212
|
+
* `after_colon_1` — Number of spaces after a colon when the object is on one line. default:`0`
|
213
|
+
* `before_colon_n` — Number of spaces before a colon when the object is on multiple lines. default:`0`
|
214
|
+
* `after_colon_n` — Number of spaces after a colon when the object is on multiple lines. default:`0`
|
215
|
+
* `before_colon` — Shorthand to set both `before_colon_1` and `before_colon_n`. default:`0`
|
216
|
+
* `after_colon` — Shorthand to set both `after_colon_1` and `after_colon_n`. default:`0`
|
217
|
+
* `around_colon` — Shorthand to set both `before_colon` and `after_colon`. default:`0`
|
218
|
+
* `lua` — (Lua only) Output a Lua table literal instead of JSON? default:`false`
|
219
|
+
* `emptyTablesAreObjects` — (Lua only) Should `{}` in Lua become a JSON object (`{}`) or JSON array (`[]`)? default:`false` (array)
|
197
220
|
|
198
221
|
You may omit the 'value' and/or 'object' parameters in your `sort` lambda if desired. For example:
|
199
222
|
|
@@ -233,12 +256,12 @@ neatJSON( obj, { sort:function(k,v){ return countByValue[v] } } ); // so
|
|
233
256
|
// {"d":1,"a":2,"b":2,"e":3,"c":3,"f":3}
|
234
257
|
~~~
|
235
258
|
|
236
|
-
_Note that the JavaScript
|
259
|
+
_Note that the JavaScript and Lua versions of NeatJSON do not provide a mechanism for cascading sort in the same manner as Ruby._
|
237
260
|
|
238
261
|
|
239
262
|
## License & Contact
|
240
263
|
|
241
|
-
NeatJSON is copyright ©2015–
|
264
|
+
NeatJSON is copyright ©2015–2022 by Gavin Kistner and is released under
|
242
265
|
the [MIT License](http://www.opensource.org/licenses/mit-license.php).
|
243
266
|
See the LICENSE.txt file for more details.
|
244
267
|
|
@@ -250,12 +273,21 @@ For other communication you can [email the author directly](mailto:!@phrogz.net?
|
|
250
273
|
|
251
274
|
* Figure out the best way to play with custom objects that use `to_json` for their representation.
|
252
275
|
* Detect circular references.
|
253
|
-
* Possibly allow illegal JSON values like `NaN` or `Infinity`.
|
254
276
|
* Possibly allow "JSON5" output (legal identifiers unquoted, etc.)
|
255
277
|
|
256
278
|
|
257
279
|
## HISTORY
|
258
280
|
|
281
|
+
* **v0.10** — August 29, 2022
|
282
|
+
* Add `force_floats` and `force_floats_in` to support serialization for non-standard parsers that differentiate between integers and floats.
|
283
|
+
* Add `trim_trailing_zeros` option to convert the `decimals` output from e.g. `5.40000` to `5.4`.
|
284
|
+
* Convert JavaScript version to require ECMAScript 6 for performance.
|
285
|
+
|
286
|
+
* **v0.9** — July 29, 2019
|
287
|
+
* Add Lua version, serializing to both JSON and Lua table literals
|
288
|
+
* All languages serialize Infinity/-Infinity to JSON as `9e9999` and `-9e9999`
|
289
|
+
* All languages serialize NaN to JSON as `"NaN"`
|
290
|
+
|
259
291
|
* **v0.8.4** — May 3, 2018
|
260
292
|
* Fix issue #27: Default sorting fails with on objects with mixed keys [Ruby only]
|
261
293
|
* _Thanks Reid Beels_
|
data/lib/neatjson.rb
CHANGED
@@ -6,13 +6,16 @@ module JSON
|
|
6
6
|
# @author Gavin Kistner <!@phrogz.net>
|
7
7
|
# @param object [Object] the object to serialize
|
8
8
|
# @param opts [Hash] the formatting options
|
9
|
-
# @option opts [Integer] :wrap
|
10
|
-
# @option opts [String] :indent
|
11
|
-
# @option opts [Boolean] :indent_last
|
12
|
-
# @option opts [Boolean] :short
|
13
|
-
# @option opts [Boolean] :sort
|
14
|
-
# @option opts [Boolean] :aligned
|
15
|
-
# @option opts [
|
9
|
+
# @option opts [Integer] :wrap (80) The maximum line width before wrapping. Use `false` to never wrap, or `true` to always wrap.
|
10
|
+
# @option opts [String] :indent (" ") Whitespace used to indent each level when wrapping (without the :short option).
|
11
|
+
# @option opts [Boolean] :indent_last (false) Indent the closing bracket for arrays and objects (without the :short option).
|
12
|
+
# @option opts [Boolean] :short (false) Keep the output 'short' when wrapping, putting opening brackets on the same line as the first value, and closing brackets on the same line as the last item.
|
13
|
+
# @option opts [Boolean] :sort (false) Sort the keys for objects to be in alphabetical order (`true`), or supply a lambda to determine ordering.
|
14
|
+
# @option opts [Boolean] :aligned (false) When wrapping objects, align the colons (only per object).
|
15
|
+
# @option opts [Boolean] :force_floats (false) Ensure that all integer values have `.0` after them.
|
16
|
+
# @option opts [Array] :force_floats_in ([]) Array of object key names to force floats inside of.
|
17
|
+
# @option opts [Integer] :decimals (null) Decimal precision to use for floats; omit to keep numeric values precise.
|
18
|
+
# @option opts [Boolean] :trim_trailing_zeros (false) Remove trailing zeros added by `decimals`` from the ends of floating point numbers.
|
16
19
|
# @option opts [Integer] :padding (0) Number of spaces to put inside brackets/braces for both arrays and objects.
|
17
20
|
# @option opts [Integer] :array_padding (0) Number of spaces to put inside brackets for arrays. Overrides `:padding`.
|
18
21
|
# @option opts [Integer] :object_padding (0) Number of spaces to put inside braces for objects. Overrides `:padding`.
|
@@ -37,6 +40,7 @@ module JSON
|
|
37
40
|
opts[:wrap] = 80 unless opts.key?(:wrap)
|
38
41
|
opts[:wrap] = -1 if opts[:wrap]==true
|
39
42
|
opts[:indent] ||= " "
|
43
|
+
opts[:force_floats_in]||= []
|
40
44
|
opts[:array_padding] ||= opts[:padding] || 0
|
41
45
|
opts[:object_padding] ||= opts[:padding] || 0
|
42
46
|
opts[:after_comma] ||= opts[:around_comma] || 0
|
@@ -56,17 +60,27 @@ module JSON
|
|
56
60
|
colonn= "#{' '*opts[:before_colon_n]}:#{' '*opts[:after_colon_n]}"
|
57
61
|
|
58
62
|
memoizer = {}
|
59
|
-
build = ->(o,indent) do
|
60
|
-
memoizer[[o,indent]] ||= case o
|
61
|
-
when String
|
63
|
+
build = ->(o,indent,floats_forced) do
|
64
|
+
memoizer[[o,indent,floats_forced]] ||= case o
|
65
|
+
when String then "#{indent}#{o.inspect}"
|
62
66
|
when Symbol then "#{indent}#{o.to_s.inspect}"
|
63
67
|
when TrueClass,FalseClass then "#{indent}#{o}"
|
64
68
|
when NilClass then "#{indent}null"
|
69
|
+
when Integer
|
70
|
+
floats_forced ? build[o.to_f, indent, floats_forced] : "#{indent}#{o.inspect}"
|
65
71
|
when Float
|
66
|
-
if
|
67
|
-
|
72
|
+
if o.infinite?
|
73
|
+
"#{indent}#{o<0 ? "-9e9999" : "9e9999"}"
|
74
|
+
elsif o.nan?
|
75
|
+
"#{indent}\"NaN\""
|
76
|
+
elsif !floats_forced && (o==o.to_i) && (o.to_s !~ /e/)
|
77
|
+
build[o.to_i, indent, floats_forced]
|
68
78
|
elsif opts[:decimals]
|
69
|
-
|
79
|
+
if opts[:trim_trailing_zeros]
|
80
|
+
"#{indent}#{o.round(opts[:decimals])}"
|
81
|
+
else
|
82
|
+
"#{indent}%.#{opts[:decimals]}f" % o
|
83
|
+
end
|
70
84
|
else
|
71
85
|
"#{indent}#{o}"
|
72
86
|
end
|
@@ -75,19 +89,19 @@ module JSON
|
|
75
89
|
if o.empty?
|
76
90
|
"#{indent}[]"
|
77
91
|
else
|
78
|
-
pieces = o.map{ |v| build[v,''] }
|
92
|
+
pieces = o.map{ |v| build[v, '', floats_forced] }
|
79
93
|
one_line = "#{indent}[#{apad}#{pieces.join comma}#{apad}]"
|
80
94
|
if !opts[:wrap] || (one_line.length <= opts[:wrap])
|
81
95
|
one_line
|
82
96
|
elsif opts[:short]
|
83
97
|
indent2 = "#{indent} #{apad}"
|
84
|
-
pieces = o.map{ |v| build[
|
98
|
+
pieces = o.map{ |v| build[v, indent2, floats_forced] }
|
85
99
|
pieces[0] = pieces[0].sub indent2, "#{indent}[#{apad}"
|
86
100
|
pieces[pieces.length-1] = "#{pieces.last}#{apad}]"
|
87
101
|
pieces.join ",\n"
|
88
102
|
else
|
89
103
|
indent2 = "#{indent}#{opts[:indent]}"
|
90
|
-
"#{indent}[\n#{o.map{ |v| build[
|
104
|
+
"#{indent}[\n#{o.map{ |v| build[v, indent2, floats_forced] }.join ",\n"}\n#{opts[:indent_last] ? indent2 : indent}]"
|
91
105
|
end
|
92
106
|
end
|
93
107
|
|
@@ -104,7 +118,8 @@ module JSON
|
|
104
118
|
when 3 then o.sort_by{ |k,v| sort[k,v,o] }
|
105
119
|
end
|
106
120
|
end
|
107
|
-
|
121
|
+
keys = o.map{ |x| x.first.to_s }
|
122
|
+
keyvals = o.map.with_index{ |(k,v),i| [ k.to_s.inspect, build[v, '', opts[:force_floats] || opts[:force_floats_in].include?(keys[i])] ] }
|
108
123
|
keyvals = keyvals.map{ |kv| kv.join(colon1) }.join(comma)
|
109
124
|
one_line = "#{indent}{#{opad}#{keyvals}#{opad}}"
|
110
125
|
if !opts[:wrap] || (one_line.length <= opts[:wrap])
|
@@ -118,11 +133,12 @@ module JSON
|
|
118
133
|
formatk = "%-#{longest}s"
|
119
134
|
keyvals.map!{ |k,v| [ formatk % k,v] }
|
120
135
|
end
|
121
|
-
keyvals.map
|
136
|
+
keyvals.map!.with_index do |(k,v),i|
|
137
|
+
floats_forced = opts[:force_floats] || opts[:force_floats_in].include?(keys[i])
|
122
138
|
indent2 = " "*"#{k}#{colonn}".length
|
123
|
-
one_line = "#{k}#{colonn}#{build[v,'']}"
|
139
|
+
one_line = "#{k}#{colonn}#{build[v, '', floats_forced]}"
|
124
140
|
if opts[:wrap] && (one_line.length > opts[:wrap]) && (v.is_a?(Array) || v.is_a?(Hash))
|
125
|
-
"#{k}#{colonn}#{build[v,indent2].lstrip}"
|
141
|
+
"#{k}#{colonn}#{build[v, indent2, floats_forced].lstrip}"
|
126
142
|
else
|
127
143
|
one_line
|
128
144
|
end
|
@@ -136,10 +152,11 @@ module JSON
|
|
136
152
|
keyvals.map!{ |k,v| [ formatk % k,v] }
|
137
153
|
end
|
138
154
|
indent2 = "#{indent}#{opts[:indent]}"
|
139
|
-
keyvals.map
|
140
|
-
|
155
|
+
keyvals.map!.with_index do |(k,v),i|
|
156
|
+
floats_forced = opts[:force_floats] || opts[:force_floats_in].include?(keys[i])
|
157
|
+
one_line = "#{k}#{colonn}#{build[v, '', floats_forced]}"
|
141
158
|
if opts[:wrap] && (one_line.length > opts[:wrap]) && (v.is_a?(Array) || v.is_a?(Hash))
|
142
|
-
"#{k}#{colonn}#{build[v,indent2].lstrip}"
|
159
|
+
"#{k}#{colonn}#{build[v, indent2, floats_forced].lstrip}"
|
143
160
|
else
|
144
161
|
one_line
|
145
162
|
end
|
@@ -154,6 +171,6 @@ module JSON
|
|
154
171
|
end
|
155
172
|
end
|
156
173
|
|
157
|
-
build[object,'']
|
174
|
+
build[object, '', opts[:force_floats]]
|
158
175
|
end
|
159
176
|
end
|
data/neatjson.gemspec
CHANGED
@@ -0,0 +1,83 @@
|
|
1
|
+
local function dump(v)
|
2
|
+
local reserved = {["and"]=1,["break"]=1,["do"]=1,["else"]=1,["elseif"]=1,["end"]=1,["false"]=1,["for"]=1,["function"]=1,["goto"]=1,["if"]=1,["in"]=1,["local"]=1,["nil"]=1,["not"]=1,["or"]=1,["repeat"]=1,["return"]=1,["then"]=1,["true"]=1,["until"]=1,["while"]=1}
|
3
|
+
local t=type(v)
|
4
|
+
if t=='table' then
|
5
|
+
local s,r={},{}
|
6
|
+
for i,v2 in ipairs(v) do s[i]=true table.insert(r,dump(v2)) end
|
7
|
+
for k,v2 in pairs(v) do
|
8
|
+
if not s[k] then
|
9
|
+
if type(k)=='string' and not reserved[k] and string.match(k,'^[%a_][%w_]*$') then
|
10
|
+
table.insert(r,k..'='..dump(v2))
|
11
|
+
else
|
12
|
+
table.insert(r,'['..dump(k)..']='..dump(v2))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
return '{'..table.concat(r,', ')..'}'
|
17
|
+
elseif t=='string' then
|
18
|
+
return string.format('%q',v)
|
19
|
+
else
|
20
|
+
return tostring(v)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
package.path = '?.lua;../lua/?.lua'
|
26
|
+
local tests = require'tests'
|
27
|
+
local neatJSON = require'neatjson'
|
28
|
+
local startTime = os.clock()
|
29
|
+
local count,pass=0,0
|
30
|
+
for _,valtest in ipairs(tests) do
|
31
|
+
local value = valtest.value
|
32
|
+
for _,test in ipairs(valtest.tests) do
|
33
|
+
local cmd = "neatJSON("..dump(value)..(test.opts and (", "..dump(test.opts)) or '')..")"
|
34
|
+
local ok,err = pcall(function()
|
35
|
+
local json, success
|
36
|
+
if test.opts then
|
37
|
+
local opts = {}
|
38
|
+
for k,v in pairs(test.opts) do opts[k]=v end
|
39
|
+
json = neatJSON(value,opts)
|
40
|
+
else
|
41
|
+
json = neatJSON(value)
|
42
|
+
end
|
43
|
+
|
44
|
+
if type(test.json)=='string' then
|
45
|
+
success = json==test.json
|
46
|
+
else
|
47
|
+
-- If it's not a string, assume it's an array of acceptable string patterns
|
48
|
+
success = false
|
49
|
+
for _,testPattern in ipairs(test.json) do
|
50
|
+
if json:match(testPattern) then
|
51
|
+
success = true
|
52
|
+
break
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
if success then
|
58
|
+
pass = pass + 1
|
59
|
+
else
|
60
|
+
local expected = type(test.json)=='string' and test.json or table.concat(test.json, ' or ')
|
61
|
+
print(cmd)
|
62
|
+
print('EXPECTED')
|
63
|
+
print(expected)
|
64
|
+
print('ACTUAL')
|
65
|
+
print(json==nil and '(nil)' or #json==0 and '(empty string)' or json)
|
66
|
+
print('')
|
67
|
+
end
|
68
|
+
end)
|
69
|
+
if not ok then
|
70
|
+
print('Error running '..cmd)
|
71
|
+
print(err)
|
72
|
+
print('')
|
73
|
+
end
|
74
|
+
count = count + 1
|
75
|
+
end
|
76
|
+
end
|
77
|
+
local elapsed = os.clock()-startTime
|
78
|
+
print(("%d/%d test%s passed in %.2fms (%.0f tests per second)"):format(
|
79
|
+
pass, count,
|
80
|
+
count==1 and '' or 's',
|
81
|
+
elapsed,
|
82
|
+
1000 * count/elapsed
|
83
|
+
))
|
data/test/tests.js
CHANGED
@@ -15,6 +15,9 @@ exports.tests = [
|
|
15
15
|
{value:5.0001, tests:[
|
16
16
|
{json:"5.0001"},
|
17
17
|
{json:"5.000", opts:{decimals:3}},
|
18
|
+
{json:"5", opts:{decimals:3, trimTrailingZeros:true}},
|
19
|
+
{json:"5.0", opts:{decimals:3, trimTrailingZeros:true, forceFloats:true}},
|
20
|
+
{json:"5.000", opts:{decimals:3, trimTrailingZeros:false, forceFloats:true}},
|
18
21
|
]},
|
19
22
|
{value:4.2, tests:[
|
20
23
|
{json:"4.2"},
|
@@ -30,7 +33,6 @@ exports.tests = [
|
|
30
33
|
{value:-2.4, tests:[{json:"-2", opts:{decimals:0}}]},
|
31
34
|
|
32
35
|
{value:"foo", tests:[{json:"\"foo\""}]},
|
33
|
-
// {value: :foo, tests:[{json:"\"foo\""}]},
|
34
36
|
{value:"foo\nbar", tests:[{json:"\"foo\\nbar\""}]},
|
35
37
|
|
36
38
|
{value:[1,2,3,4,[5,6,7,[8,9,10],11,12]], tests:[
|
@@ -169,6 +171,46 @@ exports.tests = [
|
|
169
171
|
{ json:"{\n \"a\":{\n \"b\":{\n \"c\":{\n \"d\":{\n \"e\":{\n \"f\":{\n \"g\":{\n \"h\":{\n \"i\":{\n \"j\":{\n \"k\":{\n \"l\":{\n \"m\":1\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n}", opts:{wrap:1} },
|
170
172
|
]},
|
171
173
|
|
174
|
+
{value:{inf:1/0, neginf:-1/0, nan:0/0}, tests:[
|
175
|
+
{ json:'{"inf":9e9999,"nan":"NaN","neginf":-9e9999}', opts:{sort:true} },
|
176
|
+
]},
|
177
|
+
|
178
|
+
{value:[0, 1, 1.1, 1.555555], tests:[
|
179
|
+
{ json:'[0,1,1.1,1.555555]', opts:{forceFloats:false} },
|
180
|
+
{ json:'[0.0,1.0,1.1,1.555555]', opts:{forceFloats:true} },
|
181
|
+
{ json:'[0.000,1.000,1.100,1.556]', opts:{forceFloats:true, decimals:3} },
|
182
|
+
{ json:'[0.0,1.0,1.1,1.556]', opts:{forceFloats:true, decimals:3, trimTrailingZeros:true} },
|
183
|
+
{ json:'[0,1,1.1,1.556]', opts:{forceFloats:false, decimals:3, trimTrailingZeros:true} },
|
184
|
+
]},
|
185
|
+
|
186
|
+
{value:{floats:[0, 1, 0.1, 1.555555], raw:[0, 1, 0.1, 1.555555]}, tests:[
|
187
|
+
{ json:'{"floats":[0,1,0.1,1.555555],"raw":[0,1,0.1,1.555555]}', opts:{forceFloats:false} },
|
188
|
+
{ json:'{"floats":[0.0,1.0,0.1,1.555555],"raw":[0.0,1.0,0.1,1.555555]}', opts:{forceFloats:true} },
|
189
|
+
{ json:'{"floats":[0.0,1.0,0.1,1.555555],"raw":[0,1,0.1,1.555555]}', opts:{forceFloatsIn:['floats']} },
|
190
|
+
|
191
|
+
{ json:'{"floats":[0,1,0.100,1.556],"raw":[0,1,0.100,1.556]}', opts:{forceFloats:false, decimals:3} },
|
192
|
+
{ json:'{"floats":[0.000,1.000,0.100,1.556],"raw":[0.000,1.000,0.100,1.556]}', opts:{forceFloats:true, decimals:3} },
|
193
|
+
{ json:'{"floats":[0.000,1.000,0.100,1.556],"raw":[0,1,0.100,1.556]}', opts:{forceFloatsIn:['floats'], decimals:3} },
|
194
|
+
|
195
|
+
{ json:'{"floats":[0,1,0.1,1.556],"raw":[0,1,0.1,1.556]}', opts:{forceFloats:false, decimals:3, trimTrailingZeros:true} },
|
196
|
+
{ json:'{"floats":[0.0,1.0,0.1,1.556],"raw":[0.0,1.0,0.1,1.556]}', opts:{forceFloats:true, decimals:3, trimTrailingZeros:true} },
|
197
|
+
{ json:'{"floats":[0.0,1.0,0.1,1.556],"raw":[0,1,0.1,1.556]}', opts:{forceFloatsIn:['floats'], decimals:3, trimTrailingZeros:true} },
|
198
|
+
]},
|
199
|
+
|
200
|
+
{value:[1,2,3,{a:[4,5,{a:6, b:7}], b:[8,9,{a:10, b:11}]}], tests:[
|
201
|
+
{ json:'[1,2,3,{"a":[4,5,{"a":6,"b":7}],"b":[8,9,{"a":10,"b":11}]}]', opts:{} },
|
202
|
+
{ json:'[1.0,2.0,3.0,{"a":[4.0,5.0,{"a":6.0,"b":7.0}],"b":[8.0,9.0,{"a":10.0,"b":11.0}]}]', opts:{forceFloats:true, wrap:false} },
|
203
|
+
{ json:'[1,2,3,{"a":[4.0,5.0,{"a":6.0,"b":7}],"b":[8,9,{"a":10.0,"b":11}]}]', opts:{forceFloatsIn:['a'], wrap:false} },
|
204
|
+
]},
|
205
|
+
|
206
|
+
{value:[1,2,3, {bar:[4,5,6], foo:[7,8,9]}], tests:[
|
207
|
+
{ json:'[\n\t1,\n\t2,\n\t3,\n\t{\n\t\t"bar":[4,5,6],\n\t\t"foo":[7,8,9]\n\t}\n]', opts:{wrap:20, indent:"\t"} },
|
208
|
+
{ json:'[\n\t1,\n\t2,\n\t3,\n\t{\n\t\t"bar":[4.0,5.0,6.0],\n\t\t"foo":[7,8,9]\n\t}\n]', opts:{wrap:20, indent:"\t", forceFloatsIn:['bar']} },
|
209
|
+
{ json:'[\n\t1,\n\t2,\n\t3,\n\t{\n\t\t"bar":[4,5,6],\n\t\t"foo":[7.0,8.0,9.0]\n\t}\n]', opts:{wrap:20, indent:"\t", forceFloatsIn:['foo']} },
|
210
|
+
{ json:'[\n\t1,\n\t2,\n\t3,\n\t{\n\t\t"bar":[4.0,5.0,6.0],\n\t\t"foo":[7.0,8.0,9.0]\n\t}\n]', opts:{wrap:20, indent:"\t", forceFloatsIn:['foo', 'bar']} },
|
211
|
+
{ json:'[\n\t1.0,\n\t2.0,\n\t3.0,\n\t{\n\t\t"bar":[4.0,5.0,6.0],\n\t\t"foo":[7.0,8.0,9.0]\n\t}\n]', opts:{wrap:20, indent:"\t", forceFloats:true} },
|
212
|
+
]},
|
213
|
+
|
172
214
|
// {value:Class.new{ def to_json(*a); {a:1}.to_json(*a); end }.new, tests:[
|
173
215
|
// { json:'{ "a":1}' },
|
174
216
|
// { json:'{ "a":1}', opts:{wrap:true} },
|
data/test/tests.lua
ADDED
@@ -0,0 +1,225 @@
|
|
1
|
+
return {
|
2
|
+
{value=true, tests={{json="true" }}},
|
3
|
+
{value=false, tests={{json="false" }}},
|
4
|
+
{value=nil, tests={{json="null" }}},
|
5
|
+
{value=5, tests={
|
6
|
+
{json="5"},
|
7
|
+
{json="5", opts={decimals=3}},
|
8
|
+
}},
|
9
|
+
{value=5.0, tests={
|
10
|
+
{json="5"},
|
11
|
+
{json="5", opts={lua=true}},
|
12
|
+
{json="5", opts={decimals=3}},
|
13
|
+
}},
|
14
|
+
{value=5.0001, tests={
|
15
|
+
{json="5.0001"},
|
16
|
+
{json="5.000", opts={decimals=3}},
|
17
|
+
{json="5", opts={decimals=3, trimTrailingZeros=true}},
|
18
|
+
{json="5.0", opts={decimals=3, trimTrailingZeros=true, forceFloats=true}},
|
19
|
+
{json="5.000", opts={decimals=3, trimTrailingZeros=false, forceFloats=true}},
|
20
|
+
}},
|
21
|
+
{value=4.2, tests={
|
22
|
+
{json="4.2"},
|
23
|
+
{json="4", opts={decimals=0}},
|
24
|
+
{json="4.20",opts={decimals=2}},
|
25
|
+
}},
|
26
|
+
{value=4.199, tests={{json="4.20", opts={decimals=2}}}},
|
27
|
+
{value=4.204, tests={{json="4.20", opts={decimals=2}}}},
|
28
|
+
{value=-1.9, tests={{json="-2", opts={decimals=0}}}},
|
29
|
+
{value=-2.4, tests={{json="-2", opts={decimals=0}}}},
|
30
|
+
{value=1e23, tests={{json={'^1%.0+e%+0*23$', '^1e%+0*23$'}}}},
|
31
|
+
{value=1e-9, tests={{json={'^1%.0+e%-0*9$', '^1e%-0*9$'}}}},
|
32
|
+
{value=-2.4, tests={{json="-2", opts={decimals=0}}}},
|
33
|
+
|
34
|
+
{value="foo", tests={{json="\"foo\""}}},
|
35
|
+
-- {value= :foo, tests={{json="\"foo\""}}},
|
36
|
+
{value="foo\nbar", tests={{json="\"foo\\nbar\""}}},
|
37
|
+
|
38
|
+
{value={1,2,3,4,{5,6,7,{8,9,10},11,12}}, tests={
|
39
|
+
{ json="[1,2,3,4,[5,6,7,[8,9,10],11,12]]" },
|
40
|
+
{ json="{1,2,3,4,{5,6,7,{8,9,10},11,12}}", opts={lua=true} },
|
41
|
+
{ json="[\n 1,\n 2,\n 3,\n 4,\n [5,6,7,[8,9,10],11,12]\n]", opts={wrap=30} },
|
42
|
+
{ json="[\n 1,\n 2,\n 3,\n 4,\n [\n 5,\n 6,\n 7,\n [8,9,10],\n 11,\n 12\n ]\n]", opts={wrap=20} },
|
43
|
+
{ json="[\n 1,\n 2,\n 3,\n 4,\n [\n 5,\n 6,\n 7,\n [\n 8,\n 9,\n 10\n ],\n 11,\n 12\n ]\n]", opts={wrap=true} },
|
44
|
+
{ json="[\n\t1,\n\t2,\n\t3,\n\t4,\n\t[\n\t\t5,\n\t\t6,\n\t\t7,\n\t\t[\n\t\t\t8,\n\t\t\t9,\n\t\t\t10\n\t\t],\n\t\t11,\n\t\t12\n\t]\n]", opts={wrap=true,indent="\t"} },
|
45
|
+
{ json="[1,2,3,4,[5,6,7,[8,9,10],11,12]]", opts={arrayPadding=0} },
|
46
|
+
{ json="[ 1,2,3,4,[ 5,6,7,[ 8,9,10 ],11,12 ] ]", opts={arrayPadding=1} },
|
47
|
+
{ json="[ 1,2,3,4,[ 5,6,7,[ 8,9,10 ],11,12 ] ]", opts={arrayPadding=2} },
|
48
|
+
{ json="[1, 2, 3, 4, [5, 6, 7, [8, 9, 10], 11, 12]]", opts={afterComma=1} },
|
49
|
+
{ json="[ 1, 2, 3, 4, [ 5, 6, 7, [ 8, 9, 10 ], 11, 12 ] ]", opts={afterComma=1,arrayPadding=1} },
|
50
|
+
{ json="[1,\n 2,\n 3,\n 4,\n [5,\n 6,\n 7,\n [8,\n 9,\n 10],\n 11,\n 12]]", opts={short=true,wrap=true} },
|
51
|
+
{ json="[1,\n 2,\n 3,\n 4,\n [5,\n 6,\n 7,\n [8,\n 9,\n 10],\n 11,\n 12]]", opts={short=true,wrap=true,afterComma=1} },
|
52
|
+
{ json="[ 1,\n 2,\n 3,\n 4,\n [ 5,\n 6,\n 7,\n [ 8,\n 9,\n 10 ],\n 11,\n 12 ] ]", opts={short=true,wrap=true,arrayPadding=1} },
|
53
|
+
}},
|
54
|
+
|
55
|
+
{value={1,2,3}, tests={
|
56
|
+
{ json="[1,2,3]" },
|
57
|
+
{ json="[1 ,2 ,3]", opts={beforeComma=1} },
|
58
|
+
{ json="[1 , 2 , 3]", opts={aroundComma=1} },
|
59
|
+
{ json="[\n\t1,\n\t2,\n\t3\n]", opts={wrap=true,indent="\t"} },
|
60
|
+
{ json="[\n\t1,\n\t2,\n\t3\n\t]", opts={wrap=true,indent="\t",indentLast=true} },
|
61
|
+
}},
|
62
|
+
|
63
|
+
{value={b=1,a=2}, tests={
|
64
|
+
{ json={'{"b":1,"a":2}','{"a":2,"b":1}'} },
|
65
|
+
{ json={'{b=1,a=2}','{a=2,b=1}'}, opts={lua=true} },
|
66
|
+
{ json='{"a":2,"b":1}', opts={sorted=true} },
|
67
|
+
{ json='{"a":2,"b":1}', opts={sort=true} },
|
68
|
+
{ json='{"a":2, "b":1}', opts={sorted=true,afterComma=1} },
|
69
|
+
{ json='{"a" :2,"b" :1}', opts={sorted=true,beforeColon=1} },
|
70
|
+
{ json='{"a": 2,"b": 1}', opts={sorted=true,afterColon=1} },
|
71
|
+
{ json='{"a" : 2,"b" : 1}', opts={sorted=true,beforeColon=1,afterColon=1} },
|
72
|
+
{ json='{"a" : 2, "b" : 1}', opts={sorted=true,beforeColon=1,afterColon=1,afterComma=1} },
|
73
|
+
{ json='{ "a" : 2, "b" : 1 }', opts={sorted=true,beforeColon=1,afterColon=1,afterComma=1,padding=1} },
|
74
|
+
{ json='{ "a" : 2, "b" : 1 }', opts={sorted=true,aroundColon=1,afterComma=1,objectPadding=1} },
|
75
|
+
{ json='{"a" : 2, "b" : 1}', opts={sorted=true,beforeColon=1,afterColon=1,afterComma=1,arrayPadding=1} },
|
76
|
+
{ json='{ "a" : 2, "b" : 1 }', opts={sorted=true,aroundColon=2,afterComma=1,padding=2} },
|
77
|
+
{ json='{ "a":2, "b":1 }', opts={sorted=true,afterComma=1,padding=2} },
|
78
|
+
{ json={'{"b": 1,"a": 2}','{"a": 2,"b": 1}'}, opts={afterColon1=2} },
|
79
|
+
{ json={'{"b" : 1,"a" : 2}','{"a" : 2,"b" : 1}'}, opts={aroundColon1=2} },
|
80
|
+
{ json={"{\n \"b\":1,\n \"a\":2\n}","{\n \"a\":2,\n \"b\":1\n}"}, opts={wrap=true,aroundColon1=2} },
|
81
|
+
{ json={"{\n \"b\": 1,\n \"a\": 2\n}","{\n \"a\": 2,\n \"b\": 1\n}"}, opts={wrap=true,afterColon=1} },
|
82
|
+
{ json={"{\n \"b\": 1,\n \"a\": 2\n}","{\n \"a\": 2,\n \"b\": 1\n}"}, opts={wrap=true,afterColonN=1} },
|
83
|
+
{ json="{\"a\":2,\n \"b\":1}", opts={sort=true,wrap=true,short=true} },
|
84
|
+
{ json="{\"a\": 2,\n \"b\": 1}", opts={sort=true,wrap=true,short=true,afterColon=1} },
|
85
|
+
{ json="{\"a\": 2,\n \"b\": 1}", opts={sort=true,wrap=true,short=true,afterColonN=1} },
|
86
|
+
{ json="{\"a\":2,\n \"b\":1}", opts={sort=true,wrap=true,short=true,afterColon1=1} },
|
87
|
+
}},
|
88
|
+
|
89
|
+
{value={b=1,aaa=2,cc=3}, tests={
|
90
|
+
{ json="{\n \"aaa\":2,\n \"b\":1,\n \"cc\":3\n}", opts={sort=true,wrap=true} },
|
91
|
+
{ json="{\n \"aaa\":2,\n \"b\" :1,\n \"cc\" :3\n}", opts={sort=true,wrap=true,aligned=true} },
|
92
|
+
{ json='{"aaa":2,"b":1,"cc":3}', opts={sort=true,aligned=true} },
|
93
|
+
{ json="{\n \"aaa\":2,\n \"b\" :1,\n \"cc\" :3\n}", opts={wrap=true,aligned=true,sorted=true} },
|
94
|
+
}},
|
95
|
+
|
96
|
+
{value={a=1}, tests={
|
97
|
+
{ json='{"a":1}' },
|
98
|
+
{ json="{\n \"a\":1\n}", opts={wrap=true} },
|
99
|
+
{ json="{\n \"a\":1\n }", opts={wrap=true, indentLast=true} },
|
100
|
+
{ json="{\n \"a\":1\n }", opts={wrap=true, indentLast=true, indent=" " } },
|
101
|
+
}},
|
102
|
+
|
103
|
+
{value={b=17, a=42}, tests={
|
104
|
+
{ json="{\"a\":42,\n \"b\":17}", opts={wrap=10,sorted=true,short=true} },
|
105
|
+
{ json="{\"a\":42,\n \"b\":17}", opts={wrap=10,sort=true, short=true} },
|
106
|
+
{ json="{\n \"a\":42,\n \"b\":17\n}", opts={wrap=1,sorted=true} },
|
107
|
+
{ json="{\n \"a\":42,\n \"b\":17\n}", opts={wrap=1,sort=true} },
|
108
|
+
{ json="{\"a\":42,\"b\":17}", opts={wrap=false, sort=function(k) return k end } },
|
109
|
+
{ json="{\"b\":17,\"a\":42}", opts={wrap=false, sort=function(k,v) return v end } },
|
110
|
+
{ json="{\"a\":42,\"b\":17}", opts={wrap=false, sort=function(k,v) return -v end } },
|
111
|
+
{ json="{\"a\":42,\"b\":17}", opts={wrap=false, sort=function(k,v,o) return v==o.a and 0 or 1 end } },
|
112
|
+
{ json="{\n\"b\":17,\n\"a\":42\n}", opts={wrap=1,indent="",sort=function(k) return k=="a" and 1 or 0 end } },
|
113
|
+
{ json="{\n\"a\":42,\n\"b\":17\n}", opts={wrap=1,indent="",sort=function(k) return k=="a" and 0 or 1 end } },
|
114
|
+
}},
|
115
|
+
|
116
|
+
{value={1,{a=2},3}, tests={
|
117
|
+
{ json='[1,{"a":2},3]' },
|
118
|
+
{ json='[ 1,{ "a":2 },3 ]', opts={padding=1} },
|
119
|
+
{ json='[ 1, { "a":2 }, 3 ]', opts={padding=1,afterComma=1} },
|
120
|
+
{ json="[\n 1,\n {\n \"a\":2\n },\n 3\n]", opts={wrap=true} },
|
121
|
+
{ json="[\n 1,\n {\"a\":2},\n 3\n]", opts={wrap=10} },
|
122
|
+
{ json="[\n 1,\n {\n \"a\":2\n },\n 3\n ]", opts={wrap=true,indentLast=true} },
|
123
|
+
}},
|
124
|
+
|
125
|
+
{value={1,{a=2,b=3},4}, tests={
|
126
|
+
{ json={"[1,\n {\"a\":2,\n \"b\":3},\n 4]","[1,\n {\"b\":3,\n \"a\":2},\n 4]"}, opts={wrap=0,short=true} },
|
127
|
+
}},
|
128
|
+
|
129
|
+
{value={a=1,b={2,3,4},c=3}, tests={
|
130
|
+
{ json='{"a":1,"b":[2,3,4],"c":3}', opts={sort=true} },
|
131
|
+
{ json="{\n \"a\":1,\n \"b\":[2,3,4],\n \"c\":3\n}", opts={sort=true,wrap=10} },
|
132
|
+
{ json="{\n \"a\":1,\n \"b\":[\n 2,\n 3,\n 4\n ],\n \"c\":3\n}", opts={sort=true,wrap=true} },
|
133
|
+
{ json="{\n \"a\":1,\n \"b\":[\n 2,\n 3,\n 4\n ],\n \"c\":3\n }", opts={sort=true,wrap=true,indentLast=true} },
|
134
|
+
}},
|
135
|
+
|
136
|
+
{value={hooo=42,whee={'yaaa','oooo','booy'},zoop="whoop"}, tests={
|
137
|
+
{ json="{\"hooo\":42,\n \"whee\":[\"yaaa\",\n \"oooo\",\n \"booy\"],\n \"zoop\":\"whoop\"}", opts={sort=true,wrap=20,short=true} },
|
138
|
+
}},
|
139
|
+
|
140
|
+
{value={ a={ {x="foo",y="jim"}, {x="bar",y="jam"} } }, tests={
|
141
|
+
{ json="{\"a\":[{\"x\":\"foo\",\n \"y\":\"jim\"},\n {\"x\":\"bar\",\n \"y\":\"jam\"}]}", opts={sort=true,wrap=true,short=true} },
|
142
|
+
}},
|
143
|
+
|
144
|
+
{value={abcdefghij={{abcdefghijklmnop={}}}}, tests={
|
145
|
+
{ json='{"abcdefghij":[{"abcdefghijklmnop":[]}]}' },
|
146
|
+
{ json='{"abcdefghij":[{"abcdefghijklmnop":{}}]}', opts={emptyTablesAreObjects=true} },
|
147
|
+
{ json='{"abcdefghij" : [{"abcdefghijklmnop" : []}]}', opts={wrap=1, short=true, aroundColonN=1} },
|
148
|
+
}},
|
149
|
+
|
150
|
+
{value={foo={}}, tests={
|
151
|
+
{ json='{"foo":[]}' },
|
152
|
+
{ json='{"foo":[]}', opts={wrap=false} },
|
153
|
+
{ json='{\n "foo":[]\n}', opts={wrap=5} },
|
154
|
+
{ json='{"foo":[]}', opts={wrap=1, short=true} },
|
155
|
+
}},
|
156
|
+
|
157
|
+
{value={"foo",{},"bar"}, tests={
|
158
|
+
{ json='[\n "foo",\n {},\n "bar"\n]', opts={wrap=1, emptyTablesAreObjects=true} },
|
159
|
+
{ json='[\n "foo",\n [],\n "bar"\n]', opts={wrap=1} },
|
160
|
+
{ json='["foo",\n {},\n "bar"]', opts={wrap=1, short=true, emptyTablesAreObjects=true} },
|
161
|
+
{ json='["foo",\n [],\n "bar"]', opts={wrap=1, short=true} },
|
162
|
+
}},
|
163
|
+
|
164
|
+
{value={"foo",{},"bar"}, tests={
|
165
|
+
{ json='[\n "foo",\n [],\n "bar"\n]', opts={wrap=1} },
|
166
|
+
{ json='["foo",\n [],\n "bar"]', opts={wrap=1, short=true} },
|
167
|
+
}},
|
168
|
+
|
169
|
+
{value={"foo",{{},{{foo={}},42}},"bar"}, tests={
|
170
|
+
{ json='["foo",\n [[],\n [{"foo":[]},\n 42]],\n "bar"]', opts={wrap=1, short=true} },
|
171
|
+
}},
|
172
|
+
|
173
|
+
{value={a={b={c={d={e={f={g={h={i={j={k={l={m=1}}}}}}}}}}}}}, tests={
|
174
|
+
{ json='{"a":{"b":{"c":{"d":{"e":{"f":{"g":{"h":{"i":{"j":{"k":{"l":{"m":1}}}}}}}}}}}}}', opts={wrap=false} },
|
175
|
+
{ json='{"a":{"b":{"c":{"d":{"e":{"f":{"g":{"h":{"i":{"j":{"k":{"l":{"m":1}}}}}}}}}}}}}', opts={wrap=1,short=true} },
|
176
|
+
{ json="{\n \"a\":{\n \"b\":{\n \"c\":{\n \"d\":{\n \"e\":{\n \"f\":{\n \"g\":{\n \"h\":{\n \"i\":{\n \"j\":{\n \"k\":{\n \"l\":{\n \"m\":1\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n}", opts={wrap=1} },
|
177
|
+
}},
|
178
|
+
|
179
|
+
{value={1,2,3,a=4,['for']=5}, tests={
|
180
|
+
{ json='{[1]=1,[2]=2,[3]=3,a=4,["for"]=5}', opts={lua=true, sort=true} },
|
181
|
+
{ json='{\n [1]=1,\n [2]=2,\n [3]=3,\n a=4,\n ["for"]=5\n}', opts={lua=true, sort=true, wrap=true} },
|
182
|
+
}},
|
183
|
+
|
184
|
+
{value={inf=1/0, neginf=-1/0, nan=0/0}, tests={
|
185
|
+
{ json='{"inf":9e9999,"nan":"NaN","neginf":-9e9999}', opts={sort=true} },
|
186
|
+
{ json='{inf=1/0,nan=0/0,neginf=-1/0}', opts={sort=true, lua=true} },
|
187
|
+
}},
|
188
|
+
|
189
|
+
{value={0, 1, 1.1, 1.555555}, tests={
|
190
|
+
{ json='[0,1,1.1,1.555555]', opts={forceFloats=false} },
|
191
|
+
{ json='[0.0,1.0,1.1,1.555555]', opts={forceFloats=true} },
|
192
|
+
{ json='[0.000,1.000,1.100,1.556]', opts={forceFloats=true, decimals=3} },
|
193
|
+
{ json='[0.0,1.0,1.1,1.556]', opts={forceFloats=true, decimals=3, trimTrailingZeros=true} },
|
194
|
+
{ json='[0,1,1.1,1.556]', opts={forceFloats=false, decimals=3, trimTrailingZeros=true} },
|
195
|
+
}},
|
196
|
+
|
197
|
+
{value={floats={0, 1, 0.1, 1.555555}, raw={0, 1, 0.1, 1.555555}}, tests={
|
198
|
+
{ json='{"floats":[0,1,0.1,1.555555],"raw":[0,1,0.1,1.555555]}', opts={forceFloats=false, sort=true} },
|
199
|
+
{ json='{"floats":[0.0,1.0,0.1,1.555555],"raw":[0.0,1.0,0.1,1.555555]}', opts={forceFloats=true, sort=true} },
|
200
|
+
{ json='{"floats":[0.0,1.0,0.1,1.555555],"raw":[0,1,0.1,1.555555]}', opts={forceFloatsIn={'floats'}, sort=true} },
|
201
|
+
|
202
|
+
{ json='{"floats":[0,1,0.100,1.556],"raw":[0,1,0.100,1.556]}', opts={forceFloats=false, decimals=3, sort=true} },
|
203
|
+
{ json='{"floats":[0.000,1.000,0.100,1.556],"raw":[0.000,1.000,0.100,1.556]}', opts={forceFloats=true, decimals=3, sort=true} },
|
204
|
+
{ json='{"floats":[0.000,1.000,0.100,1.556],"raw":[0,1,0.100,1.556]}', opts={forceFloatsIn={'floats'}, decimals=3, sort=true} },
|
205
|
+
|
206
|
+
{ json='{"floats":[0,1,0.1,1.556],"raw":[0,1,0.1,1.556]}', opts={forceFloats=false, decimals=3, trimTrailingZeros=true, sort=true} },
|
207
|
+
{ json='{"floats":[0.0,1.0,0.1,1.556],"raw":[0.0,1.0,0.1,1.556]}', opts={forceFloats=true, decimals=3, trimTrailingZeros=true, sort=true} },
|
208
|
+
{ json='{"floats":[0.0,1.0,0.1,1.556],"raw":[0,1,0.1,1.556]}', opts={forceFloatsIn={'floats'}, decimals=3, trimTrailingZeros=true, sort=true} },
|
209
|
+
}},
|
210
|
+
|
211
|
+
{value={1,2,3,{a={4,5,{a=6, b=7}}, b={8,9,{a=10, b=11}}}}, tests={
|
212
|
+
{ json='[1,2,3,{"a":[4,5,{"a":6,"b":7}],"b":[8,9,{"a":10,"b":11}]}]', opts={sort=true} },
|
213
|
+
{ json='[1.0,2.0,3.0,{"a":[4.0,5.0,{"a":6.0,"b":7.0}],"b":[8.0,9.0,{"a":10.0,"b":11.0}]}]', opts={forceFloats=true, wrap=false, sort=true} },
|
214
|
+
{ json='[1,2,3,{"a":[4.0,5.0,{"a":6.0,"b":7}],"b":[8,9,{"a":10.0,"b":11}]}]', opts={forceFloatsIn={'a'}, wrap=false, sort=true} },
|
215
|
+
}},
|
216
|
+
|
217
|
+
{value={1,2,3, {bar={4,5,6}, foo={7,8,9}}}, tests={
|
218
|
+
{ json='[\n\t1,\n\t2,\n\t3,\n\t{\n\t\t"bar":[4,5,6],\n\t\t"foo":[7,8,9]\n\t}\n]', opts={wrap=30, sort=true, indent="\t"} },
|
219
|
+
{ json='[\n\t1,\n\t2,\n\t3,\n\t{\n\t\t"bar":[4.0,5.0,6.0],\n\t\t"foo":[7,8,9]\n\t}\n]', opts={wrap=30, sort=true, indent="\t", forceFloatsIn={'bar'}} },
|
220
|
+
{ json='[\n\t1,\n\t2,\n\t3,\n\t{\n\t\t"bar":[4,5,6],\n\t\t"foo":[7.0,8.0,9.0]\n\t}\n]', opts={wrap=30, sort=true, indent="\t", forceFloatsIn={'foo'}} },
|
221
|
+
{ json='[\n\t1,\n\t2,\n\t3,\n\t{\n\t\t"bar":[4.0,5.0,6.0],\n\t\t"foo":[7.0,8.0,9.0]\n\t}\n]', opts={wrap=30, sort=true, indent="\t", forceFloatsIn={'foo', 'bar'}} },
|
222
|
+
{ json='[\n\t1.0,\n\t2.0,\n\t3.0,\n\t{\n\t\t"bar":[4.0,5.0,6.0],\n\t\t"foo":[7.0,8.0,9.0]\n\t}\n]', opts={wrap=30, sort=true, indent="\t", forceFloats=true} },
|
223
|
+
}},
|
224
|
+
|
225
|
+
}
|
data/test/tests.rb
CHANGED
@@ -13,6 +13,8 @@ TESTS = [
|
|
13
13
|
{value:5.0001, tests:[
|
14
14
|
{json:"5.0001"},
|
15
15
|
{json:"5.000", opts:{decimals:3}},
|
16
|
+
{json:"5.0", opts:{decimals:3, trim_trailing_zeros:true, force_floats:true}},
|
17
|
+
{json:"5.000", opts:{decimals:3, trim_trailing_zeros:false, force_floats:true}},
|
16
18
|
]},
|
17
19
|
{value:4.2, tests:[
|
18
20
|
{json:"4.2"},
|
@@ -174,7 +176,7 @@ TESTS = [
|
|
174
176
|
{ json:'{"a":{"b":{"c":{"d":{"e":{"f":{"g":{"h":{"i":{"j":{"k":{"l":{"m":1}}}}}}}}}}}}}', opts:{wrap:false} },
|
175
177
|
{ json:'{"a":{"b":{"c":{"d":{"e":{"f":{"g":{"h":{"i":{"j":{"k":{"l":{"m":1}}}}}}}}}}}}}', opts:{wrap:1,short:true} },
|
176
178
|
{ json:"{\n \"a\":{\n \"b\":{\n \"c\":{\n \"d\":{\n \"e\":{\n \"f\":{\n \"g\":{\n \"h\":{\n \"i\":{\n \"j\":{\n \"k\":{\n \"l\":{\n \"m\":1\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n }\n}", opts:{wrap:1} },
|
177
|
-
]},
|
179
|
+
]},
|
178
180
|
|
179
181
|
# Issue #27
|
180
182
|
{value:{'b'=>2, a:1}, tests:[
|
@@ -184,5 +186,45 @@ TESTS = [
|
|
184
186
|
{json:'{"a":1,"b":2}', opts:{wrap:false, sort:->(k,v,o){k.to_s}}},
|
185
187
|
{json:'{"a":1,"b":2}', opts:{wrap:false, sort:true}},
|
186
188
|
]},
|
189
|
+
|
190
|
+
{value:{inf:1.0/0, neginf:-1.0/0, nan:0.0/0}, tests:[
|
191
|
+
{ json:'{"inf":9e9999,"nan":"NaN","neginf":-9e9999}', opts:{sort:true} },
|
192
|
+
]},
|
193
|
+
|
194
|
+
{value:[0, 1, 1.1, 1.555555], tests:[
|
195
|
+
{ json:'[0,1,1.1,1.555555]', opts:{force_floats:false} },
|
196
|
+
{ json:'[0.0,1.0,1.1,1.555555]', opts:{force_floats:true} },
|
197
|
+
{ json:'[0.000,1.000,1.100,1.556]', opts:{force_floats:true, decimals:3} },
|
198
|
+
{ json:'[0.0,1.0,1.1,1.556]', opts:{force_floats:true, decimals:3, trim_trailing_zeros:true} },
|
199
|
+
{ json:'[0,1,1.1,1.556]', opts:{force_floats:false, decimals:3, trim_trailing_zeros:true} },
|
200
|
+
]},
|
201
|
+
|
202
|
+
{value:{floats:[0, 1, 0.1, 1.555555], raw:[0, 1, 0.1, 1.555555]}, tests:[
|
203
|
+
{ json:'{"floats":[0,1,0.1,1.555555],"raw":[0,1,0.1,1.555555]}', opts:{force_floats:false} },
|
204
|
+
{ json:'{"floats":[0.0,1.0,0.1,1.555555],"raw":[0.0,1.0,0.1,1.555555]}', opts:{force_floats:true} },
|
205
|
+
{ json:'{"floats":[0.0,1.0,0.1,1.555555],"raw":[0,1,0.1,1.555555]}', opts:{force_floats_in:['floats']} },
|
206
|
+
|
207
|
+
{ json:'{"floats":[0,1,0.100,1.556],"raw":[0,1,0.100,1.556]}', opts:{force_floats:false, decimals:3} },
|
208
|
+
{ json:'{"floats":[0.000,1.000,0.100,1.556],"raw":[0.000,1.000,0.100,1.556]}', opts:{force_floats:true, decimals:3} },
|
209
|
+
{ json:'{"floats":[0.000,1.000,0.100,1.556],"raw":[0,1,0.100,1.556]}', opts:{force_floats_in:['floats'], decimals:3} },
|
210
|
+
|
211
|
+
{ json:'{"floats":[0,1,0.1,1.556],"raw":[0,1,0.1,1.556]}', opts:{force_floats:false, decimals:3, trim_trailing_zeros:true} },
|
212
|
+
{ json:'{"floats":[0.0,1.0,0.1,1.556],"raw":[0.0,1.0,0.1,1.556]}', opts:{force_floats:true, decimals:3, trim_trailing_zeros:true} },
|
213
|
+
{ json:'{"floats":[0.0,1.0,0.1,1.556],"raw":[0,1,0.1,1.556]}', opts:{force_floats_in:['floats'], decimals:3, trim_trailing_zeros:true} },
|
214
|
+
]},
|
215
|
+
|
216
|
+
{value:[1,2,3,{a:[4,5,{a:6, b:7}], b:[8,9,{a:10, b:11}]}], tests:[
|
217
|
+
{ json:'[1,2,3,{"a":[4,5,{"a":6,"b":7}],"b":[8,9,{"a":10,"b":11}]}]', opts:{} },
|
218
|
+
{ json:'[1.0,2.0,3.0,{"a":[4.0,5.0,{"a":6.0,"b":7.0}],"b":[8.0,9.0,{"a":10.0,"b":11.0}]}]', opts:{force_floats:true, wrap:false} },
|
219
|
+
{ json:'[1,2,3,{"a":[4.0,5.0,{"a":6.0,"b":7}],"b":[8,9,{"a":10.0,"b":11}]}]', opts:{force_floats_in:['a'], wrap:false} },
|
220
|
+
]},
|
221
|
+
|
222
|
+
{value:[1,2,3, {bar:[4,5,6], foo:[7,8,9]}], tests:[
|
223
|
+
{ json:%Q{[\n\t1,\n\t2,\n\t3,\n\t{\n\t\t"bar":[4,5,6],\n\t\t"foo":[7,8,9]\n\t}\n]}, opts:{wrap:20, indent:"\t"} },
|
224
|
+
{ json:%Q{[\n\t1,\n\t2,\n\t3,\n\t{\n\t\t"bar":[4.0,5.0,6.0],\n\t\t"foo":[7,8,9]\n\t}\n]}, opts:{wrap:20, indent:"\t", force_floats_in:["bar"]} },
|
225
|
+
{ json:%Q{[\n\t1,\n\t2,\n\t3,\n\t{\n\t\t"bar":[4,5,6],\n\t\t"foo":[7.0,8.0,9.0]\n\t}\n]}, opts:{wrap:20, indent:"\t", force_floats_in:["foo"]} },
|
226
|
+
{ json:%Q{[\n\t1,\n\t2,\n\t3,\n\t{\n\t\t"bar":[4.0,5.0,6.0],\n\t\t"foo":[7.0,8.0,9.0]\n\t}\n]}, opts:{wrap:20, indent:"\t", force_floats_in:["foo", "bar"]} },
|
227
|
+
{ json:%Q{[\n\t1.0,\n\t2.0,\n\t3.0,\n\t{\n\t\t"bar":[4.0,5.0,6.0],\n\t\t"foo":[7.0,8.0,9.0]\n\t}\n]}, opts:{wrap:20, indent:"\t", force_floats:true} },
|
228
|
+
]},
|
187
229
|
]
|
188
230
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: neatjson
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gavin Kistner
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-08-29 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: 'Generate JSON strings from Ruby objects with flexible formatting options.
|
14
14
|
Key features: keep arrays and objects on a single line when they fit; format floats
|
@@ -26,14 +26,16 @@ files:
|
|
26
26
|
- neatjson.gemspec
|
27
27
|
- test/large.json
|
28
28
|
- test/test_neatjson.js
|
29
|
+
- test/test_neatjson.lua
|
29
30
|
- test/test_neatjson.rb
|
30
31
|
- test/tests.js
|
32
|
+
- test/tests.lua
|
31
33
|
- test/tests.rb
|
32
34
|
homepage: http://github.com/Phrogz/NeatJSON
|
33
35
|
licenses:
|
34
36
|
- MIT
|
35
37
|
metadata: {}
|
36
|
-
post_install_message:
|
38
|
+
post_install_message:
|
37
39
|
rdoc_options: []
|
38
40
|
require_paths:
|
39
41
|
- lib
|
@@ -48,9 +50,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
48
50
|
- !ruby/object:Gem::Version
|
49
51
|
version: '0'
|
50
52
|
requirements: []
|
51
|
-
|
52
|
-
|
53
|
-
signing_key:
|
53
|
+
rubygems_version: 3.2.3
|
54
|
+
signing_key:
|
54
55
|
specification_version: 4
|
55
56
|
summary: Pretty, powerful, flexible JSON generation.
|
56
57
|
test_files: []
|