jsonify 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Jsonify
1
+ # Jsonify -- a builder for JSON <a href="http://travis-ci.org/bsiggelkow/jsonify"><img src="https://secure.travis-ci.org/bsiggelkow/jsonify.png" alt=""></a>
2
2
 
3
3
  [Jsonify](https://github.com/bsiggelkow/jsonify) is to JSON as [Builder](https://github.com/jimweirich/builder) is to XML.
4
4
 
@@ -19,18 +19,15 @@ Nevertheless, this forces the developer to place this code into the model when i
19
19
 
20
20
  When someone asks "Where are the model representations defined?", I don't want to have to say "Well, look in the views folder for XML, but you have to look at the code in the model for the JSON format."
21
21
 
22
- There are other good libraries available that help solve this problem, such as Tokamak and RABL, that allow the developer to specify the representation in one format that is then interpreted into the wanted format at runtime.
23
- Please take a look at these projects when you consider alternatives; however, its my opinion that they are substantial and inherent differences between XML and JSON.
22
+ There are a number of <a href='#related'>other libraries</a> available that try to solve this problem. Some take a similar approach to Jsonify and provide a builder-style interface.
23
+ Others allow the developer to specify the representation using a common DSL that can generate both JSON and XML.
24
+ Please take a look at these projects when you consider alternatives. It's my opinion that there are substantial and inherent differences between XML and JSON; and that these differences may force the developer to make concessions in one format or the other.
24
25
 
25
- These differences may force the developer make concessions in one format to make the other format correct.
26
-
27
- But an even greater motivation for me was emulating the simplicity of Builder. I have not found a single framework for JSON that provides the simplicity and elegance of Builder. Jsonify is my attempt at remedying that situation.
28
-
29
- ___more coming soon___
26
+ But an even greater motivation for me was emulating the simplicity of [Builder](https://github.com/jimweirich/builder). I have not found a single framework for JSON that provides the simplicity and elegance of Builder. Jsonify is my attempt at remedying that situation.
30
27
 
31
28
  ## Installation
32
29
 
33
- gem install jsonify
30
+ `gem install jsonify`
34
31
 
35
32
  ## Usage
36
33
 
@@ -82,7 +79,7 @@ Results in ...
82
79
 
83
80
  ### View Templates
84
81
 
85
- Jsonify includes Rails 3 template handler. Rails will handle any template with a ___.jsonify___ extension with Jsonify.
82
+ Jsonify includes Rails 3 template handler. Rails will handle any template with a `.jsonify` extension with Jsonify.
86
83
  The Jsonify template handler exposes the `Jsonify::Builder` instance to your template with the `json` variable as in the following example:
87
84
 
88
85
  json.hello do
@@ -91,15 +88,18 @@ The Jsonify template handler exposes the `Jsonify::Builder` instance to your tem
91
88
 
92
89
  ## Documentation
93
90
 
94
- [Jsonify Yard Docs](http://rubydoc.info/github/bsiggelkow/jsonify/master/frames)
95
-
96
- ## Build Status
91
+ [Yard Docs](http://rubydoc.info/github/bsiggelkow/jsonify/master/frames)
97
92
 
98
- [Compliments of Travis](http://travis-ci.org/bsiggelkow/jsonify)
93
+ <a name='related'/>
94
+ <h2>Related Projects</h2>
95
+ - [Argonaut](https://github.com/jbr/argonaut)
96
+ - [JSON Builder](https://github.com/dewski/json_builder)
97
+ - [RABL](https://github.com/nesquena/rabl)
98
+ - [Tokamak](https://github.com/abril/tokamak)
99
99
 
100
100
  ## TODOs
101
- 1. Consider simplified means of creating arrays (e.g. json.links(@links) {|link| ...})
102
101
  1. Benchmark performance
102
+ 1. Document how partials can be used
103
103
 
104
104
  ## Roadmap
105
105
 
@@ -40,43 +40,93 @@ module Jsonify
40
40
  @pretty ? JSON.pretty_generate(JSON.parse(result)) : result
41
41
  end
42
42
 
43
- # Adds the value(s) to the current JSON object in the builder's stack.
44
- # @param *args values
45
- def add!(*args)
46
- __current.add *args
43
+ # Stores the key and value into a JSON object
44
+ # @param key the key for the pair
45
+ # @param value the value for the pair
46
+ # @return self to allow for chaining
47
+ def store!(key, value=nil)
48
+ (@stack[@level] ||= JsonObject.new).add(key,value)
49
+ self
47
50
  end
51
+
52
+ alias_method :[]=, :store!
48
53
 
49
- alias_method :<<, :add!
54
+ # Append -- pushes the given object on the end of a JsonArray.
55
+ def <<(val)
56
+ __append(val)
57
+ self
58
+ end
59
+
60
+ # Append -- pushes the given variable list objects on to the end of the JsonArray
61
+ def append!(*args)
62
+ args.each do |arg|
63
+ __append( arg )
64
+ end
65
+ self
66
+ end
50
67
 
51
- # Adds a new JsonPair to the builder.
52
- # This method will be called if the name does not match an existing method name.
68
+ # Adds a new JsonPair to the builder where the key of the pair is set to the method name
69
+ # (`sym`).
70
+ # When passed a block, the value of the pair is set to the result of that
71
+ # block; otherwise, the value is set to the argument(s) (`args`).
72
+ #
73
+ # @example Create an object literal
74
+ # json.person do
75
+ # json.first_name @person.given_name
76
+ # json.last_name @person.surname
77
+ # end
78
+ #
79
+ # @example compiles to something like ...
80
+ # "person": {
81
+ # "first_name": "George",
82
+ # "last_name": "Burdell"
83
+ # }
84
+ #
85
+ # If a block is given and an argument is passed, the argument it is assumed to be an
86
+ # Array (more specifically, an object that responds to `each`).
87
+ # The argument is iterated over and each item is yielded to the block.
88
+ # The result of the block becomes an array item of a JsonArray.
89
+ #
90
+ # @example Map an of array of links to an array of JSON objects
91
+ # json.links(@links) do |link|
92
+ # {:rel => link.first, :href => link.last}
93
+ # end
94
+ #
95
+ # @example compiles to something like ...
96
+ # "links": [
97
+ # {
98
+ # "rel": "self",
99
+ # "href": "http://example.com/people/123"
100
+ # },
101
+ # {
102
+ # "rel": "school",
103
+ # "href": "http://gatech.edu"
104
+ # }
105
+ # ]
53
106
  #
54
107
  # @param *args [Array] iterates over the given array yielding each array item to the block; the result of which is added to a JsonArray
55
108
  def method_missing(sym, *args, &block)
56
109
 
57
110
  # When no block given, simply add the symbol and arg as key - value for a JsonPair to current
58
- return __current.add( sym, args.length > 1 ? args : args.first ) unless block
111
+ return __store( sym, args.length > 1 ? args : args.first ) unless block
59
112
 
60
- # Create a JSON pair and add it to the current object
61
- pair = Generate.pair_value(sym)
62
- __current.add(pair)
113
+ # In a block; create a JSON pair (with no value) and add it to the current object
114
+ pair = Generate.pair_value(sym)
115
+ __store pair
63
116
 
64
117
  # Now process the block
65
118
  @level += 1
66
119
 
67
- unless args.empty?
68
- # Argument was given, iterate over it and add result to a JsonArray
69
- __set_current JsonArray.new
120
+ if args.empty?
121
+ block.call
122
+ else
70
123
  args.first.each do |arg|
71
- __current.add block.call(arg)
124
+ __append block.call(arg)
72
125
  end
73
- else
74
- # No argument was given; ordinary JsonObject is expected
75
- block.call(self)
76
126
  end
77
127
 
78
- # Set the value on the pair to current
79
- pair.value = __current
128
+ # Set the value on the pair to the object at the top of the stack
129
+ pair.value = @stack[@level]
80
130
 
81
131
  # Pop current off the top of the stack; we are done with it at this point
82
132
  @stack.pop
@@ -84,69 +134,17 @@ module Jsonify
84
134
  @level -= 1
85
135
  end
86
136
 
87
- # Sets the object at the top of the stack to a new JsonObject, which is yielded to the block.
88
- def object!
89
- __set_current JsonObject.new
90
- yield __current
91
- end
92
-
93
- # Sets the object at the top of the stack to a new JsonArray, which is yielded to the block.
94
- def array!
95
- __set_current JsonArray.new
96
- @level += 1
97
- yield @stack[@level-1]
98
- @level -= 1
99
- __current
100
- end
101
-
102
- # Maps each element in the given array to a JsonArray. The result of the block becomes an array item of the JsonArray.
103
- # @param array array of objects to iterate over.
104
- #
105
- # @example Map an of array of links to an array of JSON objects
106
- # json.links do
107
- # json.map!(links) do |link|
108
- # {:rel => link.first, :href => link.last}
109
- # end
110
- # end
111
- #
112
- # @example compiles to something like ...
113
- # "links": [
114
- # {
115
- # "rel": "self",
116
- # "href": "http://example.com/people/123"
117
- # },
118
- # {
119
- # "rel": "school",
120
- # "href": "http://gatech.edu"
121
- # }
122
- # ]
123
- def map!(array)
124
- __set_current JsonArray.new
125
- array.each do |item|
126
- __current << (yield item)
127
- end
128
- __current
129
- end
130
-
131
- alias_method :collect!, :map!
132
-
133
137
  private
134
138
 
135
- # Inheriting from BlankSlate requires these funky (aka non-idiomatic) method names
139
+ # BlankSlate requires the __<method> names
136
140
 
137
- # Current object at the top of the stack. If there is no object there; initializes to a new JsonObject
138
- #
139
- # @return [JsonValue] object at the top of the stack
140
- def __current
141
- @stack[@level] ||= JsonObject.new
142
- end
141
+ def __store(key,value=nil)
142
+ (@stack[@level] ||= JsonObject.new).add(key,value)
143
+ end
143
144
 
144
- # Sets the current object at the top of the stack
145
- #
146
- # @param val object to set at the top of the stack
147
- def __set_current(val)
148
- @stack[@level] = val
145
+ def __append(value)
146
+ (@stack[@level] ||= JsonArray.new).add value
149
147
  end
150
-
148
+
151
149
  end
152
150
  end
@@ -1,3 +1,3 @@
1
1
  module Jsonify
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
data/spec/builder_spec.rb CHANGED
@@ -63,46 +63,59 @@ PRETTY_JSON
63
63
  json.compile!.should == pretty_results.chomp
64
64
  end
65
65
  end
66
+
67
+ describe 'array creation' do
68
+ it 'with the append operator (<<)' do
69
+ json << 1 << 2
70
+ json.compile!.should == "[1,2]"
71
+ end
72
+ it 'with the append! method' do
73
+ json.append!( 1,2 )
74
+ .append! 3
75
+ json.compile!.should == "[1,2,3]"
76
+ end
77
+ end
78
+ describe 'object creation' do
79
+ it 'should support the element assignment operator( []= )' do
80
+ json["foo"] = 'bar'
81
+ json.compile!.should == '{"foo":"bar"}'
82
+ end
83
+ it 'should support the store! message' do
84
+ json.store!( "foo", "bar" )
85
+ .store!( 'no', "whar" )
86
+ json.compile!.should == '{"foo":"bar","no":"whar"}'
87
+ end
88
+ end
66
89
  end
67
90
 
68
91
  describe 'arrays' do
69
92
  it 'simple array should work' do
70
- json.array! do |ary|
71
- ary << 1
72
- ary << 2
73
- end
93
+ json << 1
94
+ json << 2
74
95
  json.compile!.should == "[1,2]"
75
96
  end
76
97
  it 'array of arrays should work' do
77
- json.array! do |ary|
78
- ary << json.array! {|a| a << 1}
79
- ary << json.array! {|b| b << 2}
80
- ary << 3
81
- end
82
- json.compile!.should == "[[1],[2],3]"
98
+ json << [1]
99
+ json << [2]
100
+ json << [3]
101
+ json.compile!.should == "[[1],[2],[3]]"
83
102
  end
84
103
  it 'array of hashes should work' do
85
- json.array! do |ary|
86
- ary << {:foo => :bar}
87
- ary << {:go => :far}
88
- end
104
+ json << {:foo => :bar}
105
+ json << {:go => :far}
89
106
  json.compile!.should == "[{\"foo\":\"bar\"},{\"go\":\"far\"}]"
90
107
  end
91
108
  end
92
109
 
93
110
  describe 'objects' do
94
111
  it 'simple object should work' do
95
- json.object! do |obj|
96
- obj.add :foo,:bar
97
- obj.add :go, :far
98
- end
112
+ json.foo :bar
113
+ json.go :far
99
114
  json.compile!.should == "{\"foo\":\"bar\",\"go\":\"far\"}"
100
115
  end
101
116
  it 'should handle arrays' do
102
- json.object! do |obj|
103
- obj.add 1, [2, 3]
104
- obj.add 4, 5
105
- end
117
+ json[1] = [2, 3]
118
+ json[4] = 5
106
119
  json.compile!.should == '{"1":[2,3],"4":5}'
107
120
  end
108
121
  end
@@ -136,10 +149,8 @@ PRETTY_JSON
136
149
 
137
150
  it 'hash with array' do
138
151
  json.foo do
139
- json.array! do |ary|
140
- ary << 1
141
- ary << 2
142
- end
152
+ json << 1
153
+ json << 2
143
154
  end
144
155
  json.compile!.should == "{\"foo\":[1,2]}"
145
156
  end
@@ -153,10 +164,8 @@ PRETTY_JSON
153
164
  end
154
165
 
155
166
  it 'simple array with object' do
156
- json.array! do |ary|
157
- ary << 1
158
- ary << (json.foo 'bar')
159
- end
167
+ json << 1
168
+ json << {:foo => :bar}
160
169
  json.compile!.should == "[1,{\"foo\":\"bar\"}]"
161
170
  end
162
171
 
@@ -165,10 +174,8 @@ PRETTY_JSON
165
174
  json.bar do
166
175
  json.baz 'goo'
167
176
  json.years do
168
- json.array! do |ary|
169
- ary << 2011
170
- ary << 2012
171
- end
177
+ json << 2011
178
+ json << 2012
172
179
  end
173
180
  end
174
181
  end
@@ -203,7 +210,7 @@ PRETTY_JSON
203
210
  link_class.new('foo.com', 'parent')
204
211
  ]
205
212
  }
206
- it 'should work using array!' do
213
+ it 'should work using arrays' do
207
214
  json.result do
208
215
  json.person do
209
216
  json.fname 'George'
@@ -216,23 +223,5 @@ PRETTY_JSON
216
223
  expected = "{\"result\":{\"person\":{\"fname\":\"George\",\"lname\":\"Burdell\"},\"links\":[{\"href\":\"example.com\",\"rel\":\"self\"},{\"href\":\"foo.com\",\"rel\":\"parent\"}]}}"
217
224
  JSON.parse(json.compile!).should == JSON.parse(expected)
218
225
  end
219
-
220
- it "should work using map! with argument" do
221
- json.result do
222
- json.person do
223
- json.fname 'George'
224
- json.lname 'Burdell'
225
- end
226
- json.links do
227
- json.map!(links) do |link|
228
- { :href => link.url, :rel => link.type}
229
- end
230
- end
231
- end
232
- expected = "{\"result\":{\"person\":{\"fname\":\"George\",\"lname\":\"Burdell\"},\"links\":[{\"href\":\"example.com\",\"rel\":\"self\"},{\"href\":\"foo.com\",\"rel\":\"parent\"}]}}"
233
- JSON.parse(json.compile!).should == JSON.parse(expected)
234
- end
235
226
  end
236
-
237
-
238
227
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: jsonify
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.2
5
+ version: 0.0.3
6
6
  platform: ruby
7
7
  authors:
8
8
  - Bill Siggelkow
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-07-25 00:00:00 -04:00
13
+ date: 2011-07-27 00:00:00 -04:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -144,7 +144,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
144
144
  requirements:
145
145
  - - ">="
146
146
  - !ruby/object:Gem::Version
147
- hash: -2236513269003945627
147
+ hash: 2505547202778738501
148
148
  segments:
149
149
  - 0
150
150
  version: "0"
@@ -153,7 +153,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
153
153
  requirements:
154
154
  - - ">="
155
155
  - !ruby/object:Gem::Version
156
- hash: -2236513269003945627
156
+ hash: 2505547202778738501
157
157
  segments:
158
158
  - 0
159
159
  version: "0"