gom 0.1.0 → 0.2.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 (36) hide show
  1. data/README.rdoc +70 -0
  2. data/lib/gom/object.rb +4 -1
  3. data/lib/gom/object/builder.rb +47 -0
  4. data/lib/gom/object/cached_builder.rb +42 -0
  5. data/lib/gom/object/collection.rb +72 -0
  6. data/lib/gom/object/draft.rb +34 -0
  7. data/lib/gom/object/inspector.rb +29 -15
  8. data/lib/gom/spec/acceptance/adapter_with_stateful_storage.rb +74 -5
  9. data/lib/gom/spec/acceptance/read_only_adapter_with_stateless_storage.rb +20 -0
  10. data/lib/gom/storage.rb +6 -2
  11. data/lib/gom/storage/adapter.rb +11 -4
  12. data/lib/gom/storage/configuration.rb +30 -1
  13. data/lib/gom/storage/configuration/view.rb +20 -0
  14. data/lib/gom/storage/configuration/view/class.rb +28 -0
  15. data/lib/gom/storage/configuration/view/map_reduce.rb +29 -0
  16. data/lib/gom/storage/fetcher.rb +9 -34
  17. data/lib/gom/storage/saver.rb +5 -7
  18. data/spec/acceptance/object_spec.rb +1 -0
  19. data/spec/fake_adapter.rb +55 -10
  20. data/spec/lib/gom/object/builder_spec.rb +51 -0
  21. data/spec/lib/gom/object/cached_builder_spec.rb +43 -0
  22. data/spec/lib/gom/object/collection_spec.rb +158 -0
  23. data/spec/lib/gom/object/draft_spec.rb +59 -0
  24. data/spec/lib/gom/object/inspector_spec.rb +8 -10
  25. data/spec/lib/gom/storage/adapter_spec.rb +7 -33
  26. data/spec/lib/gom/storage/configuration/view/class_spec.rb +17 -0
  27. data/spec/lib/gom/storage/configuration/view/map_reduce_spec.rb +21 -0
  28. data/spec/lib/gom/storage/configuration_spec.rb +29 -0
  29. data/spec/lib/gom/storage/fetcher_spec.rb +7 -38
  30. data/spec/lib/gom/storage/remover_spec.rb +7 -9
  31. data/spec/lib/gom/storage/saver_spec.rb +17 -33
  32. data/spec/lib/gom/storage_spec.rb +33 -9
  33. data/spec/storage.configuration +10 -0
  34. metadata +22 -6
  35. data/lib/gom/object/injector.rb +0 -45
  36. data/spec/lib/gom/object/injector_spec.rb +0 -51
