defaultable 0.0.4 → 0.0.5

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,32 @@
1
+ require 'active_support/core_ext/hash'
2
+
3
+ module Defaultable
4
+ class Registry
5
+ def initialize
6
+ @table = {}
7
+ end
8
+
9
+ def add(key, value)
10
+ @table[key] = value
11
+ end
12
+
13
+ def as_hash
14
+ @table.inject({}) do |hash, (key, val)|
15
+ if val.kind_of?(Defaultable::Settings)
16
+ val = val.registry.as_hash
17
+ else
18
+ val
19
+ end
20
+
21
+ hash[key] = val
22
+ hash
23
+ end
24
+ end
25
+
26
+ # def diff(defaults)
27
+ # settings = self.as_hash
28
+
29
+ # settings.diff(defaults)
30
+ # end
31
+ end
32
+ end
@@ -5,7 +5,7 @@ module Defaultable
5
5
  # Called to deserialize data to ruby object.
6
6
  def load(data)
7
7
  if data
8
- obj = YAML.load(data)
8
+ obj = raw_load(data)
9
9
 
10
10
  raise TypeError, "Deserialized object is not of type #{self.class.settings_class.name}. Got #{obj.class}" unless obj.is_a?(self.class.settings_class)
11
11
 
@@ -19,7 +19,13 @@ module Defaultable
19
19
  # Called to convert from ruby object to serialized data.
20
20
  def dump(obj)
21
21
  raise TypeError, "Serialization failed: Object is not of type #{self.class.settings_class.name}." unless obj.is_a?(self.class.settings_class)
22
- obj.to_yaml if obj
22
+
23
+ # We need to use the registry because we don't want to store defaults that weren't overwritten
24
+ obj.class.new(obj.registry.as_hash).to_yaml if obj
25
+ end
26
+
27
+ def raw_load(data)
28
+ YAML.load(data)
23
29
  end
24
30
  end
25
31
  end
@@ -1,17 +1,22 @@
1
1
  module Defaultable
2
2
  class Settings
3
3
  class_attribute :defaults
4
- attr_accessor :root_key, :parent
4
+ attr_accessor :registry_enabled
5
+ attr_reader :registry
5
6
 
6
- def initialize(hash=nil, root_key=nil, parent=nil, skip_defaults=false)
7
- @table = {}
7
+ attr_accessor :parent, :root_key
8
8
 
9
- self.root_key = root_key if root_key
10
- self.parent = parent if parent
9
+ def initialize(hash=nil, skip_defaults=false, enable_registry=true)
10
+ @table = {}
11
+ @registry = Registry.new
11
12
 
12
13
  if !skip_defaults && !self.class.defaults.nil?
14
+ self.registry_enabled = false
13
15
  recursive_hash_assignment self.class.defaults
14
16
  end
17
+
18
+ # Enable the registry so we know what actually was set beyond defaults
19
+ self.registry_enabled = enable_registry
15
20
 
16
21
  if !hash.nil? && hash.kind_of?(Hash)
17
22
  recursive_hash_assignment hash
@@ -29,9 +34,18 @@ module Defaultable
29
34
  key = message.to_s.gsub(/=$/, '')
30
35
  value = args.first
31
36
 
37
+ if self.registry_enabled
38
+ self.registry.add(key, value)
39
+ end
40
+
32
41
  if value.kind_of?(Defaultable::Settings)
33
- value.parent = self
34
- value.root_key = key
42
+ value.root_key = key
43
+ value.parent = self
44
+ end
45
+
46
+ if self.parent && self.parent.registry_enabled
47
+ self.registry.add(key, value)
48
+ self.parent.registry.add(self.root_key, self.class.new(self.registry.as_hash))
35
49
  end
36
50
 
37
51
  @table[key] = value
@@ -51,10 +65,6 @@ module Defaultable
51
65
  end
52
66
  end
53
67
 
54
- def has_parent?
55
- !!self.parent
56
- end
57
-
58
68
  def recursive_hash_assignment(hash)
59
69
  hash.each do |key, value|
60
70
  if value.kind_of?(Hash)
@@ -76,7 +86,7 @@ module Defaultable
76
86
  self.send("#{key}=", hash)
77
87
  end
78
88
  else
79
- self.send("#{key}=", self.class.new(hash, key, self, true))
89
+ self.send("#{key}=", self.class.new(hash, true, self.registry_enabled))
80
90
  end
