son_jay 0.2.0.alpha → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZGM2ZmI4ODc5NjU4OTk3NmE0MDQxN2M3NDJlY2IyZjc5MjNmYzBjNg==
4
+ NDg5ODk2NGI0ZTU2MTc4ZjdjMzEzNWNiMjY2OTJmMjNkNmVhOTNlYw==
5
5
  data.tar.gz: !binary |-
6
- YzliZjY4NDYyNGI0YjFlNzQ0NTE1OTBlMDM5YzQ4NmVkOTI5M2VhZg==
6
+ MzgwYWExZDQ4YTc2MDlhNGQ1NTkyNDgxOWVjMmFjNDRkYzgxZmJkZg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ZTkyOTIzNmE5Y2U1MWIyOTE4YTJmMGFjODczY2ZiMDZiMTUxYjQ3MTdiYTY1
10
- YzVmZDgzZjkzNGYzZmVjY2E1ZWY0YTYzYjZkYjU1NDE3NDUxZmNiOWZiMzA2
11
- YTc0YmNkZGFkZTllYmViNTBiNzk5YTRmOTYyYzRiMDFlZGEyNzg=
9
+ YzFlNjQ5MDEwYWEyN2M3OGE1NmJlNDFlZWMwMDc2NjM3ZjkzZTBmMDg1Zjc5
10
+ M2FjMmQ1ODk4NjlkYzA4OGExYzU2ZmNmNzc3ZjM3MmJjZmZiZWMzMzJiYWYy
11
+ YTdmY2E5MGQ0YjJlOTUwZGZmZDU4ZGJlMTFhZDRiNTRhYTZiMWU=
12
12
  data.tar.gz: !binary |-
13
- OTM2OGM2OTY1MDI4YWY5YzZiODc4Y2FhZTAyZTA2N2M2NzgyNjU2MzQ5MTIy
14
- M2M5NGVjNzAwNDQ0ZGIxMmExN2QzYWFiMjAzYzdlNTViMjRhYTI3MTg4ZWFl
15
- YmVjOTM0Nzc2NjdmZjE4NGZjMDkwZWM4OTc5MzdiOGIyYTkwNzY=
13
+ NzNjYTZkMGQ4ZThmZTU2M2QyZDVlMmJmZjFjYTc3OTIyZDRmZDA5OGQ5YTMw
14
+ YzFlMDk1ZDBiNDEyYTQ4NDdlZGMzZjM0NzNkZGM3MDM2MjZhMTA2N2ZiMWU0
15
+ NmQyZmFkMDY2OTJlZWFkYWUxODgzY2NjNmRiNjQ0ZjBmYjQyOTI=
data/.simplecov ADDED
@@ -0,0 +1,5 @@
1
+ proj_root = File.dirname(__FILE__)
2
+ SimpleCov.start do
3
+ root File.join( proj_root, 'lib' )
4
+ coverage_dir File.join( proj_root, 'coverage' )
5
+ end
data/Rakefile CHANGED
@@ -1,12 +1,22 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rspec/core/rake_task"
3
3
 
4
-
5
- desc "Run all specs and features"
6
- task all_tests: %w[spec cucumber cucumber:wip]
4
+ desc "Run all specs/features with and w/o ActiveSupport loaded"
5
+ task :all_tests do
6
+ system 'rake all_tests_without_active_support'
7
+ next unless $?.exitstatus == 0
8
+ system 'rake all_tests_with_active_support'
9
+ end
7
10
 
8
11
  task :default => :all_tests
9
12
 
13
+ desc "Run all specs and features w/o ActiveSupport loaded"
14
+ task all_tests_without_active_support: %w[all_test_types]
15
+
16
+ desc "Run all specs and features with ActiveSupport loaded"
17
+ task all_tests_with_active_support: %w[load_active_support all_test_types]
18
+
19
+ task all_test_types: %w[spec cucumber cucumber:wip]
10
20
 
11
21
  RSpec::Core::RakeTask.new(:spec)
12
22
 
@@ -21,3 +31,7 @@ namespace :cucumber do
21
31
  t.profile = 'wip'
22
32
  end
23
33
  end
