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.
- data/README.textile +42 -12
- data/Rakefile +4 -4
- data/TODO +26 -0
- data/VERSION +1 -1
- data/examples/simple_document.rb +1 -1
- data/examples/simple_object.rb +0 -2
- data/features/mongodb.yml +6 -5
- data/features/removing_documents.feature +68 -0
- data/features/step_definitions/collection_steps.rb +3 -3
- data/features/step_definitions/document_steps.rb +2 -2
- data/features/step_definitions/removing_documents_steps.rb +14 -0
- data/features/support/support.rb +2 -2
- data/lib/mongodoc.rb +4 -7
- data/lib/mongodoc/associations/collection_proxy.rb +103 -0
- data/lib/mongodoc/associations/document_proxy.rb +53 -0
- data/lib/mongodoc/associations/hash_proxy.rb +96 -0
- data/lib/mongodoc/associations/proxy_base.rb +51 -0
- data/lib/mongodoc/attributes.rb +49 -17
- data/lib/mongodoc/collection.rb +15 -5
- data/lib/mongodoc/connection.rb +83 -20
- data/lib/mongodoc/criteria.rb +9 -4
- data/lib/mongodoc/cursor.rb +9 -3
- data/lib/mongodoc/document.rb +37 -24
- data/lib/mongodoc/validations/macros.rb +11 -0
- data/lib/mongodoc/validations/validates_embedded.rb +13 -0
- data/mongodb.example.yml +13 -5
- data/mongodoc.gemspec +33 -23
- data/spec/associations/collection_proxy_spec.rb +200 -0
- data/spec/associations/document_proxy_spec.rb +42 -0
- data/spec/associations/hash_proxy_spec.rb +163 -0
- data/spec/attributes_spec.rb +113 -47
- data/spec/bson_spec.rb +24 -24
- data/spec/collection_spec.rb +67 -86
- data/spec/connection_spec.rb +98 -150
- data/spec/criteria_spec.rb +4 -3
- data/spec/cursor_spec.rb +33 -27
- data/spec/document_spec.rb +173 -156
- data/spec/embedded_save_spec.rb +8 -3
- data/spec/new_record_spec.rb +33 -121
- metadata +80 -39
- data/lib/mongodoc/parent_proxy.rb +0 -44
- data/lib/mongodoc/proxy.rb +0 -83
- data/spec/parent_proxy_spec.rb +0 -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
|
data/lib/mongodoc/proxy.rb
DELETED
@@ -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
|
data/spec/parent_proxy_spec.rb
DELETED
@@ -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
|
data/spec/proxy_spec.rb
DELETED
@@ -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
|