son_jay 0.1.0.alpha → 0.1.1.alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MjdiYTdiZjkxOWE3ZDg0ZjkxNzY0ZjNkYzEwYzg1ZWM1ZWQ3NTM5Yg==
4
+ ZTA4ZWUzZGQwNzA1NTE4NzgxOTc3YmM3NzlkZGNhOTY4Yzc1MzljMA==
5
5
  data.tar.gz: !binary |-
6
- MjA4ZmQ1NDRkZDgwN2JmZDU1YmU4ZmFmMDM0NzhkZjAyZjczMzBiOQ==
6
+ OWE2NThlMjk0YzNlZDBmNGNmYjVhNGQ2MWE0OGQ4MWEwZDRmYTZlMw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ZDkzNGQ4ZTk1ZjZhNjYyYTg0MDU0NzMwNTM2ZTM0MzJhNWQwNmY1OGIyMDY0
10
- YjY2NThhMDJhNmMwODc2NjYyNGM4NDg5NzM3OTllZmJhMjVlMzdhMmMzY2Qw
11
- ZjU5YzcwNTY3MTdhMWY1NTI0NDU2NGJiMGZkODZiMmVkOWVkYzk=
9
+ NTBiNTBkZWNhOWI1ODk1OGJhNTQ2ODlhOGQwZGRlYzhiNGE0YmZhN2QyMzBi
10
+ MTY4ZWI1MTJlODU5ZmZhYzYzMDRhMGI5ZDI2Mjg5OGQ2Y2IwMDk0MDRhYTgw
11
+ NmUyZTZhOTAzMmExMTJjNGJhMDFkM2ExNGI5OTc5OGE0YWIxMjI=
12
12
  data.tar.gz: !binary |-
13
- ZjI0N2FiMTE0MWNiYjVjM2IwZDQ2MGZkN2Y5MWUzNjg2NmVjYWRkZDQzMjU5
14
- M2FlMzdjMzM3NmVmZWQxZWVlNzJkM2M1N2VmZGE5OTlhOTBmNzg2ZDI5MmJl
15
- MjZmMjdmNTBmNGRiZDNjYTMwZWQ2YjRlZDUxZDFkMDkyNWQ0YzM=
13
+ NGVmMmM4ZmFiNWUxOWJjNjZjMGRlZTc2OTcwOTJkMmIxYWI1MzJiMzI0NmQ1
14
+ NWQyODViNDYyNDgyZWZlODdjY2VmZjE3MzI1MjEzMThiNzMyMzgzYzBhNDJi
15
+ NjFkZjNmN2FmNWEwYmQ0MjNhYWYwOWY5ZTJhNjUxZGJjNzU2Zjk=
@@ -0,0 +1,27 @@
1
+ module SonJay
2
+ module ActsAsModel
3
+
4
+ def self.included(other)
5
+ other.extend ClassBehavior
6
+ end
7
+
8
+ module ClassBehavior
9
+
10
+ def json_create(json)
11
+ data = JSON.parse( json )
12
+ instance = new
13
+ instance.sonj_content.load_data data
14
+ instance
15
+ end
16
+
17
+ def array_class
18
+ @array_class ||= begin
19
+ klass = SonJay::ModelArray(self)
20
+ const_set :Array, klass
21
+ end
22
+ end
23
+
24
+ end
25
+
26
+ end
27
+ end
@@ -9,18 +9,12 @@ module SonJay
9
9
  end
10
10
 
11
11
  class ModelArray
12
+ include ActsAsModel
12
13
  extend Forwardable
13
14
 
14
15
  class << self
15
16
  attr_accessor :entry_class
16
-
17
- def array_class
18
- #TODO: Factor out duplication w/ ObjectModel::array_class
19
- @array_class ||= begin
20
- klass = SonJay::ModelArray(self)
21
- const_set :Array, klass
22
- end
23
- end
17
+ private :entry_class=
24
18
  end
25
19
 
26
20
  def initialize
@@ -0,0 +1,16 @@
1
+ module SonJay
2
+ class ObjectModel
3
+ class PropertiesDefiner
4
+
5
+ def initialize(property_definitions)
6
+ @property_definitions = property_definitions
7
+ end
8
+
9
+ def property(name, options={})
10
+ name = "#{name}"
11
+ @property_definitions << PropertyDefinition.new( name, options[:model] )
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -1,59 +1,55 @@
1
+ require 'set'
1
2
  require 'son_jay/object_model/properties'
2
3
  require 'son_jay/object_model/property_definition'