34
+
35
+ task :load_active_support do
36
+ ENV['LOAD_ACTIVE_SUPPORT'] = '1'
37
+ end
@@ -0,0 +1,6 @@
1
+ When(/^a new SonJay model instance is built from domain object data as:$/) do |code|
2
+ object = context_data[:object]
3
+ instance = nil
4
+ context_module.module_eval code
5
+ context_data[:instance] = instance
6
+ end
@@ -0,0 +1,9 @@
1
+ When(/^data is disseminated to the domain object as:$/) do |code|
2
+ instance = context_data[:instance]
3
+ object = context_data[:object]
4
+ context_module.module_eval code
5
+ end
6
+
7
+ Then(/^the domain object attributes are as follows:$/) do |table|
8
+ object_attributes_match_table! context_data[:object], table
9
+ end
@@ -12,15 +12,5 @@ When(/^the JSON is parsed to a model instance as:$/) do |code|
12
12
  end
13
13
 
14
14
  Then(/^the instance attributes are as follows:$/) do |table|
15
- row_pairs = table.raw.each_slice(2)
16
- attribute_exprs = row_pairs.map( &:first ).reduce( :+ )
17
- expected_exprs = row_pairs.map( &:last ).reduce( :+ )
18
-
19
- instance = context_data[:instance]
20
- actuals = attribute_exprs .map{ |expr| eval( "instance.#{expr}" ) }
21
- expecteds = expected_exprs .map{ |expr| eval( expr ) }
22
-
23
- actual_hash = Hash[ attribute_exprs.zip( actuals ) ]
24
- expected_hash = Hash[ attribute_exprs.zip( expecteds ) ]
25
- expect( actual_hash ).to eq( expected_hash )
15
+ object_attributes_match_table! context_data[:instance], table
26
16
  end
@@ -1,3 +1,9 @@
1
- Given(/^an object model defined as:$/) do |code|
1
+ Given(/^a.* object model defined as:$/) do |code|
2
2
  context_module.module_eval code
3
3
  end
4
+
5
+ Given(/^a domain object(?: is)? created.* as:$/) do |code|
6
+ object = nil
7
+ context_module.module_eval code
8
+ context_data[:object] = object
9
+ end
@@ -0,0 +1,12 @@
1
+ def object_attributes_match_table!(obj, table)
2
+ row_pairs = table.raw.each_slice(2)
3
+ attribute_exprs = row_pairs.map( &:first ).reduce( :+ )
4
+ expected_exprs = row_pairs.map( &:last ).reduce( :+ )
5
+
6
+ actuals = attribute_exprs .map{ |expr| eval( "obj.#{expr}" ) }
7
+ expecteds = expected_exprs .map{ |expr| eval( expr ) }
8
+
9
+ actual_hash = Hash[ attribute_exprs.zip( actuals ) ]
10
+ expected_hash = Hash[ attribute_exprs.zip( expecteds ) ]
11
+ expect( actual_hash ).to eq( expected_hash )
12
+ end
@@ -1,4 +1,18 @@
1
- require_relative('../../lib/son_jay')
1
+ with_active_support = !!ENV['LOAD_ACTIVE_SUPPORT']
2
+
3
+ if with_active_support
4
+ gem 'activesupport'
5
+ require 'active_support/all'
6
+ puts 'ActiveSupport loaded'
7
+ end
8
+
9
+ gem 'simplecov'
10
+ require 'simplecov'
11
+ cmd_active_supp_qual = with_active_support ? 'with' : 'without'
12
+ SimpleCov.command_name "cucumber:#{cmd_active_supp_qual}_active_support"
13
+
14
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
15
+ require 'son_jay'
2
16
 
3
17
  module SonJayFeatureSupport
4
18
  def context_data
@@ -16,7 +16,7 @@ module SonJay
16
16
 
17
17
  def array_class
18
18
  @array_class ||= begin
19
- klass = SonJay::ModelArray(self)
19
+ klass = SonJay::ModelArray( self )
20
20
  const_set :Array, klass
21
21
  end
22
22
  end
@@ -3,6 +3,7 @@ require 'forwardable'
3
3
  module SonJay
4
4
  class ObjectModel
5
5
  class Properties
6
+
6
7
  class NameError < KeyError
7
8
  def initialize(name)
8
9
  super "No such property name as %s" % name.inspect
