son_jay 0.2.0.alpha → 0.3.0

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