gom 0.2.0 → 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.
Files changed (37) hide show
  1. data/README.rdoc +15 -0
  2. data/Rakefile +1 -1
  3. data/lib/gom.rb +1 -0
  4. data/lib/gom/object.rb +15 -19
  5. data/lib/gom/object/builder.rb +35 -33
  6. data/lib/gom/object/cached_builder.rb +23 -31
  7. data/lib/gom/object/collection.rb +49 -57
  8. data/lib/gom/object/draft.rb +17 -25
  9. data/lib/gom/object/id.rb +14 -22
  10. data/lib/gom/object/inspector.rb +46 -54
  11. data/lib/gom/object/mapping.rb +31 -47
  12. data/lib/gom/object/proxy.rb +25 -33
  13. data/lib/gom/spec.rb +11 -0
  14. data/lib/gom/spec/acceptance/adapter_that_needs_setup.rb +58 -0
  15. data/lib/gom/spec/acceptance/adapter_with_stateful_storage.rb +19 -21
  16. data/lib/gom/spec/acceptance/read_only_adapter_with_stateless_storage.rb +9 -8
  17. data/lib/gom/spec/object.rb +8 -0
  18. data/lib/gom/storage.rb +30 -26
  19. data/lib/gom/storage/adapter.rb +26 -43
  20. data/lib/gom/storage/configuration.rb +75 -68
  21. data/lib/gom/storage/configuration/view.rb +3 -16
  22. data/lib/gom/storage/configuration/view/class.rb +5 -22
  23. data/lib/gom/storage/configuration/view/map_reduce.rb +7 -24
  24. data/lib/gom/storage/fetcher.rb +24 -32
  25. data/lib/gom/storage/remover.rb +27 -35
  26. data/lib/gom/storage/saver.rb +35 -43
  27. data/spec/acceptance/adapter_spec.rb +16 -4
  28. data/spec/acceptance/fake_adapter_spec.rb +11 -0
  29. data/spec/acceptance/object_spec.rb +4 -1
  30. data/spec/fake_adapter.rb +12 -3
  31. data/spec/lib/gom/object/builder_spec.rb +5 -5
  32. data/spec/lib/gom/object/inspector_spec.rb +5 -9
  33. data/spec/lib/gom/object/mapping_spec.rb +27 -57
  34. data/spec/lib/gom/storage/adapter_spec.rb +1 -1
  35. data/spec/lib/gom/storage/configuration_spec.rb +33 -3
  36. data/spec/lib/gom/storage_spec.rb +19 -0
  37. metadata +50 -46
@@ -1,69 +1,61 @@
1
1
 
2
- module GOM
2
+ # Inspect an object and returns it's class and it's properties
3
+ class GOM::Object::Inspector
3
4
 
4
- module Object
5
+ attr_accessor :object
5
6
 
6
- # Inspect an object and returns it's class and it's properties
7
- class Inspector
8
-
9
- attr_accessor :object
10
-
11
- def initialize(object)
12
- @object = object
13
- end
14
-
15
- def draft
16
- initialize_draft
17
- set_class
18
- set_properties
19
- set_relations
20
- @draft
21
- end
22
-
23
- private
24
-
25
- def initialize_draft
26
- @draft = Draft.new
27
- end
7
+ def initialize(object)
8
+ @object = object
9
+ end
28
10
 
29
- def set_class
30
- @draft.class_name = @object.class.to_s
31
- end
11
+ def draft
12
+ initialize_draft
13
+ set_class
14
+ set_properties
15
+ set_relations
16
+ @draft
17
+ end
32
18
 
33
- def set_properties
34
- properties = { }
35
- read_instance_variables do |key, value|
36
- properties[key] = value if self.class.property_value?(value)
37
- end
38
- @draft.properties = properties
39
- end
19
+ private
40
20
 
41
- def set_relations
42
- relations = { }
43
- read_instance_variables do |key, value|
44
- relations[key] = value if self.class.relation_value?(value)
45
- end
46
- @draft.relations = relations
47
- end
21
+ def initialize_draft
22
+ @draft = GOM::Object::Draft.new
23
+ end
48
24
 
49
- def read_instance_variables
50
- @object.instance_variables.each do |name|
51
- key = name.to_s.sub(/^@/, "").to_sym
52
- value = @object.instance_variable_get name
53
- yield key, value
54
- end
55
- end
25
+ def set_class
26
+ @draft.class_name = @object.class.to_s
27
+ end
56
28
 