@@ -26,8 +27,6 @@ module SonJay
26
27
  :values ,
27
28
  ]
28
29
 
29
- def_delegator :@data, :has_key?, :has_name?
30
-
31
30
  def [](name)
32
31
  name = "#{name}"
33
32
  @data.fetch(name)
@@ -49,20 +48,17 @@ module SonJay
49
48
 
50
49
  def load_property(name, value)
51
50
  name = "#{name}"
52
- return unless @data.has_key?(name)
53
- if @model_properties.include?(name)
51
+ return unless @data.has_key?( name )
52
+ if @model_properties.include?( name )
54
53
  @data[name].sonj_content.load_data value
55
54
  else
56
55
  @data[name] = value
57
56
  end
58
57
  end
59
58
 
60
- def has_name?(name)
61
- @data.has_key?( "#{name}" )
62
- end
63
-
64
- def to_json(*args)
65
- @data.to_json(*args)
59
+ def to_json(options = ::JSON::State.new)
60
+ options = ::JSON::State.new(options) unless options.kind_of?(::JSON::State)
61
+ @data.to_json( options )
66
62
  end
67
63
 
68
64
  end
@@ -6,7 +6,7 @@ module SonJay
6
6
 
7
7
  def initialize(name, instruction = nil)
8
8
  @name = name
9
- @model_class = model_class_for_instruction(instruction)
9
+ @model_class = model_class_for_instruction( instruction )
10
10
  end
11
11
 
12
12
  private
@@ -14,8 +14,8 @@ module SonJay
14
14
  def model_class_for_instruction(instruction)
15
15
  if instruction.nil?
16
16
  nil
17
- elsif instruction.respond_to?(:to_ary)
18
- array_model_class(instruction)
17
+ elsif instruction.respond_to?( :to_ary )
18
+ array_model_class( instruction )
19
19
  elsif instruction.respond_to?( :new )
20
20
  instruction
21
21
  end
@@ -24,7 +24,7 @@ module SonJay
24
24
  private
25
25
 
26
26
  def array_model_class(instruction)
27
- return instruction unless instruction.respond_to?(:to_ary)
27
+ return instruction unless instruction.respond_to?( :to_ary )
28
28
  return SonJay::ValueArray if instruction == []
29
29
 
30
30
  sub_instruction = instruction.first
@@ -7,6 +7,17 @@ module SonJay
7
7
  class ObjectModel
8
8
  include ActsAsModel
9
9
 
10
+ attr_reader :sonj_content
11
+
12
+ def initialize
13
+ definitions = self.class.property_definitions
14
+ @sonj_content = ObjectModel::Properties.new( definitions )
15
+ end
16
+
17
+ def to_json(*args)
18
+ sonj_content.to_json( *args )
19
+ end
20
+
10
21
  class << self
11
22
 
12
23
  def properties(&property_initializations)
@@ -19,7 +30,7 @@ module SonJay
19
30
 
20
31
  definitions = []
21
32
 
22
- definer = PropertiesDefiner.new(definitions)
33
+ definer = PropertiesDefiner.new( definitions )
23
34
  definer.instance_eval &@property_initializations
24
35
  @property_definitions = definitions
25
36
 
@@ -42,26 +53,15 @@ module SonJay
42
53
  raise InfiniteRegressError if dependants.include?(self)
43
54
  dependants << self
44
55
  hard_model_dependencies.each do |d|
45
- next unless d.respond_to?(:validate_model_dependencies!, true)
56
+ next unless d.respond_to?( :validate_model_dependencies!, true )
46
57
  d.send :validate_model_dependencies!, dependants
47
58
  end
48
59
  end
49
60
 
50
61
  def hard_model_dependencies
51
- property_definitions.map(&:model_class).compact.uniq
62
+ property_definitions.map( &:model_class ).compact.uniq
52
63
  end
53
64
  end
54
65
 
55
- attr_reader :sonj_content
56
-
57
- def initialize
58
- definitions = self.class.property_definitions
59
- @sonj_content = ObjectModel::Properties.new( definitions )
60
- end
61
-
62
- def to_json(*args)
63
- sonj_content.to_json(*args)
64
- end
65
-
66
66
  end
67
67
  end
@@ -6,6 +6,11 @@ module SonJay
6
6
  self