@@ -0,0 +1,43 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "spec_helper"))
2
+
3
+ describe GOM::Object::CachedBuilder do
4
+
5
+ before :each do
6
+ @draft = mock GOM::Object::Draft
7
+ @id = mock GOM::Object::Id
8
+
9
+ @object = mock Object
10
+ GOM::Object::Mapping.stub(:object_by_id).and_return(@object)
11
+ GOM::Object::Mapping.stub(:put)
12
+
13
+ @builder = mock GOM::Object::Builder, :object => @object
14
+ GOM::Object::Builder.stub(:new).and_return(@builder)
15
+
16
+ @cached_builder = described_class.new @draft, @id
17
+ end
18
+
19
+ describe "object" do
20
+
21
+ it "should check the mapping for the object" do
22
+ GOM::Object::Mapping.should_receive(:object_by_id).with(@id).and_return(@object)
23
+ @cached_builder.object
24
+ end
25
+
26
+ it "should initialize the object builder" do
27
+ GOM::Object::Builder.should_receive(:new).with(@draft, @object).and_return(@builder)
28
+ @cached_builder.object
29
+ end
30
+
31
+ it "should set the mapping for the object" do
32
+ GOM::Object::Mapping.should_receive(:put).with(@object, @id).and_return(@object)
33
+ @cached_builder.object
34
+ end
35
+
36
+ it "should return the object" do
37
+ object = @cached_builder.object
38
+ object.should == @object
39
+ end
40
+
41
+ end
42
+
43
+ end
@@ -0,0 +1,158 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "spec_helper"))
2
+
3
+ describe GOM::Object::Collection do
4
+
5
+ before :each do
6
+ @object = mock Object
7
+
8
+ @fetcher = mock Object, :total_count => 1
9
+
10
+ @proxy = mock GOM::Object::Proxy
11
+ GOM::Object::Proxy.stub(:new).and_return(@proxy)
12
+
13
+ @builder = mock GOM::Object::CachedBuilder, :object => @object
14
+ GOM::Object::CachedBuilder.stub(:new).and_return(@builder)
15
+
16
+ @collection = described_class.new @fetcher
17
+ end
18
+
19
+ describe "total_count" do
20
+
21
+ it "should call the fetcher's total_count" do
22
+ @fetcher.should_receive(:total_count)
23
+ @collection.total_count
24
+ end
25
+
26
+ end
27
+
28
+ describe "first" do
29
+
30
+ context "with no previous fetched objects" do
31
+
32
+ context "with a fetcher that provides drafts" do
33
+
34
+ before :each do
35
+ @draft = mock Hash
36
+ @drafts = [ @draft ]
37
+
38
+ @fetcher.stub(:drafts).and_return(@drafts)
39
+ end
40
+
41
+ it "should get the drafts from the fetcher" do
42
+ @fetcher.should_receive(:drafts).and_return(@drafts)
43
+ @collection.first
44
+ end
45
+
46
+ it "should initialize the cached object builder with each draft" do
47
+ GOM::Object::CachedBuilder.should_receive(:new).with(@draft).and_return(@builder)
48
+ @collection.first
49
+ end
50
+
51
+ it "should initialize an object proxy with the object" do
52
+ GOM::Object::Proxy.should_receive(:new).with(@object).and_return(@proxy)
53
+ @collection.first
54
+ end
55
+
56
+ it "should return a object proxy for the first object" do
57
+ object_proxy = @collection.first
58
+ object_proxy.should == @proxy
59
+ end
60
+
61
+ end
62
+
63
+ context "with a fetcher that provides ids" do
64
+
65
+ before :each do
66
+ @id = mock GOM::Object::Id
67
+ @ids = [ @id ]
68
+
69
+ @fetcher.stub(:ids).and_return(@ids)
70
+ end
71
+
72
+ it "should get the ids from the fetcher" do
73
+ @fetcher.should_receive(:ids).and_return(@ids)
74
+ @collection.first
75
+ end
76
+
77
+ it "should not initialize the cached object builder" do
78
+ GOM::Object::CachedBuilder.should_not_receive(:new)
79
+ @collection.first
80
+ end
81
+
82
+ it "should initialize an object proxy with the id" do
83
+ GOM::Object::Proxy.should_receive(:new).with(@id).and_return(@proxy)
84
+ @collection.first
85
+ end
86
+
87
+ it "should return a object proxy for the first object" do
88
+ object_proxy = @collection.first
89
+ object_proxy.should == @proxy
90
+ end
91
+
92
+ end
93
+
94
+ context "with a fetcher that provide rows" do
95
+
96
+ before :each do
97
+ @row = mock Object
98
+ @rows = [ @row ]
99
+
100
+ @fetcher.stub(:drafts).and_return(nil)
101
+ @fetcher.stub(:rows).and_return(@rows)
102
+ end
103
+
104
+ it "should get the rows from the fetcher" do
105
+ @fetcher.should_receive(:rows).and_return(@rows)
106
+ @collection.first
107
+ end
108
+
109
+ it "should not initialize the cached object builder" do
110
+ GOM::Object::CachedBuilder.should_not_receive(:new)
111
+ @collection.first
112
+ end
113
+
114
+ it "should return the first row" do
115
+ row = @collection.first
116
+ row.should == @row
117
+ end
118
+
119
+ end
120
+
121
+ context "with a fetcher that doesn't provide drafts, ids nor rows" do
122
+
123
+ it "should raise a #{NotImplementedError}" do
124
+ lambda do
125
+ @collection.first
126
+ end.should raise_error(NotImplementedError)
127
+ end
128
+
129
+ end
130
+
131
+ end
132
+
133
+ context "with previously fetched objects" do
134
+
135
+ before :each do
136
+ @draft = mock Hash
137
+ @drafts = [ @draft ]
138
+
139
+ @fetcher.stub(:drafts).and_return(@drafts)
140
+
141
+ @collection.first
142
+ end
143
+
144
+ it "should not call the fetcher" do
145
+ @fetcher.should_not_receive(:drafts)
146
+ @collection.first
147
+ end
148
+
149
+ it "should return a object proxy for the first object" do
150
+ object_proxy = @collection.first
151
+ object_proxy.should == @proxy
152
+ end
153
+
154
+ end
155
+
156
+ end
157
+
158
+ end
@@ -0,0 +1,59 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "spec_helper"))
2
+
3
+ describe GOM::Object::Draft do
4
+
5
+ before :each do
6
+ @draft = described_class.new "object_1", "Object", { "test" => "test value" }, { "test" => "test_storage:object_2" }
7
+ end
8
+
9
+ describe "initialize" do
10
+
11
+ it "should set the id" do
12
+ @draft.id.should == "object_1"
13
+ end
14
+
15
+ it "should set the class name" do
16
+ @draft.class_name.should == "Object"
17
+ end
18
+
19
+ it "should set the properties" do
20
+ @draft.properties.should == { "test" => "test value" }
21
+ end
22
+
23
+ it "should set the relations" do
24
+ @draft.relations.should == { "test" => "test_storage:object_2" }
25
+ end
26
+
27
+ end
28
+
29
+ describe "properties" do
30
+
31
+ it "should return an empty hash if no properties are given" do
32
+ @draft.properties = nil
33
+ @draft.properties.should == { }
34
+ end
35
+
36
+ end
37
+
38
+ describe "relations" do
39
+
40
+ it "should return an empty hash if no relations are given" do
41
+ @draft.relations = nil
42
+ @draft.relations.should == { }
43
+ end
44
+
45
+ end
46
+
47
+ describe "==" do
48
+
49
+ before :each do
50
+ @same_draft = described_class.new "object_1", "Object", { "test" => "test value" }, { "test" => "test_storage:object_2" }
51
+ end
52
+
53
+ it "should return true if all members are the same" do
54
+ @draft.should == @same_draft
55
+ end
56
+
57
+ end
58
+
59
+ end
@@ -9,20 +9,18 @@ describe GOM::Object::Inspector do
9
9
  @object.instance_variable_set :@test, "test value"
