mongodoc 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
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