7
7
  end
8
8
 
9
+ def to_json(options = ::JSON::State.new)
10
+ options = ::JSON::State.new(options) unless options.kind_of?(::JSON::State)
11
+ super options
12
+ end
13
+
9
14
  alias load_data replace
10
15
 
11
16
  end
@@ -1,3 +1,3 @@
1
1
  module SonJay
2
- VERSION = "0.2.0.alpha"
2
+ VERSION = "0.3.0"
3
3
  end
data/son_jay.gemspec CHANGED
@@ -19,7 +19,9 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_development_dependency "bundler", "~> 1.5"
22
+ spec.add_development_dependency "simplecov"
22
23
  spec.add_development_dependency "rake"
23
24
  spec.add_development_dependency "rspec"
24
25
  spec.add_development_dependency "cucumber"
26
+ spec.add_development_dependency "activesupport"
25
27
  end
@@ -20,7 +20,7 @@ describe SonJay::ModelArray do
20
20
  } }
21
21
  let( :entry_class ) { Class.new do
22
22
  class Content
23
- def initialize( entry ) ; @entry = entry ; end
23
+ def initialize(entry) ; @entry = entry ; end
24
24
  def load_data(data) ; @entry.loaded_data = data ; end
25
25
  end
26
26
 
@@ -65,5 +65,11 @@ describe SonJay::ModelArray do
65
65
  expect( instance[1].loaded_data ).to eq( 'entry 1 data' )
66
66
  end
67
67
  end
68
+
69
+ describe '#sonj_content' do
70
+ it "returns the model array" do
71
+ expect( subject.sonj_content ).to equal( subject )
72
+ end
73
+ end
68
74
  end
69
75
  end
@@ -2,133 +2,157 @@ require 'spec_helper'
2
2
 
3
3
  describe SonJay::ObjectModel do
4
4
 
5
- describe "a subclass that defines value properties" do
5
+ describe "a subclass that defines (value and modeled-object) properties" do
6
+
7
+ let( :model_class ) { subject_module::RootModel }
8
+ let( :model_instance ) { model_class.new }
9
+ let( :detail_xy_class ) { subject_module::DetailXY }
10
+
11
+ let( :subject_module ) {
12
+ mod = Module.new
13
+ mod::M = mod
14
+
15
+ module mod::M
16
+
17
+ class RootModel < SonJay::ObjectModel
18
+ class << self
19
+ def properties_block_called_count
20
+ @properties_block_called_count ||= 0
21
+ end
22
+ attr_writer :properties_block_called_count
23
+ end
24
+
25
+ properties do
26
+ RootModel.properties_block_called_count += 1
27
+ property :aaa
28
+ property :bbb
29
+ property :detail_xy , model: DetailXY
30
+ property :detail_z , model: DetailZ
31
+ end
32
+ end
33
+
34
+ class DetailXY < SonJay::ObjectModel
35
+ properties do
36
+ property :xxx
37
+ property :yyy
38
+ end
39
+ end
40
+
41
+ class DetailZ < SonJay::ObjectModel
42
+ properties do
43
+ property :zzz
44
+ end
45
+ end
46
+
47
+ end
48
+
49
+ mod
50
+ }
51
+
52
+ it "does not immediately invoke its properties block when declared" do
53
+ expect( model_class.properties_block_called_count ).
54
+ to eq( 0 )
55
+ end
6
56
 
7
57
  describe '::array_class' do
8
58
  it "returns a model-array subclass for entries of this type" do
9
- array_class = subclass.array_class
10
- puts array_class.ancestors
59
+ array_class = model_class.array_class
11
60
  expect( array_class.ancestors ).to include( SonJay::ModelArray )
12
- expect( array_class.entry_class ).to eq( subclass )
61
+ expect( array_class.entry_class ).to eq( model_class )
13
62
  end
14
63
  end
15
64
 
16
- let( :subclass ) {
17
- Class.new(described_class) do
18
- properties do
19
- property :abc
20
- property :xyz
21
- end
65
+ describe "#sonj_content" do
66
+ let( :sonj_content ) { model_instance.sonj_content }
67
+
68
+ it "has number of entries equal to number of defined properties" do
69
+ expect( sonj_content.length ).to eq( 4 )
22
70
  end
23
- }
24
71
 
25
- describe "#sonj_content" do
26
- it "has name-indexed settable/gettable values for defined properties" do
27
- instance = subclass.new
72
+ it "has name-indexed settable/gettable value properties by string or symbol" do
73
+ sonj_content[ :aaa ] = 1
74
+ sonj_content[ 'bbb' ] = 'XYZ'
75
+
76
+ expect( sonj_content[ 'aaa' ] ).to eq( 1 )
77
+ expect( sonj_content[ :bbb ] ).to eq( 'XYZ' )
78
+ end
28
79
 
29
- content = instance.sonj_content
30
- expect( content.length ).to eq( 2 )
80
+ it "has nil defaults for value properties" do
81
+ expect( sonj_content[ 'aaa' ] ).to be_nil
82
+ expect( sonj_content[ :bbb ] ).to be_nil
83
+ end
31
84
 
32
- content[:abc] = 1
33
- content[:xyz] = 'XYZ'
85
+ it "has name-indexed gettable values for defined modeled-object properties by string or symbol" do
86
+ expect( sonj_content['detail_xy'] ).
87
+ to be_kind_of( subject_module::DetailXY )
88
+ expect( sonj_content[:detail_z] ).
89
+ to be_kind_of( subject_module::DetailZ )
90
+ end
34
91
 
35
- expect( content[:abc] ).to eq( 1 )
36
- expect( content[:xyz] ).to eq( 'XYZ' )
92
+ it "rejects access to an undefined property" do
93
+ expect{ sonj_content['qq'] }.to raise_exception(
94
+ described_class::Properties::NameError
95
+ )
37
96
  end
97
+
38
98
  end
39
99
 
40
100
  it "has direct property accessor methods for each property" do
41
- instance = subclass.new
42
- instance.abc, instance.xyz = 11, 22
43
-
44
- expect( [instance.abc, instance.xyz] ).to eq( [11, 22] )
101
+ model_instance.aaa, model_instance.bbb = 11, 22
102
+ expect( [model_instance.aaa, model_instance.bbb] ).to eq( [11, 22] )
103
+ expect( model_instance.detail_xy ).
104
+ to be_kind_of( subject_module::DetailXY )
105
+ expect( model_instance.detail_z ).
106
+ to be_kind_of( subject_module::DetailZ )
45
107
  end
46
108
 
47
- it "serializes to a JSON object representation w/ property values" do
48
- instance = subclass.new
49
- instance.abc, instance.xyz = 'ABC', nil
109
+ it "serializes to a JSON object representation w/ value properties" do
110
+ instance = detail_xy_class.new
111
+ instance.xxx, instance.yyy = 'ABC', nil
50
112
 
51
113
  actual_json = instance.to_json
52
114
 
53
115
  actual_data = JSON.parse( actual_json)
54
- expected_data = {'abc' => 'ABC', 'xyz' => nil}
116
+ expected_data = {'xxx' => 'ABC', 'yyy' => nil}
55
117
  expect( actual_data ).to eq( expected_data )
56
118
  end
57
119
 
58
- describe '::parse_json' do
59
- it "creates an instance with properties filled in from parsed JSON" do
60
- json = <<-JSON
61
- {
62
- "abc": 123 ,
63
- "xyz": "XYZ"
64
- }
65
- JSON
66
-
67
- instance = subclass.parse_json( json )
120
+ it "serializes to a JSON object representation w/ value and object properties" do
121
+ model_instance.aaa = 1
122
+ model_instance.bbb = 2
123
+ model_instance.detail_xy.xxx = 11
124
+ model_instance.detail_xy.yyy = 12
125
+ model_instance.detail_z.zzz = 21
68
126
 
69
- expect( instance.abc ).to eq( 123 )
70
- expect( instance.xyz ).to eq( 'XYZ' )
71
- end
72
- end
127
+ actual_json = model_instance.to_json
73
128
 
74
- end
75
-
76
- describe "a subclass that defines value and modeled-object properties" do
77
- let( :subclass ) {
78
- dmc_1, dmc_2 = detail_model_class_1, detail_model_class_2
79
- pbcs = property_block_calls
80
- Class.new(described_class) do
81
- properties do
82
- pbcs << 1
83
- property :a
84
- property :obj_1, model: dmc_1
85
- property :obj_2, model: dmc_2
86
- end
87
- end
88
- }
89
-
90
- let( :property_block_calls ) { [] }
91
-
92
- let( :detail_model_class_1 ) {
93
- Class.new(described_class) do
94
- properties do
95
- property :aaa
96
- property :bbb
97
- end
98
- end
99
- }
100
-
101
- let( :detail_model_class_2 ) {
102
- Class.new(described_class) do
103
- properties do
104
- property :ccc
105
- end
106
- end
107
- }
108
-
109
- it "does not immediately invoke its properties block when declared" do
110
- _ = subclass
111
- expect( property_block_calls ).to be_empty
112
- end
113
-
114
- describe "#sonj_content" do
115
- it "has an entry for each defined property" do
116
- content = subclass.new.sonj_content
117
- expect( content.length ).to eq( 3 )
118
- end
129
+ actual_data = JSON.parse( actual_json)
130
+ expected_data = {
131
+ 'aaa' => 1 ,
132
+ 'bbb' => 2 ,
133
+ 'detail_xy' => { 'xxx' => 11, 'yyy' => 12 } ,
134
+ 'detail_z' => { 'zzz' => 21 } ,
135
+ }
136
+ expect( actual_data ).to eq( expected_data )
119
137
  end
120
138
 
121
- describe "#sonj_content" do
122
- it "has name-indexed settable/gettable values for defined value properties" do
123
- content = subclass.new.sonj_content
124
- content[:a] = 1
125
- expect( content[:a] ).to eq( 1 )
126
- end
127
-
128
- it "has name-indexed gettable values for defined modeled-object properties" do
129
- content = subclass.new.sonj_content
130
- expect( content[:obj_1] ).to be_kind_of( detail_model_class_1 )
131
- end
139
+ it "parses from JSON to an instance with properties filled in" do
140
+ json = <<-JSON
141
+ {
142
+ "aaa": 123 ,
143
+ "bbb": "XYZ" ,
144
+ "detail_xy": { "xxx": "x", "yyy": "y" } ,
145
+ "detail_z": { "zzz": "z" }
146
+ }
147
+ JSON
148
+
149
+ instance = model_class.parse_json( json )
150
+
151
+ expect( instance.aaa ).to eq( 123 )
152
+ expect( instance.bbb ).to eq('XYZ')
153
+ expect( instance.detail_xy.xxx ).to eq('x')
154
+ expect( instance.detail_xy.yyy ).to eq('y')
155
+ expect( instance.detail_z.zzz ).to eq('z')
132
156
  end
133
157
 
134
158
  end
@@ -156,7 +180,8 @@ describe SonJay::ObjectModel do
156
180
  }