57
- def self.property_value?(value)
58
- !relation_value?(value)
59
- end
29
+ def set_properties
30
+ properties = { }
31
+ read_instance_variables do |key, value|
32
+ properties[key] = value if self.class.property_value?(value)
33
+ end
34
+ @draft.properties = properties
35
+ end
60
36
 
61
- def self.relation_value?(value)
62
- value.is_a?(GOM::Object::Proxy)
63
- end
37
+ def set_relations
38
+ relations = { }
39
+ read_instance_variables do |key, value|
40
+ relations[key] = value if self.class.relation_value?(value)
41
+ end
42
+ @draft.relations = relations
43
+ end
64
44
 
45
+ def read_instance_variables
46
+ @object.instance_variables.each do |name|
47
+ key = name.to_s.sub(/^@/, "").to_sym
48
+ value = @object.instance_variable_get name
49
+ yield key, value
65
50
  end
51
+ end
52
+
53
+ def self.property_value?(value)
54
+ !relation_value?(value)
55
+ end
66
56
 
57
+ def self.relation_value?(value)
58
+ value.is_a?(GOM::Object::Proxy)
67
59
  end
68
60
 
69
61
  end
@@ -1,61 +1,45 @@
1
1
 
2
- module GOM
2
+ # Provides a mapping between objects and ids
3
+ class GOM::Object::Mapping
3
4
 
4
- module Object
5
-
6
- # Provides a mapping between objects and ids
7
- class Mapping
8
-
9
- def initialize
10
- @map = { }
11
- end
12
-
13
- def put(object, id)
14
- @map[object] = id
15
- end
16
-
17
- def object_by_id(id)
18
- @map.respond_to?(:key) ? @map.key(id) : @map.index(id)
19
- end
20
-
21
- def id_by_object(object)
22
- @map[object]
23
- end
24
-
25
- def remove_by_id(id)
26
- @map.delete object_by_id(id)
27
- end
5
+ def initialize
6
+ @map = { }
7
+ end
28
8
 
29
- def remove_by_object(object)
30
- @map.delete object
31
- end
9
+ def put(object, id)
10
+ @map[object] = id
11
+ end
32
12
 
33
- def self.singleton
34
- @mapping ||= self.new
35
- end
13
+ def object_by_id(id)
14
+ @map.respond_to?(:key) ? @map.key(id) : @map.index(id)
15
+ end
36
16
 
37
- def self.put(object, id)
38
- self.singleton.put object, id
39
- end
17
+ def id_by_object(object)
18
+ @map[object]
19
+ end
40
20
 
41
- def self.object_by_id(id)
42
- self.singleton.object_by_id id
43
- end
21
+ def remove_by_id(id)
22
+ @map.delete object_by_id(id)
23
+ end
44
24
 
45
- def self.id_by_object(object)
46
- self.singleton.id_by_object object
47
- end
25
+ def remove_by_object(object)
26
+ @map.delete object
27
+ end
48
28
 
49
- def self.remove_by_id(id)
50
- self.singleton.remove_by_id id
51
- end
29
+ def size
30
+ @map.size
31
+ end
52
32
 
53
- def self.remove_by_object(object)
54
- self.singleton.remove_by_object object
55
- end
33
+ def clear!
34
+ @map.clear
35
+ end
56
36
 
57
- end
37
+ def self.singleton
38
+ @mapping ||= self.new
39
+ end
58
40
 
41
+ def self.method_missing(method_name, *arguments, &block)
42
+ self.singleton.send method_name, *arguments, &block
59
43
  end
60
44
 
61
45
  end
@@ -1,44 +1,36 @@
1
1
 
2
- module GOM
2
+ # The proxy that fetches an object if it's needed and simply passes method calls to it.
3
+ class GOM::Object::Proxy
3
4
 
