json_objects 0.0.1

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.
@@ -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