4
+ require 'son_jay/object_model/properties_definer'
3
5
 
4
6
  module SonJay
5
7
  class ObjectModel
6
-
7
- class PropertiesDefiner
8
-
9
- def initialize(property_definitions)
10
- @property_definitions = property_definitions
11
- end
12
-
13
- def property(name, options={})
14
- name = "#{name}"
15
- @property_definitions << PropertyDefinition.new( name, options[:model] )
16
- end
17
-
18
- end
8
+ include ActsAsModel
19
9
 
20
10
  class << self
21
11
 
22
- def json_create(json)
23
- data = JSON.parse( json )
24
- instance = new
25
- instance.sonj_content.load_data data
26
- instance
27
- end
28
-
29
12
  def properties(&property_initializations)
30
13
  @property_initializations = property_initializations
31
14
  end
32
15
 
33
16
  def property_definitions
34
- @property_definitions ||= begin
35
- definitions = []
36
-
37
- definer = PropertiesDefiner.new(definitions)
38
- definer.instance_eval &@property_initializations
39
- definitions.each do |d|
40
- name = d.name
41
- class_eval <<-CODE
42
- def #{name} ; sonj_content[#{name.inspect}] ; end
43
- def #{name}=(value) ; sonj_content[#{name.inspect}] = value ; end
44
- CODE
45
- end
46
- definitions
17
+ @property_definitions ||= nil
18
+ return @property_definitions if @property_definitions
19
+
20
+ definitions = []
21
+
22
+ definer = PropertiesDefiner.new(definitions)
23
+ definer.instance_eval &@property_initializations
24
+ @property_definitions = definitions
25
+
26
+ validate_model_dependencies!
27
+
28
+ definitions.each do |d|
29
+ name = d.name
30
+ class_eval <<-CODE
31
+ def #{name} ; sonj_content[#{name.inspect}] ; end
32
+ def #{name}=(value) ; sonj_content[#{name.inspect}] = value ; end
33
+ CODE
47
34
  end
35
+
36
+ @property_definitions
48
37
  end
49
38
 
50
- def array_class
51
- @array_class ||= begin
52
- klass = SonJay::ModelArray(self)
53
- const_set :Array, klass
39
+ private
40
+
41
+ def validate_model_dependencies!(dependants=Set.new)
42
+ raise InfiniteRegressError if dependants.include?(self)
43
+ dependants << self
44
+ hard_model_dependencies.each do |d|
45
+ next unless d.respond_to?(:validate_model_dependencies!, true)
46
+ d.send :validate_model_dependencies!, dependants
54
47
  end
55
48
  end
56
49
 
50
+ def hard_model_dependencies
51
+ property_definitions.map(&:model_class).compact.uniq
52
+ end
57
53
  end
58
54
 
59
55
  attr_reader :sonj_content
@@ -1,17 +1,12 @@
1
1
  module SonJay
2
2
  class ValueArray < ::Array
3
- Array = SonJay::ModelArray(self)
4
-
5
- def self.array_class
6
- self::Array
7
- end
3
+ include ActsAsModel
8
4
 
9
5
  def sonj_content
10
6
  self
11
7
  end
12
8
 
13
- def load_data(data)
14
- replace data
15
- end
9
+ alias load_data replace
10
+
16
11
  end
17
12
  end
@@ -1,3 +1,3 @@
1
1
  module SonJay
2
- VERSION = "0.1.0.alpha"
2
+ VERSION = "0.1.1.alpha"
3
3
  end
data/lib/son_jay.rb CHANGED
@@ -1,8 +1,10 @@
1
1
  require 'json'
2
2
  require 'son_jay/version'
3
+ require 'son_jay/acts_as_model'
3
4
  require 'son_jay/object_model'
4
5
  require 'son_jay/model_array'
5
6
  require 'son_jay/value_array'
6
7
 
7
8
  module SonJay
9
+ class InfiniteRegressError < StandardError ; end
8
10
  end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ describe SonJay::ActsAsModel do