157
181
 
158
182
  it "raises an infinte regress error when property_definitions are resolved" do
159
- expect{ subclass.property_definitions }.to raise_exception( SonJay::InfiniteRegressError )
183
+ expect{ subclass.property_definitions }.
184
+ to raise_exception( SonJay::InfiniteRegressError )
160
185
  end
161
186
  end
162
187
 
@@ -172,7 +197,8 @@ describe SonJay::ObjectModel do
172
197
  }
173
198
 
174
199
  it "raises an infinte regress error when property_definitions are resolved" do
175
- expect{ subclass.property_definitions }.to raise_exception( SonJay::InfiniteRegressError )
200
+ expect{ subclass.property_definitions }.
201
+ to raise_exception( SonJay::InfiniteRegressError )
176
202
  end
177
203
  end
178
204
 
data/spec/spec_helper.rb CHANGED
@@ -1,2 +1,16 @@
1
+ with_active_support = !!ENV['LOAD_ACTIVE_SUPPORT']
2
+
3
+ if with_active_support
4
+ gem 'activesupport'
5
+ require 'active_support/all'
6
+ puts 'ActiveSupport loaded'
7
+ end
8
+
9
+ gem 'simplecov'
10
+ require 'simplecov'
11
+ cmd_active_supp_qual = with_active_support ? 'with' : 'without'
12
+ SimpleCov.command_name "rspec:#{cmd_active_supp_qual}_active_support"
13
+
1
14
  $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
