neatjson 0.4 → 0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ffd7e1b6d8e702a1ac021f7c8dceb24bce52b4a6
4
- data.tar.gz: 956fa2524dd0f720b04b932fef9ce133311b49bf
3
+ metadata.gz: a0459381e78a14d8183c5262ac82b70bc1337ffe
4
+ data.tar.gz: bf9ee16f7b298fe1c9d97373444c39ba5f31f7b5
5
5
  SHA512:
6
- metadata.gz: c41fa707a6227ac5eec7673626f5e0dddcde3f37b946788b6625f9ac22613e93493f0fb02616215550c7af19eb22f33098a856778826238e7e62d3d9b9b73ec9
7
- data.tar.gz: 8b1f03bdb86c45d6a6b28197b5e7cfd0091dd8f8feab2123d1a4a758da2c0341e5a533098c1a1a03ac49a04e2dc68a23a3cb5d453ce82c746e14f383e96ccce5
6
+ metadata.gz: 85c571efbf5b496201b0f9147e0e830346d3441c0aca0c2118cff978b48f66ec9e6f0ea5b11d4aa14ae43720bfb7863d9b5d39f9a99d279cb2099ce879448731
7
+ data.tar.gz: 87debda657ab8272bd8039f452c83c4f6083c491258918935e7aee0497fbbcfe8468070b8e32e6219c1362d4c594c95a33ecac797c3d8a634e63ea51fb3dabf8
data/README.md CHANGED
@@ -62,10 +62,10 @@ puts JSON.neat_generate(o,sorted:true,wrap:40)
62
62
  #=> "str":"yes\nplease"
63
63
  #=> }
64
64
 
65
- puts JSON.neat_generate(o,sorted:true,wrap:40,decimals:1)
65
+ puts JSON.neat_generate(o,sorted:true,wrap:40,decimals:2)
66
66
  #=> {
67
- #=> "a":[42.0,17.0],
68
- #=> "b":42.0,
67
+ #=> "a":[42,17],
68
+ #=> "b":42.01,
69
69
  #=> "longer":true,
70
70
  #=> "str":"yes\nplease"
71
71
  #=> }
@@ -126,7 +126,7 @@ You may pass any of the following option symbols to `neat_generate`:
126
126
  * _This causes the `:indent` option to be ignored, instead basing indentation on array and object padding._
127
127
  * `:sorted` — Sort the keys for objects to be in alphabetical order? Default: `false`
128
128
  * `:aligned` — When wrapping objects, line up the colons (per object)? Default: `false`
129
- * `:decimals` — Decimal precision to use for numbers; use `false` to keep numeric values precise. Default: `false`
129
+ * `:decimals` — Decimal precision to use for non-integer numbers; use `false` to keep float values precise. Default: `false`
130
130
  * `:array_padding` — Number of spaces to put inside brackets for arrays. Default: `0`
131
131
  * `:object_padding` — Number of spaces to put inside braces for objects. Default: `0`
132
132
  * `:padding` — Shorthand to set both `:array_padding` and `:object_padding`. Default: `0`