4
+ context "included as a class mixin" do
5
+
6
+ let( :klass ) {
7
+ Class.new do
8
+ include SonJay::ActsAsModel
9
+
10
+ class Content
11
+ attr_reader :loaded_data
12
+
13
+ def load_data(data)
14
+ @loaded_data = data
15
+ end
16
+ end
17
+
18
+ def sonj_content
19
+ @sonj_content ||= Content.new
20
+ end
21
+ end
22
+ }
23
+
24
+ describe '::json_create' do
25
+ it "returns a new instance with parsed JSON data loaded into its #sonj_content object" do
26
+ instance = klass.json_create( '{"hello": "world"}' )
27
+ loaded_data = instance.sonj_content.loaded_data
28
+ expect( loaded_data ).to eq( {'hello' => 'world'} )
29
+ end
30
+ end
31
+
32
+ describe '::array_class' do
33
+ it "returns an array model class with the target as its entry class" do
34
+ result = klass.array_class
35
+ expect( result.entry_class ).to eq( klass )
36
+ end
37
+ end
38
+
39
+ end
40
+ end
@@ -31,7 +31,6 @@ describe SonJay::ModelArray do
31
31
  describe '::array_class' do
32
32
  it "returns a model-array subclass for entries of this model-array type (nested array)" do
33
33
  array_class = subclass.array_class
34
- puts array_class.ancestors
35
34
  expect( array_class.ancestors ).to include( SonJay::ModelArray )
36
35
  expect( array_class.entry_class ).to eq( subclass )
37
36
  end
@@ -133,4 +133,47 @@ describe SonJay::ObjectModel do
133
133
 
134
134
  end
135
135
 
136
+ describe "a subclass with a directly self-referential property specification" do
137
+ let!( :subclass ) {
138
+ cc = lambda{ component }
139
+ Class.new(described_class) do
140
+ properties do ; property :component, model: cc.call ; end
141
+ end
142
+ }
143
+
144
+ let!( :component ) {
145
+ cc = lambda{ sub_component }
146
+ Class.new(described_class) do
147
+ properties do ; property :component, model: cc.call ; end
148
+ end
149
+ }
150
+
151
+ let!( :sub_component ) {
152
+ cc = lambda{ subclass }
153
+ Class.new(described_class) do
154
+ properties do ; property :component, model: cc.call ; end
155
+ end
156
+ }
157
+
158
+ it "raises an infinte regress error when property_definitions are resolved" do
159
+ expect{ subclass.property_definitions }.to raise_exception( SonJay::InfiniteRegressError )
160
+ end
161
+ end
162
+
163
+ describe "a subclass with an indirectly self-referential property specification" do
164
+ let!( :subclass ) {
165
+ Class.new(described_class) do
166
+ this_model_class = self
167
+ properties do
168
+ property :a
169
+ property :b, model: this_model_class
170
+ end
171
+ end
172
+ }
173
+
174
+ it "raises an infinte regress error when property_definitions are resolved" do
175
+ expect{ subclass.property_definitions }.to raise_exception( SonJay::InfiniteRegressError )
176
+ end
177
+ end
178
+
136
179
  end
@@ -1,6 +1,10 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe SonJay::ValueArray do
4
+ it "is array-like" do
5
+ expect( subject.to_ary ).to eq( subject )
6
+ expect( subject << 1 << 2 ).to eq( [1, 2] )
7
+ end
4
8
 
5
9
  describe '#sonj_content' do
6
10
  it "returns the instance itself" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: son_jay
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.alpha
4
+ version: 0.1.1.alpha
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steve Jorgensen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-11 00:00:00.000000000 Z
11
+ date: 2014-04-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -88,13 +88,16 @@ files:
88
88
  - features/step_definitions/model_steps.rb
89
89
  - features/support/env.rb
90
90
  - lib/son_jay.rb
91
+ - lib/son_jay/acts_as_model.rb
91
92
  - lib/son_jay/model_array.rb
92
93
  - lib/son_jay/object_model.rb
93
94
  - lib/son_jay/object_model/properties.rb
95
+ - lib/son_jay/object_model/properties_definer.rb
94
96
  - lib/son_jay/object_model/property_definition.rb
95
97
  - lib/son_jay/value_array.rb
96
98
  - lib/son_jay/version.rb
97
99
  - son_jay.gemspec
100
+ - spec/acts_as_model_spec.rb
98
101
  - spec/model_array_spec.rb
99
102
  - spec/object_model/properties_spec.rb
100
103
  - spec/object_model/property_definition_spec.rb
@@ -133,6 +136,7 @@ test_files:
133
136
  - features/step_definitions/json_serialization_steps.rb
134
137
  - features/step_definitions/model_steps.rb
135
138
  - features/support/env.rb
139
+ - spec/acts_as_model_spec.rb
136
140
  - spec/model_array_spec.rb
137
141
  - spec/object_model/properties_spec.rb
138
142
  - spec/object_model/property_definition_spec.rb