10
10
  @object.instance_variable_set :@related_object, @related_object_proxy
11
11
 
12
- @object_hash = {
13
- :class => "Object",
14
- :properties => { :test => "test value" },
15
- :relations => { :related_object => @related_object_proxy }
16
- }
17
-
18
12
  @inspector = GOM::Object::Inspector.new @object
19
13
  end
20
14
 
21
- describe "perform" do
15
+ describe "draft" do
16
+
17
+ before :each do
18
+ @draft = GOM::Object::Draft.new nil, "Object", { :test => "test value" }, { :related_object => @related_object_proxy }
19
+ end
22
20
 
23
- it "should return the correct object hash" do
24
- @inspector.perform
25
- @inspector.object_hash.should == @object_hash
21
+ it "should return the correct draft" do
22
+ draft = @inspector.draft
23
+ draft.should == @draft
26
24
  end
27
25
 
28
26
  end
@@ -30,42 +30,16 @@ describe GOM::Storage::Adapter do
30
30
 
31
31
  end
32
32
 
33
- describe "setup" do
33
+ [ :setup, :fetch, :store, :remove, :collection ].each do |method_name|
34
34
 
35
- it "should raise a NotImplementedError" do
36
- lambda do
37
- @adapter.setup
38
- end.should raise_error(NotImplementedError)
39
- end
40
-
41
- end
42
-
43
- describe "fetch" do
44
-
45
- it "should raise a NotImplementedError" do
46
- lambda do
47
- @adapter.fetch
48
- end.should raise_error(NotImplementedError)
49
- end
50
-
51
- end
52
-
53
- describe "store" do
54
-
55
- it "should raise a NotImplementedError" do
56
- lambda do
57
- @adapter.store
58
- end.should raise_error(NotImplementedError)
59
- end
60
-
61
- end
35
+ describe "#{method_name}" do
62
36
 
63
- describe "remove" do
37
+ it "should raise a NotImplementedError" do
38
+ lambda do
39
+ @adapter.send method_name
40
+ end.should raise_error(NotImplementedError)
41
+ end
64
42
 
65
- it "should raise a NotImplementedError" do
66
- lambda do
67
- @adapter.remove
68
- end.should raise_error(NotImplementedError)
69
43
  end
70
44
 
71
45
  end
@@ -0,0 +1,17 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "..", "..", "spec_helper"))
2
+
3
+ describe GOM::Storage::Configuration::View::Class do
4
+
5
+ before :each do
6
+ @class = described_class.new "Object"
7
+ end
8
+
9
+ describe "initialize" do
10
+
11
+ it "should set the view's class name" do
12
+ @class.class_name.should == "Object"
13
+ end
14
+
15
+ end
16
+
17
+ end
@@ -0,0 +1,21 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "..", "..", "spec_helper"))
2
+
3
+ describe GOM::Storage::Configuration::View::MapReduce do
4
+
5
+ before :each do
6
+ @map_reduce = described_class.new "map function", "reduce function"
7
+ end
8
+
9
+ describe "initialize" do
10
+
11
+ it "should set the view's map function" do
12
+ @map_reduce.map.should == "map function"
13
+ end
14
+
15
+ it "should set the view's reduce function" do
16
+ @map_reduce.reduce.should == "reduce function"
17
+ end
18
+
19
+ end
20
+
21
+ end
@@ -44,6 +44,35 @@ describe GOM::Storage::Configuration do
44
44
 