15
+
2
16
  require 'son_jay'
@@ -22,4 +22,16 @@ describe SonJay::ValueArray do
22
22
  expect( subject.entries ).to eq( [7, 8, 9] )
23
23
  end
24
24
  end
25
+
26
+ describe '#to_json' do
27
+ it "returns a JSON representation of the array w/ values" do
28
+ subject.replace( [1, 2, 'three'] )
29
+
30
+ actual_json = subject.to_json
31
+
32
+ parsed_json = JSON.parse( actual_json )
33
+ expect( parsed_json ).to eq( [1, 2, 'three'] )
34
+ end
35
+ end
36
+
25
37
  end
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.2.0.alpha
4
+ version: 0.3.0
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-18 00:00:00.000000000 Z
11
+ date: 2014-05-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ~>
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: simplecov
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rake
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +80,20 @@ dependencies:
66
80
  - - ! '>='
67
81
  - !ruby/object:Gem::Version
68
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: activesupport
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
69
97
  description: Symmetrical transformation between structured data and JSON
70
98
  email:
71
99
  - stevej@stevej.name
@@ -75,6 +103,7 @@ extra_rdoc_files: []
75
103
  files:
76
104
  - .gitignore
77
105
  - .rspec
106
+ - .simplecov
78
107
  - .travis.yml
