neatjson 0.9 → 0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
 - data/LICENSE.txt +2 -2
 - data/README.md +31 -22
 - data/lib/neatjson.rb +35 -23
 - data/neatjson.gemspec +1 -1
 - data/test/test_neatjson.lua +83 -83
 - data/test/tests.js +30 -1
 - data/test/tests.lua +34 -2
 - data/test/tests.rb +30 -0
 - metadata +6 -7
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 2 
     | 
    
         
            +
            SHA256:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: d2820b11ac77b92de38f28231d4826cd1e77ad0f9140da5b9e41eaf995dee5ce
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: b5cdc8378b227f574f8de0d517e7964ca6cfe96e40ff30873d6a412cda5844f4
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 1681f5edb27ec6075e5bfd1d9c8a9e806b3ee4d2f76dea65d97a45d5b22fa4feefa20b2507ff060dd424cca346b4bee6ebdcd05735543dde71170f4ad2d55125
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 14a3138ab4eb40fce7f9052e250f7c1ca7394c460b3d3f4cc8ccd87d8b91bed870d395719c3c3a0343990284af37589ef5e3abc86bd0f58c2b40ed946197c8ba
         
     | 
    
        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
    
    | 
         @@ -189,29 +189,33 @@ var json = neatJSON( myValue, { arrayPadding:1, afterComma:1, beforeColonN:2, in 
     | 
|
| 
       189 
189 
     | 
    
         
             
            local json = neatJSON( myValue, { arrayPadding=1, afterComma=1, beforeColonN=2, indentLast=true } )
         
     | 
| 
       190 
190 
     | 
    
         
             
            ~~~
         
     | 
| 
       191 
191 
     | 
    
         | 
| 
       192 
     | 
    
         
            -
            * `wrap` 
     | 
| 
       193 
     | 
    
         
            -
            * `indent` 
     | 
| 
       194 
     | 
    
         
            -
            * `indent_last` 
     | 
| 
       195 
     | 
    
         
            -
            * `short` 
     | 
| 
      
 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`
         
     | 
| 
       196 
196 
     | 
    
         
             
              * _This causes the `indent` and `indent_last` options to be ignored, instead basing indentation on array and object padding._
         
     | 
| 
       197 
     | 
    
         
            -
            * `sort` 
     | 
| 
      
 197 
     | 
    
         
            +
            * `sort`                — Sort objects' keys in alphabetical order (`true`), or supply a lambda for custom sorting. default:`false`
         
     | 
| 
       198 
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 } }`
         
     | 
| 
       199 
     | 
    
         
            -
            * `aligned` 
     | 
| 
       200 
     | 
    
         
            -
            * `decimals` 
     | 
| 
       201 
     | 
    
         
            -
            * ` 
     | 
| 
       202 
     | 
    
         
            -
            * ` 
     | 
| 
       203 
     | 
    
         
            -
            * ` 
     | 
| 
       204 
     | 
    
         
            -
             
     | 
| 
       205 
     | 
    
         
            -
            * ` 
     | 
| 
       206 
     | 
    
         
            -
            * ` 
     | 
| 
       207 
     | 
    
         
            -
            * ` 
     | 
| 
       208 
     | 
    
         
            -
            * ` 
     | 
| 
       209 
     | 
    
         
            -
            * ` 
     | 
| 
       210 
     | 
    
         
            -
            * ` 
     | 
| 
       211 
     | 
    
         
            -
            * ` 
     | 
| 
       212 
     | 
    
         
            -
            * ` 
     | 
| 
       213 
     | 
    
         
            -
            * ` 
     | 
| 
       214 
     | 
    
         
            -
            * ` 
     | 
| 
      
 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`
         
     | 
| 
       215 
219 
     | 
    
         
             
            * `emptyTablesAreObjects` — (Lua only) Should `{}` in Lua become a JSON object (`{}`) or JSON array (`[]`)? default:`false` (array)
         
     | 
| 
       216 
220 
     | 
    
         | 
| 
       217 
221 
     | 
    
         
             
            You may omit the 'value' and/or 'object' parameters in your `sort` lambda if desired. For example:
         
     | 
| 
         @@ -257,7 +261,7 @@ _Note that the JavaScript and Lua versions of NeatJSON do not provide a mechanis 
     | 
|
| 
       257 
261 
     | 
    
         | 
| 
       258 
262 
     | 
    
         
             
            ## License & Contact
         
     | 
| 
       259 
263 
     | 
    
         | 
| 
       260 
     | 
    
         
            -
            NeatJSON is copyright ©2015– 
     | 
| 
      
 264 
     | 
    
         
            +
            NeatJSON is copyright ©2015–2022 by Gavin Kistner and is released under
         
     | 
| 
       261 
265 
     | 
    
         
             
            the [MIT License](http://www.opensource.org/licenses/mit-license.php).
         
     | 
| 
       262 
266 
     | 
    
         
             
            See the LICENSE.txt file for more details.
         
     | 
| 
       263 
267 
     | 
    
         | 
| 
         @@ -274,6 +278,11 @@ For other communication you can [email the author directly](mailto:!@phrogz.net? 
     | 
|
| 
       274 
278 
     | 
    
         | 
| 
       275 
279 
     | 
    
         
             
            ## HISTORY
         
     | 
| 
       276 
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 
     | 
    
         
            +
             
     | 
| 
       277 
286 
     | 
    
         
             
            * **v0.9** — July 29, 2019
         
     | 
| 
       278 
287 
     | 
    
         
             
              * Add Lua version, serializing to both JSON and Lua table literals
         
     | 
| 
       279 
288 
     | 
    
         
             
              * All languages serialize Infinity/-Infinity to JSON as `9e9999` and `-9e9999`
         
     | 
    
        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,21 +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 
72 
     | 
    
         
             
            					if o.infinite?
         
     | 
| 
       67 
73 
     | 
    
         
             
            						"#{indent}#{o<0 ? "-9e9999" : "9e9999"}"
         
     | 
| 
       68 
74 
     | 
    
         
             
            					elsif o.nan?
         
     | 
| 
       69 
75 
     | 
    
         
             
            						"#{indent}\"NaN\""
         
     | 
| 
       70 
     | 
    
         
            -
            					elsif (o==o.to_i) && (o.to_s !~ /e/)
         
     | 
| 
       71 
     | 
    
         
            -
            						build[o.to_i,indent]
         
     | 
| 
      
 76 
     | 
    
         
            +
            					elsif !floats_forced && (o==o.to_i) && (o.to_s !~ /e/)
         
     | 
| 
      
 77 
     | 
    
         
            +
            						build[o.to_i, indent, floats_forced]
         
     | 
| 
       72 
78 
     | 
    
         
             
            					elsif opts[:decimals]
         
     | 
| 
       73 
     | 
    
         
            -
            						 
     | 
| 
      
 79 
     | 
    
         
            +
            						if opts[:trim_trailing_zeros]
         
     | 
| 
      
 80 
     | 
    
         
            +
            							"#{indent}#{o.round(opts[:decimals])}"
         
     | 
| 
      
 81 
     | 
    
         
            +
            						else
         
     | 
| 
      
 82 
     | 
    
         
            +
            							"#{indent}%.#{opts[:decimals]}f" % o
         
     | 
| 
      
 83 
     | 
    
         
            +
            						end
         
     | 
| 
       74 
84 
     | 
    
         
             
            					else
         
     | 
| 
       75 
85 
     | 
    
         
             
            						"#{indent}#{o}"
         
     | 
| 
       76 
86 
     | 
    
         
             
            					end
         
     | 
| 
         @@ -79,19 +89,19 @@ module JSON 
     | 
|
| 
       79 
89 
     | 
    
         
             
            					if o.empty?
         
     | 
| 
       80 
90 
     | 
    
         
             
            						"#{indent}[]"
         
     | 
| 
       81 
91 
     | 
    
         
             
            					else
         
     | 
| 
       82 
     | 
    
         
            -
            						pieces = o.map{ |v| build[v,''] }
         
     | 
| 
      
 92 
     | 
    
         
            +
            						pieces = o.map{ |v| build[v, '', floats_forced] }
         
     | 
| 
       83 
93 
     | 
    
         
             
            						one_line = "#{indent}[#{apad}#{pieces.join comma}#{apad}]"
         
     | 
| 
       84 
94 
     | 
    
         
             
            						if !opts[:wrap] || (one_line.length <= opts[:wrap])
         
     | 
| 
       85 
95 
     | 
    
         
             
            							one_line
         
     | 
| 
       86 
96 
     | 
    
         
             
            						elsif opts[:short]
         
     | 
| 
       87 
97 
     | 
    
         
             
            							indent2 = "#{indent} #{apad}"
         
     | 
| 
       88 
     | 
    
         
            -
            							pieces = o.map{ |v| build[ 
     | 
| 
      
 98 
     | 
    
         
            +
            							pieces = o.map{ |v| build[v, indent2, floats_forced] }
         
     | 
| 
       89 
99 
     | 
    
         
             
            							pieces[0] = pieces[0].sub indent2, "#{indent}[#{apad}"
         
     | 
| 
       90 
100 
     | 
    
         
             
            							pieces[pieces.length-1] = "#{pieces.last}#{apad}]"
         
     | 
| 
       91 
101 
     | 
    
         
             
            							pieces.join ",\n"
         
     | 
| 
       92 
102 
     | 
    
         
             
            						else
         
     | 
| 
       93 
103 
     | 
    
         
             
            							indent2 = "#{indent}#{opts[:indent]}"
         
     | 
| 
       94 
     | 
    
         
            -
            							"#{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}]"
         
     | 
| 
       95 
105 
     | 
    
         
             
            						end
         
     | 
| 
       96 
106 
     | 
    
         
             
            					end
         
     | 
| 
       97 
107 
     | 
    
         | 
| 
         @@ -108,7 +118,8 @@ module JSON 
     | 
|
| 
       108 
118 
     | 
    
         
             
            								when 3 then o.sort_by{ |k,v| sort[k,v,o] }
         
     | 
| 
       109 
119 
     | 
    
         
             
            								end
         
     | 
| 
       110 
120 
     | 
    
         
             
            						end
         
     | 
| 
       111 
     | 
    
         
            -
            						 
     | 
| 
      
 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])] ] }
         
     | 
| 
       112 
123 
     | 
    
         
             
            						keyvals = keyvals.map{ |kv| kv.join(colon1) }.join(comma)
         
     | 
| 
       113 
124 
     | 
    
         
             
            						one_line = "#{indent}{#{opad}#{keyvals}#{opad}}"
         
     | 
| 
       114 
125 
     | 
    
         
             
            						if !opts[:wrap] || (one_line.length <= opts[:wrap])
         
     | 
| 
         @@ -122,11 +133,12 @@ module JSON 
     | 
|
| 
       122 
133 
     | 
    
         
             
            									formatk = "%-#{longest}s"
         
     | 
| 
       123 
134 
     | 
    
         
             
            									keyvals.map!{ |k,v| [ formatk % k,v] }
         
     | 
| 
       124 
135 
     | 
    
         
             
            								end
         
     | 
| 
       125 
     | 
    
         
            -
            								keyvals.map 
     | 
| 
      
 136 
     | 
    
         
            +
            								keyvals.map!.with_index do |(k,v),i|
         
     | 
| 
      
 137 
     | 
    
         
            +
            									floats_forced = opts[:force_floats] || opts[:force_floats_in].include?(keys[i])
         
     | 
| 
       126 
138 
     | 
    
         
             
            									indent2 = " "*"#{k}#{colonn}".length
         
     | 
| 
       127 
     | 
    
         
            -
            									one_line = "#{k}#{colonn}#{build[v,'']}"
         
     | 
| 
      
 139 
     | 
    
         
            +
            									one_line = "#{k}#{colonn}#{build[v, '', floats_forced]}"
         
     | 
| 
       128 
140 
     | 
    
         
             
            									if opts[:wrap] && (one_line.length > opts[:wrap]) && (v.is_a?(Array) || v.is_a?(Hash))
         
     | 
| 
       129 
     | 
    
         
            -
            										"#{k}#{colonn}#{build[v,indent2].lstrip}"
         
     | 
| 
      
 141 
     | 
    
         
            +
            										"#{k}#{colonn}#{build[v, indent2, floats_forced].lstrip}"
         
     | 
| 
       130 
142 
     | 
    
         
             
            									else
         
     | 
| 
       131 
143 
     | 
    
         
             
            										one_line
         
     | 
| 
       132 
144 
     | 
    
         
             
            									end
         
     | 
| 
         @@ -141,9 +153,9 @@ module JSON 
     | 
|
| 
       141 
153 
     | 
    
         
             
            								end
         
     | 
| 
       142 
154 
     | 
    
         
             
            								indent2 = "#{indent}#{opts[:indent]}"
         
     | 
| 
       143 
155 
     | 
    
         
             
            								keyvals.map! do |k,v|
         
     | 
| 
       144 
     | 
    
         
            -
            									one_line = "#{k}#{colonn}#{build[v,'']}"
         
     | 
| 
      
 156 
     | 
    
         
            +
            									one_line = "#{k}#{colonn}#{build[v, '', floats_forced]}"
         
     | 
| 
       145 
157 
     | 
    
         
             
            									if opts[:wrap] && (one_line.length > opts[:wrap]) && (v.is_a?(Array) || v.is_a?(Hash))
         
     | 
| 
       146 
     | 
    
         
            -
            										"#{k}#{colonn}#{build[v,indent2].lstrip}"
         
     | 
| 
      
 158 
     | 
    
         
            +
            										"#{k}#{colonn}#{build[v, indent2, floats_forced].lstrip}"
         
     | 
| 
       147 
159 
     | 
    
         
             
            									else
         
     | 
| 
       148 
160 
     | 
    
         
             
            										one_line
         
     | 
| 
       149 
161 
     | 
    
         
             
            									end
         
     | 
| 
         @@ -158,6 +170,6 @@ module JSON 
     | 
|
| 
       158 
170 
     | 
    
         
             
            			end
         
     | 
| 
       159 
171 
     | 
    
         
             
            		end
         
     | 
| 
       160 
172 
     | 
    
         | 
| 
       161 
     | 
    
         
            -
            		build[object,'']
         
     | 
| 
      
 173 
     | 
    
         
            +
            		build[object, '', opts[:force_floats]]
         
     | 
| 
       162 
174 
     | 
    
         
             
            	end
         
     | 
| 
       163 
175 
     | 
    
         
             
            end
         
     | 
    
        data/neatjson.gemspec
    CHANGED
    
    
    
        data/test/test_neatjson.lua
    CHANGED
    
    | 
         @@ -1,83 +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 
     | 
    
         
            -
            ))
         
     | 
