mongodoc 0.2.1 → 0.2.2

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 (44) hide show
  1. data/README.textile +42 -12
  2. data/Rakefile +4 -4
  3. data/TODO +26 -0
  4. data/VERSION +1 -1
  5. data/examples/simple_document.rb +1 -1
  6. data/examples/simple_object.rb +0 -2
  7. data/features/mongodb.yml +6 -5
  8. data/features/removing_documents.feature +68 -0
  9. data/features/step_definitions/collection_steps.rb +3 -3
  10. data/features/step_definitions/document_steps.rb +2 -2
  11. data/features/step_definitions/removing_documents_steps.rb +14 -0
  12. data/features/support/support.rb +2 -2
  13. data/lib/mongodoc.rb +4 -7
  14. data/lib/mongodoc/associations/collection_proxy.rb +103 -0
  15. data/lib/mongodoc/associations/document_proxy.rb +53 -0
  16. data/lib/mongodoc/associations/hash_proxy.rb +96 -0
  17. data/lib/mongodoc/associations/proxy_base.rb +51 -0
  18. data/lib/mongodoc/attributes.rb +49 -17
  19. data/lib/mongodoc/collection.rb +15 -5
  20. data/lib/mongodoc/connection.rb +83 -20
  21. data/lib/mongodoc/criteria.rb +9 -4
  22. data/lib/mongodoc/cursor.rb +9 -3
  23. data/lib/mongodoc/document.rb +37 -24
  24. data/lib/mongodoc/validations/macros.rb +11 -0
  25. data/lib/mongodoc/validations/validates_embedded.rb +13 -0
  26. data/mongodb.example.yml +13 -5
  27. data/mongodoc.gemspec +33 -23
  28. data/spec/associations/collection_proxy_spec.rb +200 -0
  29. data/spec/associations/document_proxy_spec.rb +42 -0
  30. data/spec/associations/hash_proxy_spec.rb +163 -0
  31. data/spec/attributes_spec.rb +113 -47
  32. data/spec/bson_spec.rb +24 -24
  33. data/spec/collection_spec.rb +67 -86
  34. data/spec/connection_spec.rb +98 -150
  35. data/spec/criteria_spec.rb +4 -3
  36. data/spec/cursor_spec.rb +33 -27
  37. data/spec/document_spec.rb +173 -156
  38. data/spec/embedded_save_spec.rb +8 -3
  39. data/spec/new_record_spec.rb +33 -121
  40. metadata +80 -39
  41. data/lib/mongodoc/parent_proxy.rb +0 -44
  42. data/lib/mongodoc/proxy.rb +0 -83
  43. data/spec/parent_proxy_spec.rb +0 -44
  44. data/spec/proxy_spec.rb +0 -80