@@ -157,6 +157,11 @@ For other communication you can [email the author directly](mailto:!@phrogz.net?
157
157
 
158
158
  ## HISTORY
159
159
 
160
+ * **v0.5** - April 19th, 2015
161
+ * Do not format integers (or floats that equal their integer) using `decimals` option.
162
+ * Make `neatJSON()` JavaScript available to Node.js as well as web browsers.
163
+ * Add (Node-based) testing for the JavaScript version.
164
+
160
165
  * **v0.4** - April 18th, 2015
161
166
  * Add JavaScript version with online runner.
162
167
 
data/lib/neatjson.rb CHANGED
@@ -11,7 +11,7 @@ module JSON
11
11
  # @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.
12
12
  # @option opts [Boolean] :sorted (false) Sort the keys for objects to be in alphabetical order.
13
13
  # @option opts [Boolean] :aligned (false) When wrapping objects, align the colons (only per object).
14
- # @option opts [Integer] :decimals (null) Decimal precision to use for numbers; omit to keep numberic values precise.
14
+ # @option opts [Integer] :decimals (null) Decimal precision to use for floats; omit to keep numberic values precise.
15
15
  # @option opts [Integer] :padding (0) Number of spaces to put inside brackets/braces for both arrays and objects.
16
16
  # @option opts [Integer] :array_padding (0) Number of spaces to put inside brackets for arrays. Overrides `:padding`.
17
17
  # @option opts [Integer] :object_padding (0) Number of spaces to put inside braces for objects. Overrides `:padding`.
@@ -41,12 +41,14 @@ module JSON
41
41
 
42
42
  build = ->(o,indent) do
43
43
  case o
44
- when String then "#{indent}#{o.inspect}"
44
+ when String,Integer then "#{indent}#{o.inspect}"
45
45
  when Symbol then "#{indent}#{o.to_s.inspect}"
46
46
  when TrueClass,FalseClass then "#{indent}#{o}"
47
47
  when NilClass then "#{indent}null"
48
- when Numeric
49
- if opts[:decimals]
48
+ when Float
49
+ if (o==o.to_i) && (o.to_s !~ /e/)
50
+ build[o.to_i,indent]
51
+ elsif opts[:decimals]
50
52
  "#{indent}%.#{opts[:decimals]}f" % o
51
53
  else
52
54
  "#{indent}#{o}"
data/neatjson.gemspec CHANGED
@@ -2,13 +2,13 @@
2
2
  require 'date'
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "neatjson"
5
- s.version = "0.4"
5
+ s.version = "0.5"
6
6
  s.date = Date.today.iso8601
7
7
  s.authors = ["Gavin Kistner"]
8
8
  s.email = "gavin@phrogz.net"
9
9
  s.homepage = "http://github.com/Phrogz/NeatJSON"
10
10
  s.summary = "Pretty, powerful, flexible JSON generation."
11
- s.description = "Generate JSON strings from Ruby objects with flexible formatting options. The most important feature is that it can behave like pp, keeping arrays and objects on a single line when they fit."
11
+ s.description = "Generate JSON strings from Ruby objects with flexible formatting options. Key features: keep arrays and objects on a single line when they fit; format floats to specific precision; sort and align object keys; adjust whitespace padding of arrays and objects, inside and around commas and colons. JavaScript version included."
12
12
  s.license = "MIT license (MIT)"
13
13
  s.platform = Gem::Platform::RUBY
14
14
  s.require_paths = ['lib']
@@ -0,0 +1,23 @@
1
+ var neatJSON = require('../javascript/neatjson.js').neatJSON;
2
+ require('./tests.js').tests.forEach(function(valTest){
3
+ var value = valTest.value;
4
+ valTest.tests.forEach(function(test){
5
+ var mesg = "neatJSON("+JSON.stringify(value);
6
+ if (test.opts){
7
+ var opts = {};
8
+ for (var k in test.opts) opts[k] = test.opts[k];
9
+ var json = neatJSON(value,opts);
10
+ mesg += ","+JSON.stringify(test.opts);
11
+ }else{
12
+ var json = neatJSON(value);
13
+ }
14
+ var success = (test.json.constructor==RegExp) ? test.json.test(json) : json==test.json;
15
+ if (!success){
16
+ console.log(mesg+")");
17
+ console.log('EXPECTED');
18
+ console.log(test.json);
19
+ console.log('ACTUAL');
20
+ console.log(json,"\n");
21
+ }
22
+ });
23
+ });
@@ -1,138 +1,15 @@
1
- require 'minitest/autorun'
2
1
  require '../lib/neatjson'
3
-
4
- class Dummy
5
- def to_json(*a)
6
- {a:1}.to_json(*a)
7
- end
8
- end
9
-
10
- class Flexi
11
- def to_json(*a)
12
- JSON.neat_generate({a:1},*a)
13
- end
14
- end
15
-
16
- class TestFlexiJSON < Minitest::Unit::TestCase
17
- def test_booleans
18
- assert_equal "true", JSON.neat_generate(true)
19
- assert_equal "false", JSON.neat_generate(false)
20
- assert_equal "null", JSON.neat_generate(nil)
21
- end
22
-
23
- def test_numbers
24
- assert_equal "5", JSON.neat_generate(5)
25
- assert_equal "4.2", JSON.neat_generate(4.2)
26
- assert_equal "4.20", JSON.neat_generate(4.2, decimals:2)
27
- assert_equal "4.20", JSON.neat_generate(4.199,decimals:2)
28
- assert_equal "4.20", JSON.neat_generate(4.204,decimals:2)
29
-
30
- assert_equal "4", JSON.neat_generate(4.2, decimals:0)
31
- assert_equal "5", JSON.neat_generate(4.9, decimals:0)
32
- assert_equal "-2", JSON.neat_generate(-1.9,decimals:0)
33
- assert_equal "-2", JSON.neat_generate(-2.4,decimals:0)
34
-
35
- assert_equal "1.0e+23", JSON.neat_generate(1e23)
36
- assert_equal "1.0e-09", JSON.neat_generate(1e-9)
37
- end
38
-
39
- def test_strings
40
- assert_equal '"foo"', JSON.neat_generate('foo')
41
- assert_equal '"foo"', JSON.neat_generate(:foo)
42
- assert_equal '"foo\nbar"', JSON.neat_generate("foo\nbar")
43
- end
44
-
45
- def test_arrays
46
- @a1 = [1,2,3,4,[5,6,7,[8,9,10],11,12]]
47
- assert_equal "[1,2,3,4,[5,6,7,[8,9,10],11,12]]", JSON.neat_generate(@a1)
48
- assert_equal "[\n 1,\n 2,\n 3,\n 4,\n [5,6,7,[8,9,10],11,12]\n]", JSON.neat_generate(@a1,wrap:30)
49
- assert_equal "[\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]", JSON.neat_generate(@a1,wrap:20)
50
- assert_equal "[\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]", JSON.neat_generate(@a1,wrap:true)
51
- assert_equal "[\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]", JSON.neat_generate(@a1,wrap:true,indent:"\t")
52
- assert_equal "[1,2,3,4,[5,6,7,[8,9,10],11,12]]", JSON.neat_generate(@a1,array_padding:0)
53
- assert_equal "[ 1,2,3,4,[ 5,6,7,[ 8,9,10 ],11,12 ] ]", JSON.neat_generate(@a1,array_padding:1)
54
- assert_equal "[ 1,2,3,4,[ 5,6,7,[ 8,9,10 ],11,12 ] ]", JSON.neat_generate(@a1,array_padding:2)
55
- assert_equal "[1, 2, 3, 4, [5, 6, 7, [8, 9, 10], 11, 12]]", JSON.neat_generate(@a1,after_comma:1)
56
- assert_equal "[ 1, 2, 3, 4, [ 5, 6, 7, [ 8, 9, 10 ], 11, 12 ] ]", JSON.neat_generate(@a1,after_comma:1,array_padding:1)
57
- assert_equal "[1,\n 2,\n 3,\n 4,\n [5,\n 6,\n 7,\n [8,\n 9,\n 10],\n 11,\n 12]]", JSON.neat_generate(@a1,short:true,wrap:true)
58
- assert_equal "[1,\n 2,\n 3,\n 4,\n [5,\n 6,\n 7,\n [8,\n 9,\n 10],\n 11,\n 12]]", JSON.neat_generate(@a1,short:true,wrap:true,after_comma:1)
59
- assert_equal "[ 1,\n 2,\n 3,\n 4,\n [ 5,\n 6,\n 7,\n [ 8,\n 9,\n 10 ],\n 11,\n 12 ] ]", JSON.neat_generate(@a1,short:true,wrap:true,array_padding:1)
60
-
61
- @a2 = [1,2,3]
62
- assert_equal "[1,2,3]", JSON.neat_generate(@a2)
63
- assert_equal "[1 ,2 ,3]", JSON.neat_generate(@a2,before_comma:1)
64
- assert_equal "[1 , 2 , 3]", JSON.neat_generate(@a2,around_comma:1)
65
- end
66
-
67
- def test_hashes
68
- @h1 = {b:1,a:2}
69
- assert_equal '{"b":1,"a":2}', JSON.neat_generate(@h1)
70
- assert_equal '{"a":2,"b":1}', JSON.neat_generate(@h1,sorted:true)
71
-
72
- assert_equal '{"a":2, "b":1}', JSON.neat_generate(@h1,sorted:true,after_comma:1)
73
- assert_equal '{"a" :2,"b" :1}', JSON.neat_generate(@h1,sorted:true,before_colon:1)
74
- assert_equal '{"a": 2,"b": 1}', JSON.neat_generate(@h1,sorted:true,after_colon:1)
75
- assert_equal '{"a" : 2,"b" : 1}', JSON.neat_generate(@h1,sorted:true,before_colon:1,after_colon:1)
76
- assert_equal '{"a" : 2, "b" : 1}', JSON.neat_generate(@h1,sorted:true,before_colon:1,after_colon:1,after_comma:1)
77
- assert_equal '{ "a" : 2, "b" : 1 }', JSON.neat_generate(@h1,sorted:true,before_colon:1,after_colon:1,after_comma:1,padding:1)
78
- assert_equal '{ "a" : 2, "b" : 1 }', JSON.neat_generate(@h1,sorted:true,around_colon:1,after_comma:1,object_padding:1)
79
- assert_equal '{"a" : 2, "b" : 1}', JSON.neat_generate(@h1,sorted:true,before_colon:1,after_colon:1,after_comma:1,array_padding:1)
80
- assert_equal '{ "a" : 2, "b" : 1 }', JSON.neat_generate(@h1,sorted:true,around_colon:2,after_comma:1,padding:2)
81
- assert_equal '{ "a":2, "b":1 }', JSON.neat_generate(@h1,sorted:true,after_comma:1,padding:2)
82
-
83
- @h2 = {b:1,aaa:2,cc:3}
84
- assert_equal %Q{{\n "b":1,\n "aaa":2,\n "cc":3\n}}, JSON.neat_generate(@h2,wrap:true)
85
- assert_equal %Q{{\n "b" :1,\n "aaa":2,\n "cc" :3\n}}, JSON.neat_generate(@h2,wrap:true,aligned:true)
86
- assert_equal %Q{{"b":1,"aaa":2,"cc":3}}, JSON.neat_generate(@h2,aligned:true)
87
- assert_equal %Q{{\n "aaa":2,\n "b" :1,\n "cc" :3\n}}, JSON.neat_generate(@h2,wrap:true,aligned:true,sorted:true)
88
-
89
- @h3 = {a:1}
90
- assert_equal '{"a":1}', JSON.neat_generate(@h3)
91
- assert_equal "{\n \"a\":1\n}", JSON.neat_generate(@h3,wrap:true)
92
-
93
- @h4 = { b:17, a:42 }
94
- assert_equal "{\"a\":42,\n \"b\":17}", JSON.neat_generate(@h4,wrap:10,sorted:true,short:true)
95
- end
96
-
97
- def test_mixed
98
- a = [1,{a:2},3]
99
- assert_equal '[1,{"a":2},3]', JSON.neat_generate(a)
100
- assert_equal '[ 1,{ "a":2 },3 ]', JSON.neat_generate(a,padding:1)
101
- assert_equal '[ 1, { "a":2 }, 3 ]', JSON.neat_generate(a,padding:1,after_comma:1)
102
- assert_equal %Q{[\n 1,\n {\n "a":2\n },\n 3\n]}, JSON.neat_generate(a,wrap:true)
103
- assert_equal %Q{[\n 1,\n {"a":2},\n 3\n]}, JSON.neat_generate(a,wrap:10)
104
-
105
- a = [1,{a:2,b:3},4]
106
- assert_equal "[1,\n {\"a\":2,\n \"b\":3},\n 4]", JSON.neat_generate(a,wrap:0,short:true)
107
-
108
- h = {a:1,b:[2,3,4],c:3}
109
- assert_equal '{"a":1,"b":[2,3,4],"c":3}', JSON.neat_generate(h)
110
- assert_equal %Q{{\n "a":1,\n "b":[2,3,4],\n "c":3\n}}, JSON.neat_generate(h,wrap:10)
111
- assert_equal %Q{{\n "a":1,\n "b":[\n 2,\n 3,\n 4\n ],\n "c":3\n}}, JSON.neat_generate(h,wrap:true)
112
-
113
- h = {hooo:42,whee:%w[yaaa oooo booy],zoop:"whoop"}
114
- assert_equal <<-ENDFORMAT.chomp, JSON.neat_generate(h,wrap:20,short:true)
115
- {"hooo":42,
116
- "whee":["yaaa",
117
- "oooo",
118
- "booy"],
119
- "zoop":"whoop"}
120
- ENDFORMAT
121
-
122
- h = { a:[ {x:"foo",y:"jim"}, {x:"bar",y:"jam"} ] }
123
- assert_equal <<-ENDFORMAT.chomp, JSON.neat_generate(h,wrap:true,short:true)
124
- {"a":[{"x":"foo",
125
- "y":"jim"},
126
- {"x":"bar",
127
- "y":"jam"}]}
128
- ENDFORMAT
129
- end
130
-
131
- def test_custom
132
- assert_equal '{ "a":1}', JSON.neat_generate(Dummy.new)
133
- assert_equal '{ "a":1}', JSON.neat_generate(Dummy.new,wrap:true)
134
- assert_equal '{"a":1}', JSON.neat_generate(Dummy.new,indent:'')
135
- assert_equal '{"a":1}', JSON.neat_generate(Flexi.new)
136
- assert_equal "{\n \"a\":1\n}", JSON.neat_generate(Flexi.new,wrap:true)
137
- end
138
- end
2
+ require './tests'
3
+
4
+ TESTS.each do |value_tests|
5
+ val, tests = value_tests[:value], value_tests[:tests]
6
+ tests.each do |test|
7
+ begin
8
+ json = test[:opts] ? JSON.neat_generate(val,test[:opts].dup) : JSON.neat_generate(val)
9
+ mesg = test[:opts] ? "JSON.neat_generate(#{val.inspect},#{test[:opts].inspect})" : "JSON.neat_generate(#{val.inspect})"
10
+ raise "#{mesg}\nEXPECTED:\n#{test[:json]}\nACTUAL:\n#{json}\n\n" unless test[:json]===json
11
+ rescue StandardError => e
12
+ puts e
13
+ end
14
+ end
15
+ end
data/test/tests.js ADDED
@@ -0,0 +1,126 @@
1
+ exports.tests = [
2
+ {value:true, tests:[{json:"true" }]},
3
+ {value:false, tests:[{json:"false" }]},
4
+ // {value:nil, tests:[{json:"null" }]},
5
+ {value:null, tests:[{json:"null" }]},
6
+ {value:undefined,tests:[{json:"null" }]},
7
+ {value:5, tests:[
8
+ {json:"5"},
9
+ {json:"5", opts:{decimals:3}}
10
+ ]},
11
+ {value:5.0, tests:[
12
+ {json:"5"},
13
+ {json:"5", opts:{decimals:3}}
14
+ ]},
15
+ {value:5.0001, tests:[
16
+ {json:"5.0001"},
17
+ {json:"5.000", opts:{decimals:3}}
18
+ ]},
19
+ {value:4.2, tests:[
20
+ {json:"4.2"},
21
+ {json:"4", opts:{decimals:0}},
22
+ {json:"4.20",opts:{decimals:2}},
23
+ ]},
24
+ {value:4.199, tests:[{json:"4.20", opts:{decimals:2}}]},
25
+ {value:4.204, tests:[{json:"4.20", opts:{decimals:2}}]},
26
+ {value:-1.9, tests:[{json:"-2", opts:{decimals:0}}]},
27
+ {value:-2.4, tests:[{json:"-2", opts:{decimals:0}}]},
28
+ {value:1e23, tests:[{json:/1(?:\.0+)?e\+23/i}]},
29
+ {value:1e-9, tests:[{json:/1(?:\.0+)?e-0*9/i}]},
30
+ {value:-2.4, tests:[{json:"-2", opts:{decimals:0}}]},
31
+
32
+ {value:"foo", tests:[{json:"\"foo\""}]},
33
+ // {value: :foo, tests:[{json:"\"foo\""}]},
34
+ {value:"foo\nbar", tests:[{json:"\"foo\\nbar\""}]},
35
+
36
+ {value:[1,2,3,4,[5,6,7,[8,9,10],11,12]], tests:[
37
+ { json:"[1,2,3,4,[5,6,7,[8,9,10],11,12]]" },
38
+ { json:"[\n 1,\n 2,\n 3,\n 4,\n [5,6,7,[8,9,10],11,12]\n]", opts:{wrap:30} },
39
+ { 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} },
40
+ { 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} },
41
+ { 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"} },
42
+ { json:"[1,2,3,4,[5,6,7,[8,9,10],11,12]]", opts:{arrayPadding:0} },
43
+ { json:"[ 1,2,3,4,[ 5,6,7,[ 8,9,10 ],11,12 ] ]", opts:{arrayPadding:1} },
44
+ { json:"[ 1,2,3,4,[ 5,6,7,[ 8,9,10 ],11,12 ] ]", opts:{arrayPadding:2} },
45
+ { json:"[1, 2, 3, 4, [5, 6, 7, [8, 9, 10], 11, 12]]", opts:{afterComma:1} },
46
+ { json:"[ 1, 2, 3, 4, [ 5, 6, 7, [ 8, 9, 10 ], 11, 12 ] ]", opts:{afterComma:1,arrayPadding:1} },
47
+ { 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} },
48
+ { 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} },
49
+ { 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} },
50
+ ]},
51
+
52
+ {value:[1,2,3], tests:[
53
+ { json:"[1,2,3]" },
54
+ { json:"[1 ,2 ,3]", opts:{beforeComma:1} },
55
+ { json:"[1 , 2 , 3]", opts:{aroundComma:1} }
56
+ ]},
57
+
58
+ {value:{b:1,a:2}, tests:[
59
+ { json:'{"b":1,"a":2}' },
60
+ { json:'{"a":2,"b":1}', opts:{sorted:true} },
61
+ { json:'{"a":2, "b":1}', opts:{sorted:true,afterComma:1} },
62
+ { json:'{"a" :2,"b" :1}', opts:{sorted:true,beforeColon:1} },
63
+ { json:'{"a": 2,"b": 1}', opts:{sorted:true,afterColon:1} },
64
+ { json:'{"a" : 2,"b" : 1}', opts:{sorted:true,beforeColon:1,afterColon:1} },
65
+ { json:'{"a" : 2, "b" : 1}', opts:{sorted:true,beforeColon:1,afterColon:1,afterComma:1} },
66
+ { json:'{ "a" : 2, "b" : 1 }', opts:{sorted:true,beforeColon:1,afterColon:1,afterComma:1,padding:1} },
67
+ { json:'{ "a" : 2, "b" : 1 }', opts:{sorted:true,aroundColon:1,afterComma:1,objectPadding:1} },
68
+ { json:'{"a" : 2, "b" : 1}', opts:{sorted:true,beforeColon:1,afterColon:1,afterComma:1,arrayPadding:1} },
69
+ { json:'{ "a" : 2, "b" : 1 }', opts:{sorted:true,aroundColon:2,afterComma:1,padding:2} },
70
+ { json:'{ "a":2, "b":1 }', opts:{sorted:true,afterComma:1,padding:2} }
71
+ ]},
72
+
73
+ {value:{b:1,aaa:2,cc:3}, tests:[
74
+ { json:"{\n \"b\":1,\n \"aaa\":2,\n \"cc\":3\n}", opts:{wrap:true} },
75
+ { json:"{\n \"b\" :1,\n \"aaa\":2,\n \"cc\" :3\n}", opts:{wrap:true,aligned:true} },
76
+ { json:"{\"b\":1,\"aaa\":2,\"cc\":3}", opts:{aligned:true} },
77
+ { json:"{\n \"aaa\":2,\n \"b\" :1,\n \"cc\" :3\n}", opts:{wrap:true,aligned:true,sorted:true} }
78
+ ]},
79
+
80
+ {value:{a:1}, tests:[
81
+ { json:'{"a":1}' },
82
+ { json:"{\n \"a\":1\n}", opts:{wrap:true} }
83
+ ]},
84
+
85
+ {value:{ b:17, a:42 }, tests:[
86
+ { json:"{\"a\":42,\n \"b\":17}", opts:{wrap:10,sorted:true,short:true} }
87
+ ]},
88
+
89
+ {value:[1,{a:2},3], tests:[
90
+ { json:'[1,{"a":2},3]' },
91
+ { json:'[ 1,{ "a":2 },3 ]', opts:{padding:1} },
92
+ { json:'[ 1, { "a":2 }, 3 ]', opts:{padding:1,afterComma:1} },
93
+ { json:"[\n 1,\n {\n \"a\":2\n },\n 3\n]", opts:{wrap:true} },
94
+ { json:"[\n 1,\n {\"a\":2},\n 3\n]", opts:{wrap:10} }
95
+ ]},
96
+
97
+ {value:[1,{a:2,b:3},4], tests:[
98
+ { json:"[1,\n {\"a\":2,\n \"b\":3},\n 4]", opts:{wrap:0,short:true} },
99
+ ]},
100
+
101
+ {value:{a:1,b:[2,3,4],c:3}, tests:[
102
+ { json:'{"a":1,"b":[2,3,4],"c":3}' },
103
+ { json:"{\n \"a\":1,\n \"b\":[2,3,4],\n \"c\":3\n}", opts:{wrap:10} },
104
+ { json:"{\n \"a\":1,\n \"b\":[\n 2,\n 3,\n 4\n ],\n \"c\":3\n}", opts:{wrap:true} }
105
+ ]},
106
+
107
+ {value:{hooo:42,whee:['yaaa','oooo','booy'],zoop:"whoop"}, tests:[
108
+ { json:"{\"hooo\":42,\n \"whee\":[\"yaaa\",\n \"oooo\",\n \"booy\"],\n \"zoop\":\"whoop\"}", opts:{wrap:20,short:true} }
109
+ ]},
110
+
111
+ {value:{ a:[ {x:"foo",y:"jim"}, {x:"bar",y:"jam"} ] }, tests:[
112
+ { json:"{\"a\":[{\"x\":\"foo\",\n \"y\":\"jim\"},\n {\"x\":\"bar\",\n \"y\":\"jam\"}]}", opts:{wrap:true,short:true} }
113
+ ]},
114
+
115
+ // {value:Class.new{ def to_json(*a); {a:1}.to_json(*a); end }.new, tests:[
116
+ // { json:'{ "a":1}' },
117
+ // { json:'{ "a":1}', opts:{wrap:true} },
118
+ // { json:'{"a":1}', opts:{indent:''} },
119
+ // ]},
120
+
121
+ // {value:Class.new{ def to_json(*a); JSON.neat_generate({a:1},*a); end }.new, tests:[
122
+ // { json:'{"a":1}' },
123
+ // { json:"{\n \"a\":1\n}", opts:{wrap:true} }
124
+ // ]}
125
+ ]
126
+
data/test/tests.rb ADDED
@@ -0,0 +1,124 @@
1
+ TESTS = [
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:{decimals:3}}
12
+ ]},
13
+ {value:5.0001, tests:[
14
+ {json:"5.0001"},
15
+ {json:"5.000", opts:{decimals:3}}
16
+ ]},
17
+ {value:4.2, tests:[
18
+ {json:"4.2"},
19
+ {json:"4", opts:{decimals:0}},
20
+ {json:"4.20",opts:{decimals:2}},
21
+ ]},
22
+ {value:4.199, tests:[{json:"4.20", opts:{decimals:2}}]},
23
+ {value:4.204, tests:[{json:"4.20", opts:{decimals:2}}]},
24
+ {value:-1.9, tests:[{json:"-2", opts:{decimals:0}}]},
25
+ {value:-2.4, tests:[{json:"-2", opts:{decimals:0}}]},
26
+ {value:1e23, tests:[{json:/1(?:\.0+)?e\+23/i}]},
27
+ {value:1e-9, tests:[{json:/1(?:\.0+)?e-0*9/i}]},
28
+ {value:-2.4, tests:[{json:"-2", opts:{decimals:0}}]},
29
+
30
+ {value:"foo", tests:[{json:"\"foo\""}]},
31
+ {value: :foo, tests:[{json:"\"foo\""}]},
32
+ {value:"foo\nbar", tests:[{json:"\"foo\\nbar\""}]},
33
+
34
+ {value:[1,2,3,4,[5,6,7,[8,9,10],11,12]], tests:[
35
+ { json:"[1,2,3,4,[5,6,7,[8,9,10],11,12]]" },
36
+ { json:"[\n 1,\n 2,\n 3,\n 4,\n [5,6,7,[8,9,10],11,12]\n]", opts:{wrap:30} },
37
+ { 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} },
38
+ { 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} },
39
+ { 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"} },
40
+ { json:"[1,2,3,4,[5,6,7,[8,9,10],11,12]]", opts:{array_padding:0} },
41
+ { json:"[ 1,2,3,4,[ 5,6,7,[ 8,9,10 ],11,12 ] ]", opts:{array_padding:1} },
42
+ { json:"[ 1,2,3,4,[ 5,6,7,[ 8,9,10 ],11,12 ] ]", opts:{array_padding:2} },
43
+ { json:"[1, 2, 3, 4, [5, 6, 7, [8, 9, 10], 11, 12]]", opts:{after_comma:1} },
44
+ { json:"[ 1, 2, 3, 4, [ 5, 6, 7, [ 8, 9, 10 ], 11, 12 ] ]", opts:{after_comma:1,array_padding:1} },
45
+ { 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} },
46
+ { 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,after_comma:1} },
47
+ { 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,array_padding:1} },
48
+ ]},
49
+
50
+ {value:[1,2,3], tests:[
51
+ { json:"[1,2,3]" },
52
+ { json:"[1 ,2 ,3]", opts:{before_comma:1} },
53
+ { json:"[1 , 2 , 3]", opts:{around_comma:1} }
54
+ ]},
55
+
56
+ {value:{b:1,a:2}, tests:[
57
+ { json:'{"b":1,"a":2}' },
58
+ { json:'{"a":2,"b":1}', opts:{sorted:true} },
59
+ { json:'{"a":2, "b":1}', opts:{sorted:true,after_comma:1} },
60
+ { json:'{"a" :2,"b" :1}', opts:{sorted:true,before_colon:1} },
61
+ { json:'{"a": 2,"b": 1}', opts:{sorted:true,after_colon:1} },
62
+ { json:'{"a" : 2,"b" : 1}', opts:{sorted:true,before_colon:1,after_colon:1} },
63
+ { json:'{"a" : 2, "b" : 1}', opts:{sorted:true,before_colon:1,after_colon:1,after_comma:1} },
64
+ { json:'{ "a" : 2, "b" : 1 }', opts:{sorted:true,before_colon:1,after_colon:1,after_comma:1,padding:1} },
65
+ { json:'{ "a" : 2, "b" : 1 }', opts:{sorted:true,around_colon:1,after_comma:1,object_padding:1} },
66
+ { json:'{"a" : 2, "b" : 1}', opts:{sorted:true,before_colon:1,after_colon:1,after_comma:1,array_padding:1} },
67
+ { json:'{ "a" : 2, "b" : 1 }', opts:{sorted:true,around_colon:2,after_comma:1,padding:2} },
68
+ { json:'{ "a":2, "b":1 }', opts:{sorted:true,after_comma:1,padding:2} }
69
+ ]},
70
+
71
+ {value:{b:1,aaa:2,cc:3}, tests:[
72
+ { json:"{\n \"b\":1,\n \"aaa\":2,\n \"cc\":3\n}", opts:{wrap:true} },
73
+ { json:"{\n \"b\" :1,\n \"aaa\":2,\n \"cc\" :3\n}", opts:{wrap:true,aligned:true} },
74
+ { json:"{\"b\":1,\"aaa\":2,\"cc\":3}", opts:{aligned:true} },
75
+ { json:"{\n \"aaa\":2,\n \"b\" :1,\n \"cc\" :3\n}", opts:{wrap:true,aligned:true,sorted:true} }
76
+ ]},
77
+
78
+ {value:{a:1}, tests:[
79
+ { json:'{"a":1}' },
80
+ { json:"{\n \"a\":1\n}", opts:{wrap:true} }
81
+ ]},
82
+
83
+ {value:{ b:17, a:42 }, tests:[
84
+ { json:"{\"a\":42,\n \"b\":17}", opts:{wrap:10,sorted:true,short:true} }
85
+ ]},
86
+
87
+ {value:[1,{a:2},3], tests:[
88
+ { json:'[1,{"a":2},3]' },
89
+ { json:'[ 1,{ "a":2 },3 ]', opts:{padding:1} },
90
+ { json:'[ 1, { "a":2 }, 3 ]', opts:{padding:1,after_comma:1} },
91
+ { json:"[\n 1,\n {\n \"a\":2\n },\n 3\n]", opts:{wrap:true} },
92
+ { json:"[\n 1,\n {\"a\":2},\n 3\n]", opts:{wrap:10} }
93
+ ]},
94
+
95
+ {value:[1,{a:2,b:3},4], tests:[
96
+ { json:"[1,\n {\"a\":2,\n \"b\":3},\n 4]", opts:{wrap:0,short:true} },
97
+ ]},
98
+
99
+ {value:{a:1,b:[2,3,4],c:3}, tests:[
100
+ { json:'{"a":1,"b":[2,3,4],"c":3}' },
101
+ { json:"{\n \"a\":1,\n \"b\":[2,3,4],\n \"c\":3\n}", opts:{wrap:10} },
102
+ { json:"{\n \"a\":1,\n \"b\":[\n 2,\n 3,\n 4\n ],\n \"c\":3\n}", opts:{wrap:true} }
103
+ ]},
104
+
105
+ {value:{hooo:42,whee:['yaaa','oooo','booy'],zoop:"whoop"}, tests:[
106
+ { json:"{\"hooo\":42,\n \"whee\":[\"yaaa\",\n \"oooo\",\n \"booy\"],\n \"zoop\":\"whoop\"}", opts:{wrap:20,short:true} }
107
+ ]},
108
+
109
+ {value:{ a:[ {x:"foo",y:"jim"}, {x:"bar",y:"jam"} ] }, tests:[
110
+ { json:"{\"a\":[{\"x\":\"foo\",\n \"y\":\"jim\"},\n {\"x\":\"bar\",\n \"y\":\"jam\"}]}", opts:{wrap:true,short:true} }
111
+ ]},
112
+
113
+ {value:Class.new{ def to_json(*a); {a:1}.to_json(*a); end }.new, tests:[
114
+ { json:'{ "a":1}' },
115
+ { json:'{ "a":1}', opts:{wrap:true} },
116
+ { json:'{"a":1}', opts:{indent:''} },
117
+ ]},
118
+
119
+ {value:Class.new{ def to_json(*a); JSON.neat_generate({a:1},*a); end }.new, tests:[
120
+ { json:'{"a":1}' },
121
+ { json:"{\n \"a\":1\n}", opts:{wrap:true} }
122
+ ]}
123
+ ]
124
+
metadata CHANGED
@@ -1,18 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: neatjson
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.4'
4
+ version: '0.5'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gavin Kistner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-18 00:00:00.000000000 Z
11
+ date: 2015-04-19 00:00:00.000000000 Z
12
12
  dependencies: []
