json_objects 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a9dc2ff554538a1a27dfdef5d8b79c0c7dafb314
4
+ data.tar.gz: a818bb78f50fe251ba711fefaa084293d2fb73ba
5
+ SHA512:
6
+ metadata.gz: 08bc57e8de4bb9ef1c17cd31d6377ae33a1ec694ff1a66234058f4a650133d794f5b2e5b7ff0f87fa229bbb2f9d39efd2a7d22facc0fc9b32d6b14e65098cd79
7
+ data.tar.gz: e68f57a8c8b6d57d3babf2d70c5bb494465d15c1fa745f904d93a6cc512a79d7db8a745d367f9722718409a6d24d526807857fb9105a99aee5c433511558045f
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in wisethinker.gemspec
4
+ gemspec
5
+
6
+ group :test, :development do
7
+ gem 'guard-minitest'
8
+ gem 'byebug'
9
+ gem 'benchmark-ips'
10
+ gem 'pry'
11
+ end
@@ -0,0 +1,6 @@
1
+ guard :minitest do
2
+ watch(%r{^spec/(.*)_spec.rb$})
3
+ watch(%r{^lib/(.+).rb$}) { |m| "spec/#{m[1]}_spec.rb" }
4
+ watch(%r{^spec/spec_helper.rb$}) { 'spec' }
5
+ watch(%r{^lib/*}) {'spec'}
6
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Dave Vallance
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,33 @@
1
+ # JsonObject
2
+
3
+ ## Description
4
+
5
+ See http://www.wisethinker.info/json-object/index for a quick description and more detailed information.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ## Ruby 2.0 dependent
12
+
13
+ I've used Ruby 2.0 keyword arguments. If theres a big demand for pre Ruby 2 support let me know ;)
14
+
15
+ ```ruby
16
+ gem 'json_object'
17
+ ```
18
+
19
+ And then execute:
20
+
21
+ $ bundle
22
+
23
+ Or install it yourself as:
24
+
25
+ $ gem install json_object
26
+
27
+ ## Contributing
28
+
29
+ 1. Fork it ( https://github.com/[my-github-username]/json_object/fork )
30
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
31
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
32
+ 4. Push to the branch (`git push origin my-new-feature`)
33
+ 5. Create a new Pull Request
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rake/testtask'
4
+
5
+ Rake::TestTask.new do |t|
6
+ t.pattern = "spec/**/*_spec.rb"
7
+ end
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'json_object/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "json_objects"
8
+ spec.version = JsonObject::VERSION
9
+ spec.authors = ["Dave Vallance"]
10
+ spec.email = ["davevallance@gmail.com"]
11
+ spec.summary = %q{Instead of accessing JSON Hashs the usual way, this allows creating custom classes to represent and access the JSON values.}
12
+ spec.description = %q{Quickly build objects to represent, store and access JSON Hash values. You can control the accessor method names, default values and provide procs to do more complex computation.}
13
+ spec.homepage = "https://github.com/dvallance/json_object"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ end
@@ -0,0 +1,203 @@
1
+ require "json_object/version"
2
+ require 'json'
3
+ require 'ostruct'
4
+
5
+ # The intended use of this module is for inclusion in a class, there by giving
6
+ # the class the necessary methods to store a JSON Hash and define custom accessors
7
+ # to retrieve its values.
8
+ #
9
+ # @example when including class has a no argument initializer
10
+ # class SomeClass
11
+ # include JsonObject
12
+ # end
13
+ #
14
+ # @example when the including class has an initializer with arguments
15
+ # class AnotherClass
16
+ # include JsonObject
17
+ #
18
+ # def initialize string
19
+ # # does something with string
20
+ # end
21
+ #
22
+ # # we must override the default {#create} method as it will call
23
+ # # new() with no arguments on the class by default
24
+ #
25
+ # #this is the form it must take
26
+ # def self.create hash, parent=nil
27
+ # # here we imagine getting the initializer string param from the hash
28
+ # obj = new(hash["..."])
29
+ #
30
+ # # we must set the json_hash instance variable for proper functionality
31
+ # obj.json_hash = hash
32
+ #
33
+ # # optionally we can set the hash_parent variable
34
+ # obj.parent = parent
35
+ #
36
+ # #finnally we return our new object
37
+ # obj
38
+ # end
39
+ #
40
+ # # same as above but using Object#tap for a cleaner implementation
41
+ # def self.create hash, parent=nil
42
+ # new(hash["..."]).tap do |obj|
43
+ # obj.json_hash = hash
44
+ # obj.parent = parent
45
+ # end
46
+ # end
47
+ #
48
+ # end
49
+ module JsonObject
50
+
51
+ # A sane default class for use by {ClassMethods#object_accessor} when a custom
52
+ # class is not provided.
53
+ #
54
+ # Simply an OpenStruct object with our JsonObject module included.
55
+ #
56
+ # @see ClassMethods#object_accessor
57
+ class JsonOpenStruct < OpenStruct
58
+ include JsonObject
59
+
60
+ # Making sure we set our json_* attributes otherwise
61
+ def self.create hash, parent=nil
62
+ new(hash).tap do |obj|
63
+ obj.parent = parent
64
+ obj.json_hash = hash
65
+ end
66
+ end
67
+ end
68
+
69
+ # JsonObject class methods
70
+ class << self
71
+
72
+ # Allows setting a custom class to replace the default JsonOpenStruct.
73
+ def default_json_object_class= klass
74
+ @default_json_object_class = klass
75
+ end
76
+
77
+ # Retrieve a set default class or use our JsonOpenStruct default.
78
+ def default_json_object_class
79
+ @default_json_object_class || JsonObject::JsonOpenStruct
80
+ end
81
+
82
+ def create
83
+ Class.new.include(JsonObject)
84
+ end
85
+ end
86
+
87
+ # Callback runs when module is included in another module/class.
88
+ #
89
+ # We use this to automatically extend our ClassMethods module in a
90
+ # class that includes JsonObject.
91
+ def self.included klass
92
+ klass.extend ClassMethods
93
+ end
94
+
95
+ # Used to aid in nested JsonObject's traversing back through their parents.
96
+ attr_accessor :parent
97
+
98
+ # Stores the underlying JSON Hash that we wish to then declare accessors for.
99
+ attr_accessor :json_hash
100
+
101
+ # Nested JsonObjects might be initalized with new so we account for that by
102
+ # supplying a empty hash default.
103
+ def json_hash= hash
104
+ @json_hash = hash || {}
105
+ end
106
+
107
+ # This will be extended when JsonObject is included in a class.
108
+ module ClassMethods
109
+
110
+ # Provides a default implementation of this method, which is a required
111
+ # call, used by {#object_accessor}
112
+ #
113
+ # Usable with a class that can be initialized with no arguments e.g. new()
114
+ def create hash, parent=nil
115
+ new().tap do |obj|
116
+ obj.parent = parent
117
+ obj.json_hash = hash
118
+ end
119
+ end
120
+
121
+ def create_value_accessor_method attribute, opts={}, &block
122
+ method_name = opts[:name] || attribute
123
+ cached_method_results_name = "@#{method_name}_cached"
124
+ define_method method_name.to_sym do
125
+ return instance_variable_get(cached_method_results_name) if instance_variable_defined?(cached_method_results_name)
126
+ instance_variable_set("@#{method_name}_cached", begin
127
+ block.yield self
128
+ end)
129
+ end
130
+ end
131
+
132
+ private :create_value_accessor_method
133
+
134
+ # Creates an accessor method to retrieve values from the stored {#json_hash}
135
+ #
136
+ # @param [#to_s] attribute will be used to retrieve a value from {#json_hash} and will be the name of the new accessor method by default
137
+ # @param [Hash] opts
138
+ # @option opts [#to_s] :name Will explicitly set the new accessor method name
139
+ # @option opts [Object] :default If {#json_hash} has no value for the given attribute the default provided will be returned.
140
+ # @option opts [Proc] :proc Allows a supplied proc to return the value from the created accessor method. The proc has access to self and the current value; may be from the :default option if provided.
141
+ def value_accessor attribute, opts={}
142
+ default_value = opts[:default]
143
+ proc_provided = opts[:proc]
144
+ create_value_accessor_method attribute, opts do |obj|
145
+ value = obj.json_hash[attribute.to_s]
146
+ value = default_value if value.nil?
147
+ proc_provided ? proc_provided.call(obj, value) : value
148
+ end
149
+ self
150
+ end
151
+
152
+
153
+ # Convienience method for defining muiltiple accessors with one call.
154
+ # @example Muiltiple accessors with no options
155
+ # value_accessors :first_name, :last_name, :age
156
+ #
157
+ # @example Muiltiple accessors with some options
158
+ # value_accessors [:selected, default: false], [:category, name: :main_category], :age
159
+ #
160
+ # @param args [#to_s, Array<#to_s, [Hash]>]
161
+ def value_accessors *args
162
+ args.each do |values|
163
+ value_accessor *Array(values)
164
+ end
165
+ self
166
+ end
167
+
168
+ # Similar to value_accessor.
169
+ #
170
+ # @example Accepting the default object class
171
+ # object_accessor :address_information
172
+ #
173
+ # @example Assigning a JsonObject class
174
+ # object_accessor :address_information, class: AddressInformation
175
+ #
176
+ # @param [#to_s] attribute will be used to retrieve the expected hash value from {#json_hash} and will be the name of the new accessor method by default.
177
+ # @param [Hash] opts
178
+ # @option opts [#to_s] :name Will explicitly set the new accessor method name
179
+ def object_accessor attribute, opts={}
180
+ klass = opts.fetch(:class, JsonObject.default_json_object_class)
181
+ set_parent = opts.fetch(:set_parent, true)
182
+ create_value_accessor_method attribute, opts do |obj|
183
+ value_for_attribute = obj.json_hash[attribute.to_s]
184
+ methods_value = if value_for_attribute.is_a? Array
185
+ value_for_attribute.inject([]) do |classes, hash|
186
+ classes << klass.create(hash, set_parent ? obj : nil)
187
+ end
188
+ else
189
+ value_for_attribute.nil? ? nil : klass.create(value_for_attribute, set_parent ? obj : nil)
190
+ end
191
+ end
192
+ self
193
+ end
194
+ end
195
+
196
+ # Alternative for include JsonObject is to inherit this class
197
+ # @example
198
+ # class MyClass < JsonObject::Base
199
+ # end
200
+ class Base
201
+ include JsonObject
202
+ end
203
+ end
@@ -0,0 +1,3 @@
1
+ module JsonObject
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,324 @@
1
+ require_relative 'spec_helper'
2
+
3
+ include JsonObject
4
+
5
+ describe JsonObject do
6
+
7
+ it "the default json_object_class is correct" do
8
+ JsonObject.default_json_object_class.must_equal JsonOpenStruct
9
+ end
10
+
11
+ it "we can change the default json_object_class" do
12
+ klass = Class.new()
13
+ JsonObject.default_json_object_class = klass
14
+ JsonObject.default_json_object_class.must_equal klass
15
+ #reset to correct default
16
+ JsonObject.default_json_object_class = JsonOpenStruct
17
+ end
18
+
19
+ subject { Class.new(Base) }
20
+
21
+ describe Base do
22
+
23
+ it "creating an instance with a nil hash will create an empty hash" do
24
+ subject.create(nil).json_hash.must_be_instance_of Hash
25
+ end
26
+ end
27
+
28
+ describe "value_accessors" do
29
+
30
+ let(:json) do
31
+ JSON.parse(<<-EOS
32
+ {"an_integer":1,"a_string":"my string","a_boolean":true,"an_array":[1,2,3],"false_boolean":false}
33
+ EOS
34
+ )
35
+ end
36
+
37
+ it "caching is working" do
38
+ subject.value_accessor :an_integer
39
+ check = subject.create(json)
40
+ check.instance_variable_defined?("@an_integer_cached").must_equal false
41
+ check.instance_variable_get("@an_integer_cached").must_equal nil
42
+ check.an_integer
43
+ check.instance_variable_defined?("@an_integer_cached").must_equal true
44
+ check.instance_variable_get("@an_integer_cached").must_equal 1
45
+ end
46
+
47
+ describe "#value_accessor works for data types Integer, String, Boolean and Array" do
48
+
49
+ it "integer" do
50
+ subject.value_accessor :an_integer
51
+ subject.create(json).an_integer.must_equal 1
52
+ end
53
+
54
+ it "string" do
55
+ subject.value_accessor :a_string
56
+ subject.create(json).a_string.must_equal "my string"
57
+ end
58
+
59
+ it "boolean" do
60
+ subject.value_accessor :a_boolean
61
+ subject.create(json).a_boolean.must_equal true
62
+ end
63
+
64
+ it "array" do
65
+ subject.value_accessor :an_array
66
+ subject.create(json).an_array.must_equal [1,2,3]
67
+ end
68
+
69
+ describe "assigning a specific accessor name" do
70
+ it "to one attribute" do
71
+ subject.value_accessor :an_integer, name: "new_integer_accessor"
72
+ subject.create(json).methods.must_include :new_integer_accessor
73
+ subject.create(json).new_integer_accessor.must_equal 1
74
+ end
75
+
76
+ it "with an existing accessor of the same name and a proc" do
77
+ subject.value_accessor :an_integer
78
+ subject.value_accessor :an_integer, name: "new_integer_accessor", proc: Proc.new {|obj, value| value * 2 }
79
+ subject.create(json).methods.must_include :new_integer_accessor
80
+ subject.create(json).an_integer.must_equal 1
81
+ subject.create(json).new_integer_accessor.must_equal 2
82
+ end
83
+ end
84
+
85
+ it "when a value doesn't exist nil will be found" do
86
+ subject.value_accessor :not_there
87
+ subject.create(json).not_there.must_equal nil
88
+ end
89
+
90
+ it "we can provide a default value so a nil return can be avoided" do
91
+ subject.value_accessor :not_there, default: "my default value"
92
+ subject.create(json).not_there.must_equal "my default value"
93
+ end
94
+
95
+ it "we can provide a default value that would evaluate to false" do
96
+ subject.value_accessor :not_there, default: false
97
+ subject.create(json).not_there.must_equal false
98
+ end
99
+
100
+ it "a default value will not overwrite an existing value that evaluates to false" do
101
+ subject.value_accessor :false_boolean, default: true
102
+ subject.create(json).false_boolean.must_equal false
103
+ end
104
+
105
+ it "we can provide a modifier proc" do
106
+ subject.value_accessor :an_integer, proc: Proc.new {|json_object,value| value*2}
107
+ subject.create(json).an_integer.must_equal 2
108
+ end
109
+
110
+ it "another modifying proc example showing it works after :default" do
111
+ subject.value_accessor :not_there, default: "small", proc: Proc.new {|json_object, value| value.sub('small', 'big')}
112
+ subject.create(json).not_there.must_equal "big"
113
+ end
114
+ end
115
+
116
+ describe "#value_accessors can be used to define muiltible accessors at a time" do
117
+
118
+ it "integer, string, boolean in one line assignment" do
119
+ subject.value_accessors :an_integer, :a_string, :a_boolean
120
+ subject.create(json).an_integer.must_equal 1
121
+ subject.create(json).a_string.must_equal "my string"
122
+ subject.create(json).a_boolean.must_equal true
123
+ end
124
+
125
+ it "correctly uses options like :name" do
126
+ subject.value_accessors :an_integer, [:a_string, name: "custom_name"]
127
+ subject.create(json).methods.must_include :custom_name
128
+ subject.create(json).custom_name.must_equal "my string"
129
+ end
130
+
131
+ end
132
+ end
133
+
134
+ describe "#object_accessor" do
135
+
136
+ let(:json) do
137
+ JSON.parse(<<-EOS
138
+ {"an_object":{"id":1, "name":"object one", "enabled":true}, "name":"record one"}
139
+ EOS
140
+ )
141
+ end
142
+
143
+ let :object_handler_class do
144
+ Class.new(Base).tap do |obj|
145
+ obj.value_accessors :id, :name, :object
146
+ end
147
+ end
148
+
149
+ it "caching is working" do
150
+ subject.object_accessor :an_object
151
+ check = subject.create(json)
152
+ check.instance_variable_defined?("@an_object_cached").must_equal false
153
+ check.instance_variable_get("@an_object_cached").must_equal nil
154
+ check.an_object
155
+ check.instance_variable_defined?("@an_object_cached").must_equal true
156
+ check.instance_variable_get("@an_object_cached").must_be_instance_of JsonOpenStruct
157
+ end
158
+
159
+ describe "providing a class to handle a json object" do
160
+
161
+ it "we correctly have an instace of our object handler" do
162
+ subject.object_accessor :an_object, class: object_handler_class
163
+ subject.create(json).an_object.must_be_instance_of object_handler_class
164
+ end
165
+
166
+ it "the object handler contains the correct values " do
167
+ subject.object_accessor :an_object, class: object_handler_class
168
+ object_handler_class.value_accessor :an_integer
169
+ subject.create(json).an_object.id.must_equal 1
170
+ end
171
+
172
+ it "the object handler sets the parent by default" do
173
+ TempClass = JsonObject.create
174
+ TempClass.object_accessor :an_object, class: object_handler_class
175
+ TempClass.create(json).an_object.parent.must_be_instance_of TempClass
176
+ end
177
+
178
+ it "the object handler handles set_parent(false)" do
179
+ Temp2Class = JsonObject.create
180
+ Temp2Class.object_accessor :an_object, class: object_handler_class, set_parent: false
181
+ Temp2Class.create(json).an_object.parent.must_be_instance_of NilClass
182
+ end
183
+
184
+ it "the object handler has a value_accessor set that has access to the object and its parent via proc" do
185
+ subject.value_accessor :name
186
+ object_handler_class.value_accessor :parents_name, proc: Proc.new {|json_object, value| json_object.parent.name}
187
+ subject.object_accessor :an_object, class: object_handler_class
188
+ subject.create(json).an_object.parents_name.must_equal "record one"
189
+
190
+ #also confirm the parent is correct
191
+ result = subject.create(json)
192
+ result.an_object.parent.must_equal result
193
+ end
194
+
195
+ end
196
+
197
+ describe "not supplying a specific object handler" do
198
+
199
+ it "assigns the values to an OpenStruct object by default" do
200
+ subject.object_accessor :an_object
201
+ subject.create(json).an_object.must_be_instance_of JsonOpenStruct
202
+ end
203
+
204
+ it "also has access to the parent" do
205
+ subject.object_accessor :an_object
206
+ result = subject.create(json)
207
+ result.an_object.parent.must_equal result
208
+ end
209
+ end
210
+
211
+ describe "an object handler given a nil (non-existing json object)" do
212
+
213
+ it "simply returns nil" do
214
+ subject.object_accessor :dosent_exist, class: object_handler_class
215
+ subject.create(json).dosent_exist.must_be_nil
216
+ end
217
+
218
+ end
219
+
220
+ describe "with arrays" do
221
+ let(:json) do
222
+ JSON.parse(<<-EOS
223
+ {"objects":[
224
+ {"id":1, "name":"object one"},
225
+ {"id":2, "name":"object two"},
226
+ {"id":3, "name":"object three"}
227
+ ]
228
+ }
229
+ EOS
230
+ )
231
+ end
232
+
233
+ describe "not supplying object class handlers" do
234
+
235
+ it "when theres an array of objects we will get back an array" do
236
+
237
+ subject.object_accessor :objects
238
+ subject.create(json).objects.must_be_instance_of Array
239
+ end
240
+
241
+ it "the array will contain OpenStruct objects" do
242
+
243
+ subject.object_accessor :objects
244
+ subject.create(json).objects[0].must_be_instance_of JsonOpenStruct
245
+
246
+ end
247
+
248
+ it "when the json array is empty the return value will be as well" do
249
+ subject.object_accessor :objects
250
+ subject.create(JSON.parse('{"objects":[]}')).objects.must_be_empty
251
+ end
252
+ end
253
+
254
+ describe "when using object handler classes" do
255
+
256
+ it "providing a custom class for our objects works" do
257
+ subject.object_accessor :objects, class: object_handler_class
258
+ subject.create(json).objects.must_be_instance_of Array
259
+ end
260
+
261
+ it "the array will contain our supplied object handlers" do
262
+ subject.object_accessor :objects, class: object_handler_class
263
+ subject.create(json).objects[0].must_be_instance_of object_handler_class
264
+ end
265
+
266
+ it "when the json array is empty the return value will be as well" do
267
+ subject.object_accessor :objects, class: object_handler_class
268
+ subject.create(JSON.parse('{"objects":[]}')).objects.must_be_empty object_handler_class
269
+ end
270
+
271
+ it "if we rename the accessor name it will be used instead of the attribute name" do
272
+ subject.object_accessor :objects, name: 'cool_objects', class: object_handler_class
273
+ subject.create(json).methods.must_include :cool_objects
274
+ subject.create(json).cool_objects.first.id.must_equal 1
275
+ end
276
+
277
+ it "the object handler sets the parent by default" do
278
+ Temp3Class = JsonObject.create
279
+ Temp3Class.object_accessor :objects, class: object_handler_class
280
+ Temp3Class.create(json).objects.first.parent.must_be_instance_of Temp3Class
281
+ end
282
+
283
+ it "the object handler handles set_parent(false)" do
284
+ Temp4Class = JsonObject.create
285
+ Temp4Class.object_accessor :objects, class: object_handler_class, set_parent: false
286
+ Temp4Class.create(json).objects.first.parent.must_be_instance_of NilClass
287
+ end
288
+
289
+ end
290
+ end
291
+
292
+ describe "with arrays that have null entries" do
293
+ let(:json) do
294
+ JSON.parse(<<-EOS
295
+ {"objects":[
296
+ null,
297
+ {"id":2, "name":"object three"},
298
+ {"id":3, "name":"object three"}
299
+ ]
300
+ }
301
+ EOS
302
+ )
303
+ end
304
+
305
+ describe "not supplying object class handlers" do
306
+
307
+ it "OpenStruct handles a nil initializer" do
308
+ subject.object_accessor :objects
309
+ subject.create(json).objects.must_be_instance_of Array
310
+ subject.create(json).objects.first.must_be_instance_of JsonOpenStruct
311
+ end
312
+ end
313
+
314
+ describe "supplying an object handler class" do
315
+ it "OpenStruct handles a nil initializer" do
316
+ subject.object_accessor :objects, class: object_handler_class
317
+ subject.create(json).objects.must_be_instance_of Array
318
+ subject.create(json).objects.first.must_be_instance_of object_handler_class
319
+ subject.create(json).objects.first.id.must_equal nil
320
+ end
321
+ end
322
+ end
323
+ end
324
+ end
@@ -0,0 +1,6 @@
1
+ require_relative '../lib/json_object'
2
+ require 'minitest/autorun'
3
+ require 'minitest/spec'
4
+ require 'json'
5
+ require 'pry'
6
+ require 'byebug'
metadata ADDED
@@ -0,0 +1,88 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: json_objects
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Dave Vallance
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description: Quickly build objects to represent, store and access JSON Hash values.
42
+ You can control the accessor method names, default values and provide procs to do
43
+ more complex computation.
44
+ email:
45
+ - davevallance@gmail.com
46
+ executables: []
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - ".gitignore"
51
+ - Gemfile
52
+ - Guardfile
53
+ - LICENSE.txt
54
+ - README.md
55
+ - Rakefile
56
+ - json_object.gemspec
57
+ - lib/json_object.rb
58
+ - lib/json_object/version.rb
59
+ - spec/json_object_spec.rb
60
+ - spec/spec_helper.rb
61
+ homepage: https://github.com/dvallance/json_object
62
+ licenses:
63
+ - MIT
64
+ metadata: {}
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubyforge_project:
81
+ rubygems_version: 2.2.2
82
+ signing_key:
83
+ specification_version: 4
84
+ summary: Instead of accessing JSON Hashs the usual way, this allows creating custom
85
+ classes to represent and access the JSON values.
86
+ test_files:
87
+ - spec/json_object_spec.rb
88
+ - spec/spec_helper.rb