| 
      
 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:[
         
     | 
| 
         @@ -173,6 +175,33 @@ exports.tests = [ 
     | 
|
| 
       173 
175 
     | 
    
         
             
            		{ json:'{"inf":9e9999,"nan":"NaN","neginf":-9e9999}', opts:{sort:true} },
         
     | 
| 
       174 
176 
     | 
    
         
             
            	]},
         
     | 
| 
       175 
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 
     | 
    
         
            +
            	]},
         
     | 
| 
       176 
205 
     | 
    
         | 
| 
       177 
206 
     | 
    
         
             
            	// {value:Class.new{ def to_json(*a); {a:1}.to_json(*a); end }.new, tests:[
         
     | 
| 
       178 
207 
     | 
    
         
             
            	// 	{ json:'{  "a":1}' },
         
     | 
    
        data/test/tests.lua
    CHANGED
    
    | 
         @@ -14,6 +14,9 @@ return { 
     | 
|
| 
       14 
14 
     | 
    
         
             
            	{value=5.0001, tests={
         
     | 
| 
       15 
15 
     | 
    
         
             
            		{json="5.0001"},
         
     | 
| 
       16 
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}},
         
     | 
| 
       17 
20 
     | 
    
         
             
            	}},
         
     | 
| 
       18 
21 
     | 
    
         
             
            	{value=4.2, tests={
         
     | 
| 
       19 
22 
     | 
    
         
             
            		{json="4.2"},
         
     | 
| 
         @@ -174,11 +177,40 @@ return { 
     | 
|
| 
       174 
177 
     | 
    
         
             
            	}},
         
     | 
| 
       175 
178 
     | 
    
         | 
| 
       176 
179 
     | 
    
         
             
            	{value={1,2,3,a=4,['for']=5}, tests={
         
     | 
| 
       177 
     | 
    
         
            -
            		{ json='{[1]=1,[2]=2,[3]=3,a=4,["for"]=5}', opts={lua=true, sort=true} }
         
     | 
| 
      
 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} },
         
     | 
| 
       178 
182 
     | 
    
         
             
            	}},
         
     | 