13
- description: Generate JSON strings from Ruby objects with flexible formatting options.
14
- The most important feature is that it can behave like pp, keeping arrays and objects
15
- on a single line when they fit.
13
+ description: 'Generate JSON strings from Ruby objects with flexible formatting options.
14
+ Key features: keep arrays and objects on a single line when they fit; format floats
15
+ to specific precision; sort and align object keys; adjust whitespace padding of
16
+ arrays and objects, inside and around commas and colons. JavaScript version included.'
16
17
  email: gavin@phrogz.net
17
18
  executables: []
18
19
  extensions: []
@@ -21,11 +22,12 @@ files:
21
22
  - ".yardopts"
22
23
  - LICENSE.txt
23
24
  - README.md
24
- - html/neatjson.html
25
- - html/neatjson.js
26
25
  - lib/neatjson.rb
27
26
  - neatjson.gemspec
27
+ - test/test_neatjson.js
28
28
  - test/test_neatjson.rb
29
+ - test/tests.js
30
+ - test/tests.rb
29
31
  homepage: http://github.com/Phrogz/NeatJSON
30
32
  licenses:
31
33
  - MIT license (MIT)
data/html/neatjson.html DELETED
@@ -1,151 +0,0 @@
1
- <!DOCTYPE html>
2
- <html><head>
3
- <meta charset="utf-8">
4
- <title>NeatJSON Online</title>
5
- <style type="text/css">
6
- h1 { background:#444; color:#ccc; text-align:center; margin:0; padding:0.2em 0; margin-bottom:1em; }
7
- html, body { height:100%; min-height:100%; padding:0; margin:0; background:#eee; }
8
- #input, #output, #code { display:block; width:90%; margin:1em auto; height:35%; background:#fff; }
9
- #code { height:1em; background:none; }
10
- #output { border:1px solid green; background:rgba(100,255,0,0.5); color:#080 }
11
- label { padding-right:0.6em }
12
- #options { width:90%; margin:1em auto }
13
- .option { display:inline-block; margin-right:2em; user-select:none; -webkit-user-select:none; }
14
- input[type="range"] { width:5em }
15
- b { background:yellow }
16
- </style>
17
- </head><body>
18
- <h1>NeatJSON Online v0.4</h1>
19
- <div id="options">
20
- <div class="option-row">
21
- <span class="option">
22
- <label><input type="checkbox" id="wrap" checked> Wrap?</label>
23
- <label id="wrapopts1">width <input type="text" id="wrapSize" value="40" size="3"></label>
24
- <label id="wrapopts2"><input type="checkbox" id="short"> Short?</label>
25
- <label id="wrapopts3"><input type="checkbox" id="aligned"> Align Keys?</label>
26
- </span>
27
- <span class="option"><label><input type="checkbox" id="sorted"> Sort Keys?</label></span>
28
- <span class="option">
29
- <label><input type="checkbox" id="useDecimals"> Format Decimals?</label>
30
- <input type="text" id="decimals" value="3" size="3" min="0" max="10" style="visibility:hidden">
31
- </span>
32
- </div><div class="option-row">
33
- <span class="option"><label>Indent Spaces <input type="range" id="indent" value="2" min="0" max="5" step="1"></label></span>
34
- <span class="option"><label>Array Padding<input type="range" id="arrayPadding" value="0" min="0" max="3" step="1"></label></span>
35
- <span class="option"><label>Object Padding<input type="range" id="objectPadding" value="0" min="0" max="3" step="1"></label></span>
36
- </div><div class="option-row">
37
- <span class="option"><label>Before Comma<input type="range" id="beforeComma" value="0" min="0" max="3" step="1"></label></span>
38
- <span class="option"><label>After Comma<input type="range" id="afterComma" value="0" min="0" max="3" step="1"></label></span>
39
- <span class="option"><label>Before Colon<input type="range" id="beforeColon" value="0" min="0" max="3" step="1"></label></span>
40
- <span class="option"><label>After Colon<input type="range" id="afterColon" value="0" min="0" max="3" step="1"></label></span>
41
- </div>
42
- </div>
43
-
44
- <textarea id="input">["foo","bar",{"dogs":42,"piggies":0,"cats":7},{"jimmy":[1,2,3,4,5],"jammy":3.14159265358979,"hot":"pajammy"}]</textarea>
45
- <pre id="code"></pre>
46
- <pre id="output"></pre>
47
- <script type="text/javascript" src="neatjson.js"></script>
48
- <script type="text/javascript">
49
- var opts = document.querySelectorAll('input');
50
- [].forEach.call(opts,function(opt){
51
- opt.addEventListener('input',neaten,false);
52
- opt.addEventListener('change',neaten,false);
53
- opt.addEventListener('click',neaten,false);
54
- })
55
-
56
- var inp = document.querySelector('#input'),
57
- cde = document.querySelector('#code'),
58
- out = document.querySelector('#output');
59
- var opts;
60
-
61
- var wrap = document.querySelector('#wrap'),
62
- wdth = document.querySelector('#wrapSize'),
63
- shrt = document.querySelector('#short'),
64
- dec0 = document.querySelector('#useDecimals'),
65
- decN = document.querySelector('#decimals'),
66
- sort = document.querySelector('#sorted'),
67
- algn = document.querySelector('#aligned'),
68
- indN = document.querySelector('#indent'),
69
- arrayPadding = document.querySelector('#arrayPadding'),
70
- objectPadding = document.querySelector('#objectPadding'),
71
- beforeComma = document.querySelector('#beforeComma'),
72
- afterComma = document.querySelector('#afterComma'),
73
- beforeColon = document.querySelector('#beforeColon'),
74
- afterColon = document.querySelector('#afterColon');
75
-
76
- window.onload = neaten;
77
- inp.addEventListener('input',neaten,false);
78
-
79
- function neaten(){
80
- try{
81
- changeOptions();
82
- if (isEmpty(opts)){
83
- code.innerHTML = "var json = neatJSON(obj);";
84
- }else{
85
- var parts=[];
86
- for (var k in opts) parts.push('<b>'+k+'</b>:'+JSON.stringify(opts[k]));
87
- code.innerHTML = "var json = neatJSON(obj,{ "+parts.join(', ')+" });";
88
- }
89
- out.innerHTML = neatJSON(JSON.parse(inp.value),opts);
90
- }catch(e){
91
- out.innerHTML = e;
92
- }
93
- }
94
-
95
- function changeOptions() {
96
- opts = {};
97
- if (!wrap.checked || wdth.value!=80) opts.wrap = wrap.checked ? (wdth.value=='' ? true : wdth.value*1) : false;
98
- if (wrap.checked && shrt.checked) opts.short = true;
99
- document.querySelector('#wrapopts1').style.visibility = wrap.checked ? '' : 'hidden';
100
- document.querySelector('#wrapopts2').style.visibility = wrap.checked ? '' : 'hidden';
101
- document.querySelector('#wrapopts3').style.visibility = wrap.checked ? '' : 'hidden';
102
-
103
- if (indN.value!=2 && (wrap.checked && !shrt.checked)) opts.indent = repeat(' ',indN.value*1);
104
-
105
- if (dec0.checked){
106
- opts.decimals = decN.value*1;
107
- decN.style.visibility = '';
108
- }else{
109
- decN.style.visibility = 'hidden';
110
- }
111
-
112
- if (sort.checked) opts.sorted = true;
113
- if (wrap.checked && algn.checked) opts.aligned = true;
114
-
115
- if (arrayPadding.value!=0 && objectPadding.value==arrayPadding.value){
116
- opts.padding = arrayPadding.value*1;
117
- }else{
118
- if (arrayPadding.value!=0) opts.arrayPadding = arrayPadding.value*1;
119
- if (objectPadding.value!=0) opts.objectPadding = objectPadding.value*1;
120
- }
121
- if (beforeComma.value!=0 && beforeComma.value==afterComma.value){
122
- opts.aroundComma = beforeComma.value*1;
123
- }else{
124
- if (beforeComma.value!=0) opts.beforeComma = beforeComma.value*1;
125
- if (afterComma.value!=0) opts.afterComma = afterComma.value*1;
126
- }
127
- if (beforeColon.value!=0 && beforeColon.value==afterColon.value){
128
- opts.aroundColon = beforeColon.value*1;
129
- }else{
130
- if (beforeColon.value!=0) opts.beforeColon = beforeColon.value*1;
131
- if (afterColon.value!=0) opts.afterColon = afterColon.value*1;
132
- }
133
- }
134
-
135
- function repeat(str,times){ // http://stackoverflow.com/a/17800645/405017
136
- var result = '';
137
- while(true){
138
- if (times & 1) result += str;
139
- times >>= 1;
140
- if (times) str += str;
141
- else break;
142
- }
143
- return result;
144
- }
145
-
146
- function isEmpty(obj){
147
- for (var k in obj) return false;
148
- return true;
149
- }
150
- </script>
151
- </body></html>
data/html/neatjson.js DELETED
@@ -1,106 +0,0 @@
1
- function neatJSON(value,opts){
2
- opts = opts || {}
3
- if (!('wrap' in opts)) opts.wrap = 80;
4
- if (opts.wrap==true) opts.wrap = -1;
5
- if (!('indent' in opts)) opts.indent = ' ';
6
- if (!('arrayPadding' in opts)) opts.arrayPadding = ('padding' in opts) ? opts.padding : 0;
7
- if (!('objectPadding' in opts)) opts.objectPadding = ('padding' in opts) ? opts.padding : 0;
8
- if (!('afterComma' in opts)) opts.afterComma = ('aroundComma' in opts) ? opts.aroundComma : 0;
9
- if (!('beforeComma' in opts)) opts.beforeComma = ('aroundComma' in opts) ? opts.aroundComma : 0;
10
- if (!('afterColon' in opts)) opts.afterColon = ('aroundColon' in opts) ? opts.aroundColon : 0;
11
- if (!('beforeColon' in opts)) opts.beforeColon = ('aroundColon' in opts) ? opts.aroundColon : 0;
12
-
13
- var apad = repeat(' ',opts.arrayPadding),
14
- opad = repeat(' ',opts.objectPadding),
15
- comma = repeat(' ',opts.beforeComma)+','+repeat(' ',opts.afterComma),
16
- colon = repeat(' ',opts.beforeColon)+':'+repeat(' ',opts.afterColon);
17
-
18
- return build(value,'');
19
-
20
- function build(o,indent){
21
- if (o===null || o===undefined) return indent+'null';
22
- else{
23
- switch(o.constructor){
24
- case Number:
25
- return indent + (('decimals' in opts) ? o.toFixed(opts.decimals) : (o+''));
26
-
27
- case Array:
28
- var pieces = o.map(function(v){ return build(v,'') });
29
- var oneLine = indent+'['+apad+pieces.join(comma)+apad+']';
30
- if (opts.wrap===false || oneLine.length<=opts.wrap) return oneLine;
31
- if (opts.short){
32
- var indent2 = indent+' '+apad;
33
- pieces = o.map(function(v){ return build(v,indent2) });
34
- pieces[0] = pieces[0].replace(indent2,indent+'['+apad);
35
- pieces[pieces.length-1] = pieces[pieces.length-1]+apad+']';
36
- return pieces.join(',\n');
37
- }else{
38
- var indent2 = indent+opts.indent;
39
- return indent+'[\n'+o.map(function(v){ return build(v,indent2) }).join(',\n')+'\n'+indent+']';
40
- }
41
-
42
- case Object:
43
- var keyvals=[],i=0;
44
- for (var k in o) keyvals[i++] = [JSON.stringify(k), build(o[k],'')];
45
- if (opts.sorted) keyvals = keyvals.sort(function(kv1,kv2){ kv1=kv1[0]; kv2=kv2[0]; return kv1<kv2?-1:kv1>kv2?1:0 });
46
- keyvals = keyvals.map(function(kv){ return kv.join(colon) }).join(comma);
47
- var oneLine = indent+"{"+opad+keyvals+opad+"}";
48
- if (opts.wrap===false || oneLine.length<opts.wrap) return oneLine;
49
- if (opts.short){
50
- var keyvals=[],i=0;
51
- for (var k in o) keyvals[i++] = [indent+' '+opad+JSON.stringify(k),o[k]];
52
- if (opts.sorted) keyvals = keyvals.sort(function(kv1,kv2){ kv1=kv1[0]; kv2=kv2[0]; return kv1<kv2?-1:kv1>kv2?1:0 });
53
- keyvals[0][0] = keyvals[0][0].replace(indent+' ',indent+'{');
54
- if (opts.aligned){
55
- var longest = 0;
56
- for (var i=keyvals.length;i--;) if (keyvals[i][0].length>longest) longest = keyvals[i][0].length;
57
- var padding = repeat(' ',longest);
58
- for (var i=keyvals.length;i--;) keyvals[i][0] = padRight(padding,keyvals[i][0]);
59
- }
60
- for (var i=keyvals.length;i--;){
61
- var k=keyvals[i][0], v=keyvals[i][1];
62
- var indent2 = repeat(' ',(k+colon).length);
63
- var oneLine = k+colon+build(v,'');
64
- // console.log(opts.wrap, oneLine.length, !v, typeof v)
65
- keyvals[i] = (opts.wrap===false || oneLine.length<=opts.wrap || !v || typeof v!="object") ? oneLine : (k+colon+build(v,indent2).replace(/^\s+/,''));
66
- }
67
- return keyvals.join(',\n') + opad + '}';
68
- }else{
69
- var keyvals=[],i=0;
70
- for (var k in o) keyvals[i++] = [indent+opts.indent+JSON.stringify(k),o[k]];
71
- if (opts.sorted) keyvals = keyvals.sort(function(kv1,kv2){ kv1=kv1[0]; kv2=kv2[0]; return kv1<kv2?-1:kv1>kv2?1:0 });
72
- if (opts.aligned){
73
- var longest = 0;
74
- for (var i=keyvals.length;i--;) if (keyvals[i][0].length>longest) longest = keyvals[i][0].length;
75
- var padding = repeat(' ',longest);
76
- for (var i=keyvals.length;i--;) keyvals[i][0] = padRight(padding,keyvals[i][0]);
77
- }
78
- var indent2 = indent+opts.indent;
79
- for (var i=keyvals.length;i--;){
80
- var k=keyvals[i][0], v=keyvals[i][1];
81
- var oneLine = k+colon+build(v,'');
82
- keyvals[i] = (opts.wrap===false || oneLine.length<=opts.wrap || !v || typeof v!="object") ? oneLine : (k+colon+build(v,indent2).replace(/^\s+/,''));
83
- }
84
- return indent+'{\n'+keyvals.join(',\n')+'\n'+indent+'}'
85
- }
86
-
87
- default:
88
- return indent+JSON.stringify(o);
89
- }
90
- }
91
- }
92
-
93
- function repeat(str,times){ // http://stackoverflow.com/a/17800645/405017
94
- var result = '';
95
- while(true){
96
- if (times & 1) result += str;
97
- times >>= 1;
98
- if (times) str += str;
99
- else break;
100
- }
101
- return result;
102
- }
103
- function padRight(pad, str){
104
- return (str + pad).substring(0, pad.length);
105
- }
106
- }