81
91
  end
82
92
 
@@ -1,3 +1,3 @@
1
1
  module Defaultable
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
data/lib/defaultable.rb CHANGED
@@ -5,4 +5,5 @@ require 'active_support/core_ext/class/attribute'
5
5
  module Defaultable
6
6
  autoload :Serialization, 'defaultable/serialization'
7
7
  autoload :Settings, 'defaultable/settings'
8
+ autoload :Registry, 'defaultable/registry'
8
9
  end
@@ -5,11 +5,6 @@ describe Defaultable::Settings do
5
5
  Defaultable::Settings.set_defaults({})
6
6
  end
7
7
 
8
- it "should not have a parent" do
9
- setting = Defaultable::Settings.new
10
- setting.has_parent?.should be_false
11
- end
12
-
13
8
  it "should initialize with a hash" do
14
9
  setting = Defaultable::Settings.new({:child => 'Bobert'})
15
10
  setting.child.should eq('Bobert')
@@ -178,4 +173,46 @@ describe Defaultable::Settings do
178
173
  setting = DummySetting.new(:movie => { :genre => 'asdf' })
179
174
  end
180
175
  end
176
+
177
+ describe Defaultable::Registry do
178
+ before(:each) do
179
+ class DummySetting < Defaultable::Settings
180
+ set_defaults :movie => {:name => 'Iron Man' }
181
+ end
182
+ end
183
+
184
+ it "should not include defaults in the registry" do
185
+ setting = DummySetting.new
186
+ setting.registry.as_hash.has_key?(:movie).should be_false
187
+ end
188
+
189
+ it "should not include defaults in the registry unless overwritten" do
190
+ setting = DummySetting.new
191
+ setting.movie = 'asdf'
192
+ setting.registry.as_hash.has_key?(:movie).should be_false
193
+ end
194
+
195
+ it "should be able to overwrite nested defaults" do
196
+ class DummySetting < Defaultable::Settings
197
+ set_defaults :movie => {:name => 'Iron Man', :genre => 'Action Adventure'}
198
+ end
199
+ setting = DummySetting.new
200
+ setting.movie.genre = 'Unable to put into mongodb gridfs'
201
+
202
+ setting.registry.as_hash['movie'].has_key?('genre').should be_true
203
+ setting.registry.as_hash['movie'].has_key?('name').should be_false
204
+ end
205
+
206
+ it "should be able to overwrite multiple nested defaults" do
207
+ class DummySetting < Defaultable::Settings
208
+ set_defaults :movie => {:name => 'Iron Man', :genre => 'Action Adventure'}
209
+ end
210
+ setting = DummySetting.new
211
+ setting.movie.genre = 'Unable to put into mongodb gridfs'
212
+ setting.movie.name = 'Independence Day'
213
+
214
+ setting.registry.as_hash['movie'].has_key?('genre').should be_true
215
+ setting.registry.as_hash['movie'].has_key?('name').should be_true
216
+ end
217
+ end
181
218
  end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ describe Defaultable::Registry do
4
+ before(:each) do
5
+ class DummySetting < Defaultable::Settings; end
6
+ end
7
+
8
+ after(:each) do
9
+ DummySetting.set_defaults Hash.new
10
+ end
11
+
12
+ it "should log settings to the registry" do
13
+ setting = DummySetting.new
14
+ setting.blah = 'asdf'
15
+
16
+ setting.registry.as_hash.should have_key('blah')
17
+ end
18
+
19
+ it "should not log defaults to the registry" do
20
+ DummySetting.set_defaults :foo => 'bar'
21
+
22
+ setting = DummySetting.new
23
+ setting.registry.as_hash.should_not have_key('foo')
24
+ end
25
+
26
+ it "should set registry values for nested attributes" do
27
+ setting = DummySetting.new(:stuff => {:bar => 'foo'})
28
+ setting.registry.as_hash['stuff'].should have_key('bar')
29
+ end
30
+
31
+ it "should not set nested attributes registry values even in nested defaults" do
32
+ DummySetting.set_defaults :values => {:foo => 'bar'}
33
+
34
+ DummySetting.new.registry.as_hash.should_not have_key('values')
35
+ end
36
+
37
+ it "should set nested attributes registry values even in nested defaults" do
38
+ DummySetting.set_defaults :values => {:foo => 'bar'}
39
+
40
+ setting = DummySetting.new(:values => {:bar => 'foo'})
41
+ setting.registry.as_hash.should have_key('values')
42
+ setting.values.bar?.should be_true
43
+ end
44
+
45
+ it "should set nested attributes registry values and retain nested defaults" do
46
+ DummySetting.set_defaults :values => {:foo => 'bar'}
47
+
48
+ setting = DummySetting.new(:values => {:bar => 'foo'})
49
+ setting.registry.as_hash.should have_key('values')
50
+ setting.values.bar?.should be_true
51
+ setting.values.foo?.should be_true
52
+ end
53
+ end
@@ -6,6 +6,10 @@ describe Defaultable::Serialization do
6
6
  Defaultable::Serialization.settings_class = DummySetting