| 
       179 
183 
     | 
    
         | 
| 
       180 
184 
     | 
    
         
             
            	{value={inf=1/0, neginf=-1/0, nan=0/0}, tests={
         
     | 
| 
       181 
185 
     | 
    
         
             
            		{ json='{"inf":9e9999,"nan":"NaN","neginf":-9e9999}', opts={sort=true} },
         
     | 
| 
       182 
186 
     | 
    
         
             
            		{ json='{inf=1/0,nan=0/0,neginf=-1/0}', opts={sort=true, lua=true} },
         
     | 
| 
       183 
     | 
    
         
            -
            	}}
         
     | 
| 
      
 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={} },
         
     | 
| 
      
 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} },
         
     | 
| 
      
 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} },
         
     | 
| 
      
 215 
     | 
    
         
            +
            	-- }},
         
     | 
| 
       184 
216 
     | 
    
         
             
            }
         
     | 
    
        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"},
         
     | 
| 
         @@ -188,5 +190,33 @@ TESTS = [ 
     | 
|
| 
       188 
190 
     | 
    
         
             
            	{value:{inf:1.0/0, neginf:-1.0/0, nan:0.0/0}, tests:[
         
     | 
| 
       189 
191 
     | 
    
         
             
            		{ json:'{"inf":9e9999,"nan":"NaN","neginf":-9e9999}', opts:{sort:true} },
         
     | 
| 
       190 
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 
     | 
    
         
            +
            	]},
         
     | 
| 
       191 
221 
     | 
    
         
             
            ]
         
     | 