79
108
  - Gemfile
80
109
  - LICENSE.txt
@@ -83,9 +112,12 @@ files:
83
112
  - cucumber.yml
84
113
  - features/json_parsing.feature
85
114
  - features/json_serialization.feature
115
+ - features/step_definitions/data_staging_steps.rb
116
+ - features/step_definitions/data_unloading_steps.rb
86
117
  - features/step_definitions/json_parsing_steps.rb
87
118
  - features/step_definitions/json_serialization_steps.rb
88
119
  - features/step_definitions/model_steps.rb
120
+ - features/support/attribute_value_verification.rb
89
121
  - features/support/env.rb
90
122
  - lib/son_jay.rb
91
123
  - lib/son_jay/acts_as_model.rb
@@ -99,7 +131,6 @@ files:
99
131
  - son_jay.gemspec
100
132
  - spec/acts_as_model_spec.rb
101
133
  - spec/model_array_spec.rb
102
- - spec/object_model/properties_spec.rb
103
134
  - spec/object_model/property_definition_spec.rb
104
135
  - spec/object_model_spec.rb
105
136
  - spec/son_jay_spec.rb
@@ -120,9 +151,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
120
151
  version: '0'
121
152
  required_rubygems_version: !ruby/object:Gem::Requirement
122
153
  requirements:
123
- - - ! '>'
154
+ - - ! '>='
124
155
  - !ruby/object:Gem::Version
125
- version: 1.3.1
156
+ version: '0'
126
157
  requirements: []
127
158
  rubyforge_project:
128
159
  rubygems_version: 2.2.2
@@ -132,13 +163,15 @@ summary: Symmetrical transformation between structured data and JSON
132
163
  test_files:
133
164
  - features/json_parsing.feature
134
165
  - features/json_serialization.feature
166
+ - features/step_definitions/data_staging_steps.rb
167
+ - features/step_definitions/data_unloading_steps.rb
135
168
  - features/step_definitions/json_parsing_steps.rb
136
169
  - features/step_definitions/json_serialization_steps.rb
137
170
  - features/step_definitions/model_steps.rb
171
+ - features/support/attribute_value_verification.rb
138
172
  - features/support/env.rb
139
173
  - spec/acts_as_model_spec.rb
140
174
  - spec/model_array_spec.rb
141
- - spec/object_model/properties_spec.rb
142
175
  - spec/object_model/property_definition_spec.rb
143
176
  - spec/object_model_spec.rb
144
177
  - spec/son_jay_spec.rb