4
- module Object
5
-
6
- # The proxy that fetches an object if it's needed and simply passes method calls to it.
7
- class Proxy
8
-
9
- def initialize(object_or_id)
10
- @object, @id = object_or_id.is_a?(GOM::Object::Id) ?
11
- [ nil, object_or_id ] :
12
- [ object_or_id, nil ]
13
- end
14
-
15
- def object
16
- fetch_object unless @object
17
- @object
18
- end
19
-
20
- def id
21
- fetch_id unless @id
22
- @id
23
- end
5
+ def initialize(object_or_id)
6
+ @object, @id = object_or_id.is_a?(GOM::Object::Id) ?
7
+ [ nil, object_or_id ] :
8
+ [ object_or_id, nil ]
9
+ end
24
10
 
25
- def method_missing(method_name, *arguments, &block)
26
- fetch_object unless @object
27
- @object.send method_name, *arguments, &block
28
- end
11
+ def object
12
+ fetch_object unless @object
13
+ @object
14
+ end
29
15
 
30
- private
16
+ def id
17
+ fetch_id unless @id
18
+ @id
19
+ end
31
20
 
32
- def fetch_object
33
- @object = GOM::Storage::Fetcher.new(@id).object
34
- end
21
+ def method_missing(method_name, *arguments, &block)
22
+ fetch_object unless @object
23
+ @object.send method_name, *arguments, &block
24
+ end
35
25
 
36
- def fetch_id
37
- @id = GOM::Object::Mapping.id_by_object @object
38
- end
26
+ private
39
27
 
40
- end
28
+ def fetch_object
29
+ @object = GOM::Storage::Fetcher.new(@id).object
30
+ end
41
31
 
32
+ def fetch_id
33
+ @id = GOM::Object::Mapping.id_by_object @object
42
34
  end
43
35
 
44
36
  end
data/lib/gom/spec.rb CHANGED
@@ -1,4 +1,15 @@
1
1
  require 'rspec'
2
2
 
3
+ require File.join(File.dirname(__FILE__), "spec", "acceptance", "adapter_that_needs_setup")
3
4
  require File.join(File.dirname(__FILE__), "spec", "acceptance", "adapter_with_stateful_storage")
4
5
  require File.join(File.dirname(__FILE__), "spec", "acceptance", "read_only_adapter_with_stateless_storage")
6
+
7
+ module GOM
8
+
9
+ module Spec
10
+
11
+ autoload :Object, File.join(File.dirname(__FILE__), "spec", "object")
12
+
13
+ end
14
+
15
+ end
@@ -0,0 +1,58 @@
1
+
2
+ shared_examples_for "an adapter that needs setup" do
3
+
4
+ before :each do
5
+ GOM::Storage.teardown
6
+ end
7
+
8
+ describe "fetching an object" do
9
+
10
+ it "should raise a #{GOM::Storage::Adapter::NoSetupError}" do
11
+ lambda do
12
+ GOM::Storage.fetch "test_storage:object_1"
13
+ end.should raise_error(GOM::Storage::Adapter::NoSetupError)
14
+ end
15
+
16
+ end
17
+
18
+ describe "storing an object" do
19
+
20
+ it "should raise a #{GOM::Storage::Adapter::NoSetupError}" do
21
+ lambda do
22
+ GOM::Storage.store :object
23
+ end.should raise_error(GOM::Storage::Adapter::NoSetupError)
24
+ end
25
+
26
+ end
27
+
28
+ describe "removing an object" do
29
+
30
+ it "should raise a #{GOM::Storage::Adapter::NoSetupError}" do
31
+ lambda do
32
+ GOM::Storage.remove "test_storage:object_1"
33
+ end.should raise_error(GOM::Storage::Adapter::NoSetupError)
34
+ end
35
+
36
+ end
37
+
38
+ describe "fetching a class collection" do
39
+
40
+ it "should raise a #{GOM::Storage::Adapter::NoSetupError}" do
41
+ lambda do
42
+ GOM::Storage.collection :test_storage, :test_object_class_view
43
+ end.should raise_error(GOM::Storage::Adapter::NoSetupError)
44
+ end
45
+
46
+ end
47
+
48
+ describe "fetching a map collection" do
49
+
50
+ it "should raise a #{GOM::Storage::Adapter::NoSetupError}" do
51
+ lambda do
52
+ GOM::Storage.collection :test_storage, :test_map_view
53
+ end.should raise_error(GOM::Storage::Adapter::NoSetupError)
54
+ end
55
+
56
+ end
57
+
58
+ end
@@ -5,20 +5,24 @@ shared_examples_for "an adapter connected to a stateful storage" do
5
5
  GOM::Storage.setup