| 
       192 
222 
     | 
    
         | 
    
        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'
         
     | 
| 
       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
         
     | 
| 
         @@ -35,7 +35,7 @@ homepage: http://github.com/Phrogz/NeatJSON 
     | 
|
| 
       35 
35 
     | 
    
         
             
            licenses:
         
     | 
| 
       36 
36 
     | 
    
         
             
            - MIT
         
     | 
| 
       37 
37 
     | 
    
         
             
            metadata: {}
         
     | 
| 
       38 
     | 
    
         
            -
            post_install_message: 
     | 
| 
      
 38 
     | 
    
         
            +
            post_install_message:
         
     | 
| 
       39 
39 
     | 
    
         
             
            rdoc_options: []
         
     | 
| 
       40 
40 
     | 
    
         
             
            require_paths:
         
     | 
| 
       41 
41 
     | 
    
         
             
            - lib
         
     | 
| 
         @@ -50,9 +50,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement 
     | 
|
| 
       50 
50 
     | 
    
         
             
                - !ruby/object:Gem::Version
         
     | 
| 
       51 
51 
     | 
    
         
             
                  version: '0'
         
     | 
| 
       52 
52 
     | 
    
         
             
            requirements: []
         
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
       55 
     | 
    
         
            -
            signing_key: 
         
     | 
| 
      
 53 
     | 
    
         
            +
            rubygems_version: 3.2.3
         
     | 
| 
      
 54 
     | 
    
         
            +
            signing_key:
         
     | 
| 
       56 
55 
     | 
    
         
             
            specification_version: 4
         
     | 
| 
       57 
56 
     | 
    
         
             
            summary: Pretty, powerful, flexible JSON generation.
         
     | 
| 
       58 
57 
     | 
    
         
             
            test_files: []
         
     |