@@ -1,44 +0,0 @@
1
- module MongoDoc
2
- class ParentProxy
3
- attr_reader :assoc_name, :_parent
4
-
5
- def initialize(parent, assoc_name)
6
- raise ArgumentError.new('ParentProxy requires a parent') if parent.nil?
7
- raise ArgumentError.new('ParentProxy require an association name') if assoc_name.blank?
8
- @_parent = parent
9
- @assoc_name = assoc_name
10
- end
11
-
12
- def _path_to_root(src, attrs)
13
- _parent._path_to_root(src, _annotated_keys(attrs))
14
- end
15
-
16
- def _selector_path_to_root(selector)
17
- _parent._selector_path_to_root(_annotated_keys(selector))
18
- end
19
-
20
- protected
21
-
22
- def _annotated_keys(hash)
23
- hash.inject({}) do |annotated, (key, value)|
24
- annotated["#{assoc_name}.#{key}"] = value
25
- annotated
26
- end
27
- end
28
-
29
- private
30
-
31
- def method_missing(method, *args)
32
- unless @_parent.respond_to?(method)
33
- message = "undefined method `#{method.to_s}' for proxied \"#{@_parent}\":#{@_parent.class.to_s}"
34
- raise NoMethodError, message
35
- end
36
-
37
- if block_given?
38
- @_parent.send(method, *args) { |*block_args| yield(*block_args) }
39
- else
40
- @_parent.send(method, *args)
41
- end
42
- end
43
- end
44
- end
@@ -1,83 +0,0 @@
1
- # Thanks Sandro!
2
- # http://github.com/sandro
3
- module MongoDoc
4
- class Proxy
5
- # List of array methods (that are not in +Object+) that need to be
6
- # delegated to +collection+.
7
- ARRAY_METHODS = (Array.instance_methods - Object.instance_methods).map { |n| n.to_s }
8
-
9
- # List of additional methods that must be delegated to +collection+.
10
- MUST_DEFINE = %w[to_a to_ary inspect to_bson ==]
11
-
12
- (ARRAY_METHODS + MUST_DEFINE).uniq.each do |method|
13
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
14
- def #{method}(*args, &block) # def each(*args, &block)
15
- collection.send(:#{method}, *args, &block) # collection.send(:each, *args, &block)
16
- end # end
17
- RUBY
18
- end
19
-
20
- attr_reader :assoc_name, :collection, :collection_class, :_parent, :_root
21
-
22
- def _parent=(parent)
23
- @_parent = parent
24
- end
25
-
26
- def _root=(root)
27
- @_root = root
28
- collection.each do |item|
29
- item._root = root
30
- end
31
- end
32
-
33
- def initialize(options)
34
- @assoc_name = options[:assoc_name]
35
- @collection = []
36
- @collection_class = options[:collection_class]
37
- @_root = options[:root]
38
- @_parent = options[:parent]
39
- end
40
-
41
- alias_method :append, :<<
42
- def <<(item)
43
- item = build(item) if Hash === item
44
- if Document === item
45
- item._parent = self
46
- item._root = _root
47
- _root.send(:register_save_observer, item)
48
- end
49
- append item
50
- self
51
- end
52
- alias_method :push, :<<
53
- alias_method :concat, :<<
54
-
55
- # Lie about our class. Borrowed from Rake::FileList
56
- # Note: Does not work for case equality (<tt>===</tt>)
57
- def is_a?(klass)
58
- klass == Array || super(klass)
59
- end
60
- alias kind_of? is_a?
61
-
62
- def _path_to_root(src, attrs)
63
- assoc_path = "#{assoc_name}.#{index(src)}"
64
- assoc_attrs = attrs.inject({}) do |assoc_attrs, (key, value)|
65
- assoc_attrs["#{assoc_path}.#{key}"] = value
66
- assoc_attrs
67
- end
68
- _parent._path_to_root(src, assoc_attrs)
69
- end
70
-
71
- def _selector_path_to_root(selector)
72
- annotated_selector = selector.inject({}) do |annotated, (key, value)|
73
- annotated["#{assoc_name}.#{key}"] = value
74
- annotated
75
- end
76
- _parent._selector_path_to_root(annotated_selector)
77
- end
78
-
79
- def build(attrs)
80
- collection_class.new(attrs)
81
- end
82
- end
83
- end
@@ -1,44 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
-
3
- describe "MongoDoc::ParentProxy" do
4
- class Parent
5
- include MongoDoc::Document
6
- end
7
-
8
- class Child
9
- include MongoDoc::Document
10
- end
11
-
12
- before do
13
- @parent = Parent.new
14
- @assoc_name = 'association'
15
- end
16
-
17
- subject do
18
- MongoDoc::ParentProxy.new(@parent, @assoc_name)
19
- end
20
-
21
- it "has the association name" do
22
- should respond_to(:assoc_name)
23
- end
24
-
25
- it "has a parent" do
26
- should respond_to(:_parent)
27
- end
28
-
29
- it "requires a parent" do
30
- expect do
31
- MongoDoc::ParentProxy.new(nil, @assoc_name)
32
- end.should raise_error
33
- end
34
-
35
- it "requires an association name" do
36
- expect do
37
- MongoDoc::ParentProxy.new(@parent, nil)
38
- end.should raise_error
39
- end
40
-
41
- it "inserts the association name the _path_to_root" do
42
- subject._path_to_root(Child.new, :name1 => 'value1', :name2 => 'value2').should == {"#{@assoc_name}.name1" => 'value1', "#{@assoc_name}.name2" => "value2"}
43
- end
44
- end
@@ -1,80 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
-
3
- describe MongoDoc::Proxy do
4
- class ProxyTest
5
- include MongoDoc::Document
6
-
7
- key :name
8
- end
9
-
10
- let(:root) { stub('root', :register_save_observer => nil) }
11
- let(:proxy) { MongoDoc::Proxy.new(:assoc_name => 'has_many_name', :collection_class => ProxyTest, :root => root, :parent => root) }
12
-
13
- context "#<<" do
14
- let(:item) { ProxyTest.new }
15
-
16
- it "appends the item to the collection" do
17
- (proxy << item).should include(item)
18
- end
19
-
20
- context "when the item is a Hash" do
21
- let(:hash) {{:name => 'hash'}}
22
-
23
- it "calls build when the item is a hash" do
24
- proxy.should_receive(:build).with(hash).and_return(item)
25
- proxy << hash
26
- end
27
-
28
- it "registers a save observer" do
29
- proxy.stub(:build).and_return(item)
30
- root.should_receive(:register_save_observer)
31
- proxy << hash
32
- end
33
-
34
- it "sets the root" do
35
- proxy.stub(:build).and_return(item)
36
- proxy << hash
37
- item._root.should == root
38
- end
39
- end
40
-
41
- context "when the item is not a MongoDoc::Document" do
42
- it "does not register a save observer" do
43
- root.should_not_receive(:register_save_observer)
44
- proxy << 'not_doc'
45
- end
46
-
47
- it "does not set the root" do
48
- item.should_not_receive(:_root=)
49
- proxy << 'not_doc'
50
- end
51
- end
52
-
53
- context "when the item is a MongoDoc::Document" do
54
- it "registers a save observer" do
55
- root.should_receive(:register_save_observer)
56
- proxy << item
57
- end
58
-
59
- it "sets the root" do
60
- proxy << item
61
- item._root.should == root
62
- end
63
- end
64
-
65
- context "when the item is an array" do
66
- it "adds the array" do
67
- array = ['something else']
68
- proxy << array
69
- proxy.should include(array)
70
- end
71
- end
72
- end
73
-
74
- context "#build" do
75
- it "builds an object of the collection class from the hash attrs" do
76
- name = 'built'
77
- proxy.build({:name => name}).name.should == name
78
- end
79
- end
80
- end