7
7
  end
8
8
 
9
+ after(:each) do
10
+ DummySetting.set_defaults Hash.new
11
+ end
12
+
9
13
  it "should set a class for settings" do
10
14
  Defaultable::Serialization.settings_class.should eq(DummySetting)
11
15
  end
@@ -64,4 +68,42 @@ describe Defaultable::Serialization do
64
68
  unserialized = encoder.load(serialized)
65
69
  unserialized.bobby?.should be_true
66
70
  end
71
+
72
+ it "should not serialize defaults that didn't get overwritten" do
73
+ encoder = Defaultable::Serialization.new
74
+ settings = DummySetting.new
75
+
76
+ settings.foo = 'bar'
77
+ serialized = encoder.dump(settings)
78
+
79
+ DummySetting.set_defaults :bobby => 'tables'
80
+
81
+ unserialized = encoder.raw_load(serialized)
82
+ unserialized.bobby?.should be_false
83
+ end
84
+
85
+ it "should not serialize nested defaults that didn't get overwritten" do
86
+ encoder = Defaultable::Serialization.new
87
+ settings = DummySetting.new
88
+
89
+ settings.foo = 'bar'
90
+ serialized = encoder.dump(settings)
91
+
92
+ DummySetting.set_defaults :bobby => {:effing => 'tables'}
93
+
94
+ unserialized = encoder.raw_load(serialized)
95
+ unserialized.bobby?.should be_false
96
+ end
97
+
98
+ it "should not serialize nested defaults that didn't get overwritten (but other values did)" do
99
+ encoder = Defaultable::Serialization.new
100
+ DummySetting.set_defaults :bobby => {:effing => 'tables'}
101
+ settings = DummySetting.new
102
+
103
+ settings.bobby = 'tables'
104
+ serialized = encoder.dump(settings)
105
+
106
+ unserialized = encoder.raw_load(serialized)
107
+ unserialized.bobby?.should be_true
108
+ end
67
109
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: defaultable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2011-12-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
16
- requirement: &70278791694720 !ruby/object:Gem::Requirement
16
+ requirement: &70121466071200 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '3.0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70278791694720
24
+ version_requirements: *70121466071200
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &70278791693100 !ruby/object:Gem::Requirement
27
+ requirement: &70121466070520 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '2.7'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70278791693100
35
+ version_requirements: *70121466070520
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: pry
38
- requirement: &70278791692600 !ruby/object:Gem::Requirement
38
+ requirement: &70121466069920 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,7 +43,7 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70278791692600
46
+ version_requirements: *70121466069920
47
47
  description: Defaultable is an extendable class to allow easy method chaining for
48
48
  settings along with defaults.
49
49
  email:
@@ -59,11 +59,13 @@ files:
59
59
  - Rakefile
60
60
  - defaultable.gemspec
61
61
  - lib/defaultable.rb
62
+ - lib/defaultable/registry.rb
62
63
  - lib/defaultable/serialization.rb
63
64
  - lib/defaultable/settings.rb
64
65
  - lib/defaultable/version.rb
65
66
  - spec/defaultable_spec.rb
66
67
  - spec/env_test.yml
68
+ - spec/registry_spec.rb
67
69
  - spec/serialization_spec.rb
68
70
  - spec/spec_helper.rb
69
71
  - spec/test.yml
@@ -94,6 +96,7 @@ summary: Settings made easy.
94
96
  test_files:
95
97
  - spec/defaultable_spec.rb
96
98
  - spec/env_test.yml
99
+ - spec/registry_spec.rb
97
100
  - spec/serialization_spec.rb
98
101
  - spec/spec_helper.rb
99
102
  - spec/test.yml