@@ -1,125 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe SonJay::ObjectModel::Properties do
4
- subject{
5
- described_class.new( [
6
- SonJay::ObjectModel::PropertyDefinition.new( 'aaa' ) ,
7
- SonJay::ObjectModel::PropertyDefinition.new( 'bbb' ) ,
8
- SonJay::ObjectModel::PropertyDefinition.new( 'ccc' ) ,
9
- SonJay::ObjectModel::PropertyDefinition.new( 'ddd', ddd_model_class ) ,
10
- ] )
11
- }
12
-
13
- let( :ddd_model_class ) { Class.new do
14
- class Content
15
- def initialize(model) ; @model = model ; end
16
- def load_data(data) ; @model.class.loaded_data = data ; end
17
- end
18
- class << self ; attr_accessor :loaded_data ; end
19
- def to_json(*) ; '"ddd..."' ; end
20
- def sonj_content ; Content.new(self) ; end
21
- end }
22
-
23
- it "has an entry for each property name specified during initialization" do
24
- expect( subject.length ).to eq( 4 )
25
- expect( subject ).to have_name('aaa')
26
- expect( subject ).to have_name('bbb')
27
- expect( subject ).to have_name('ccc')
28
- expect( subject ).to have_name('ddd')
29
- end
30
-
31
- describe "property value access by name" do
32
- it "reads nil by default for an existing value property" do
33
- expect( subject['aaa'] ).to be_nil
34
- end
35
-
36
- it "writes and reads existing value properties" do
37
- subject['bbb'] = 10
38
- subject['aaa'] = 11
39
-
40
- expect( subject['bbb'] ).to eq( 10 )
41
- expect( subject['aaa'] ).to eq( 11 )
42
- end
43
-
44
- it "refuses to read a non-existent property" do
45
- expect{ subject['abc'] }.to raise_exception( described_class::NameError )
46
- end
47
-
48
- it "refuses to write a non-existent property" do
49
- expect{ subject['abc'] = 1 }.to raise_exception( described_class::NameError )
50
- end
51
-
52
- it "allows reading/writing by symbol or string for property name" do
53
- subject['aaa'] = 10
54
- subject[:bbb] = 11
55
-
56
- expect( subject[:aaa] ).to eq( 10 )
57
- expect( subject['bbb'] ).to eq( 11 )
58
- end
59
-
60
- it "reads an instance of the model for a modeled attribute" do
61
- expect( subject[:ddd] ).to be_kind_of( ddd_model_class )
62
- end
63
- end
64
-
65
- describe "#to_json" do
66
- it "returns a JSON object representation with attribute values" do
67
- subject['aaa'] = 'abc'
68
- subject['ccc'] = true
69
-
70
- actual_json = subject.to_json
71
-
72
- actual_data = JSON.parse( actual_json )
73
- expected_data = {
74
- 'aaa' => 'abc' ,
75
- 'bbb' => nil ,
76
- 'ccc' => true ,
77
- 'ddd' => "ddd..." ,
78
- }
79
- expect( actual_data ).to eq( expected_data )
80
- end
81
- end
82
-
83
- describe "load_property" do
84
- it "writes to existing value properties" do
85
- subject.load_property( 'bbb', 11 )
86
- subject.load_property( 'ccc', 12 )
87
-
88
- expect( subject['bbb'] ).to eq( 11 )
89
- expect( subject['ccc'] ).to eq( 12 )
90
- end
91
-
92
- it "loads data into existing modeled properties" do
93
- subject.load_property( 'ddd', 'some data' )
94
- expect( ddd_model_class.loaded_data ).to eq( 'some data' )
95
- end
96
-
97
- it "ignores attempts to write to non-existent properties" do
98
- expect{ subject.load_property('xx', 10) }.
99
- not_to change{ subject.length }
100
- end
101
-
102
- it "allows string or symbol for property name" do
103
- subject.load_property( 'aaa' , 888 )
104
- subject.load_property( :ccc , 999 )
105
-
106
- expect( subject['aaa'] ).to eq( 888 )
107
- expect( subject['ccc'] ).to eq( 999 )
108
- end
109
- end
110
-
111
- describe "load_data" do
112
- it "populates property values from hash entries" do
113
- subject.load_data({
114
- 'bbb' => 'abc' ,
115
- 'ccc' => false ,
116
- 'ddd' => 'something...' ,
117
- })
118
- expect( subject['aaa'] ).to be_nil
119
- expect( subject['bbb'] ).to eq( 'abc' )
120
- expect( subject['ccc'] ).to eq( false )
121
- expect( ddd_model_class.loaded_data ).to eq( 'something...' )
122
- end
123
- end
124
-
125
- end