6
6
  end
7
7
 
8
+ after :all do
9
+ GOM::Storage.teardown
10
+ end
11
+
8
12
  before :each do
9
- @related_object = Object.new
10
- @related_object.instance_variable_set :@number, 16
13
+ @related_object = GOM::Spec::Object.new
14
+ @related_object.number = 16
11
15
 
12
- @object = Object.new
13
- @object.instance_variable_set :@number, 11
14
- @object.instance_variable_set :@related_object, GOM::Object.reference(@related_object)
16
+ @object = GOM::Spec::Object.new
17
+ @object.number = 11
18
+ @object.related_object = GOM::Object.reference @related_object
15
19
  end
16
20
 
17
21
  describe "fetching an object" do
18
22
 
19
23
  before :each do
20
24
  GOM::Storage.store @object, :test_storage
21
- @id = GOM::Object.id(@object)
25
+ @id = GOM::Object.id @object
22
26
 
23
27
  @object = GOM::Storage.fetch @id
24
28
  end
@@ -29,11 +33,11 @@ shared_examples_for "an adapter connected to a stateful storage" do
29
33
  end
30
34
 
31
35
  it "should return an object of the correct class" do
32
- @object.class.should == Object
36
+ @object.class.should == GOM::Spec::Object
33
37
  end
34
38
 
35
39
  it "should set the object's instance variables" do
36
- @object.instance_variable_get(:@number).should == 11
40
+ @object.number.should == 11
37
41
  end
38
42
 
39
43
  it "should assign an object id" do
@@ -41,9 +45,9 @@ shared_examples_for "an adapter connected to a stateful storage" do
41
45
  end
42
46
 
43
47
  it "should also fetch the related object" do
44
- related_object_proxy = @object.instance_variable_get :@related_object
48
+ related_object_proxy = @object.related_object
45
49
  related_object_proxy.should be_instance_of(GOM::Object::Proxy)
46
- related_object_proxy.object.instance_variable_get(:@number).should == 16
50
+ related_object_proxy.object.number.should == 16
47
51
  end
48
52
 
49
53
  end
@@ -74,7 +78,7 @@ shared_examples_for "an adapter connected to a stateful storage" do
74
78
  it "should store the related object" do
75
79
  GOM::Storage.store @object, :test_storage
76
80
  related_object = GOM::Storage.fetch GOM::Object.id(@related_object)
77
- related_object.instance_variable_get(:@number).should == 16
81
+ related_object.number.should == 16
78
82
  end
79
83
 
80
84
  end
@@ -115,8 +119,7 @@ shared_examples_for "an adapter connected to a stateful storage" do
115
119
  describe "fetching a class collection" do
116
120
 
117
121
  before :each do
118
- @another_object = mock Object, :class => mock(Class, :to_s => "Test")
119
- @another_object.instance_variable_set :@number, 17
122
+ @another_object = Object.new
120
123
 
121
124
  GOM::Storage.store @object, :test_storage
122
125
  GOM::Storage.store @another_object, :test_storage
@@ -138,13 +141,7 @@ shared_examples_for "an adapter connected to a stateful storage" do
138
141
  collection.size.should > 0
139
142
  collection.each do |object_proxy|
140
143
  object_proxy.should be_instance_of(GOM::Object::Proxy)
141
- [
142
- @object.instance_variable_get(:@number),
143
- @related_object.instance_variable_get(:@number)
144
- ].should include(object_proxy.object.instance_variable_get(:@number))
145
- [
146
- @another_object.instance_variable_get(:@number)
147
- ].should_not include(object_proxy.object.instance_variable_get(:@number))
144
+ object_proxy.object.should be_instance_of(GOM::Spec::Object)
148
145
  end
149
146
  end
150
147
 
@@ -171,7 +168,8 @@ shared_examples_for "an adapter connected to a stateful storage" do
171
168
  collection.size.should > 0
172
169
  collection.each do |object_proxy|
173
170
  object_proxy.should be_instance_of(GOM::Object::Proxy)
174
- object_proxy.object.instance_variable_get(:@number).should == @object.instance_variable_get(:@number)
171
+ object_proxy.object.should be_instance_of(GOM::Spec::Object)
172
+ object_proxy.object.number.should == @object.number
175
173
  end
176
174
  end
177
175