45
45
  end
46
46
 
47
+ describe "views" do
48
+
49
+ it "should return a hash including class views" do
50
+ view = @configuration.views[:test_object_class_view]
51
+ view.should be_instance_of(described_class::View::Class)
52
+ view.class_name.should == "Object"
53
+ end
54
+
55
+ it "should return a hash including map reduce views" do
56
+ view = @configuration.views[:test_map_view]
57
+ view.should be_instance_of(described_class::View::MapReduce)
58
+ view.map.should == "function(document) { }"
59
+ view.reduce.should == "function(key, values) { }"
60
+ end
61
+
62
+ it "should raise a #{NotImplementedError} if the view type is invalid" do
63
+ @configuration["views"]["test_invalid_view"] = { "type" => "invalid" }
64
+ lambda do
65
+ @configuration.views[:test_invalid_view]
66
+ end.should raise_error(NotImplementedError)
67
+ end
68
+
69
+ it "should return nil if given view name doesn't exists" do
70
+ view = @configuration.views[:invalid]
71
+ view.should be_nil
72
+ end
73
+
74
+ end
75
+
47
76
  describe "read" do
48
77
 
49
78
  it "should read the configuration file" do
@@ -6,24 +6,14 @@ describe GOM::Storage::Fetcher do
6
6
  @id = GOM::Object::Id.new "test_storage", "object_1"
7
7
  @object = Object.new
8
8
  @object.instance_variable_set :@test, "test value"
9
- @object_hash = {
10
- :class => "Object",
11
- :properties => { :test => "test value" }
12
- }
9
+ @draft = GOM::Object::Draft.new nil, "Object", { :test => "test value" }
13
10
 
14
- @new_method = mock Method, :arity => 3
15
- @klass = mock Class, :new => @object, :method => @new_method
16
- Object.stub(:const_get).and_return(@klass)
17
-
18
- @adapter = mock GOM::Storage::Adapter, :fetch => @object_hash
11
+ @adapter = mock GOM::Storage::Adapter, :fetch => @draft
19
12
  @configuration = mock GOM::Storage::Configuration, :adapter => @adapter
20
13
  GOM::Storage::Configuration.stub(:[]).and_return(@configuration)
21
14
 
22
- GOM::Object::Mapping.stub(:object_by_id)
23
- GOM::Object::Mapping.stub(:put)
24
-
25
- @injector = mock GOM::Object::Injector, :perform => nil, :object => @object
26
- GOM::Object::Injector.stub(:new).and_return(@injector)
15
+ @builder = mock GOM::Object::CachedBuilder, :object => @object
16
+ GOM::Object::CachedBuilder.stub(:new).and_return(@builder)
27
17
 
28
18
  @fetcher = described_class.new @id
29
19
  @fetcher.stub(:object_class).and_return(@klass)
@@ -43,33 +33,12 @@ describe GOM::Storage::Fetcher do
43
33
  end
44
34
 
45
35
  it "should fetch the id from the adapter instance" do
46
- @adapter.should_receive(:fetch).with("object_1").and_return(@object_hash)
47
- @fetcher.object
48
- end
49
-
50
- it "should initialize the object with nil-arguments to the constructor" do
51
- @klass.should_receive(:new).with(nil, nil, nil).and_return(@object)
52
- @fetcher.object
53
- end
54
-
55
- it "should initialize the object with no arguments to the constructor if a variable argument count is needed" do
56
- @new_method.stub(:arity).and_return(-1)
57
- @klass.should_receive(:new).with(no_args).and_return(@object)
58
- @fetcher.object
59
- end
60
-
61
- it "should check if a mapping exists for the object" do
62
- GOM::Object::Mapping.should_receive(:object_by_id).with(@id).and_return(Object.new)
63
- @fetcher.object
64
- end
65
-
66
- it "should initialize the object if not given" do
67
- GOM::Object::Injector.should_receive(:new).with(anything, @object_hash).and_return(@injector)
36
+ @adapter.should_receive(:fetch).with("object_1").and_return(@draft)
68
37
  @fetcher.object
69
38
  end
70
39
 
71
- it "should create mapping between object and id" do
72
- GOM::Object::Mapping.should_receive(:put).with(@object, @id)
40
+ it "should initialize the cached object builder" do
41
+ GOM::Object::CachedBuilder.should_receive(:new).with(@draft, @id).and_return(@builder)
73
42
  @fetcher.object
74
43
  end
75
44