mongodoc 0.1.2 → 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.
- data/README.textile +143 -0
- data/Rakefile +35 -3
- data/VERSION +1 -1
- data/examples/simple_document.rb +35 -0
- data/examples/simple_object.rb +32 -0
- data/features/finders.feature +72 -0
- data/features/mongodoc_base.feature +12 -2
- data/features/named_scopes.feature +66 -0
- data/features/new_record.feature +36 -0
- data/features/partial_updates.feature +105 -0
- data/features/step_definitions/criteria_steps.rb +4 -41
- data/features/step_definitions/document_steps.rb +56 -5
- data/features/step_definitions/documents.rb +14 -3
- data/features/step_definitions/finder_steps.rb +15 -0
- data/features/step_definitions/named_scope_steps.rb +18 -0
- data/features/step_definitions/partial_update_steps.rb +32 -0
- data/features/step_definitions/query_steps.rb +51 -0
- data/features/using_criteria.feature +5 -1
- data/lib/mongodoc/attributes.rb +76 -63
- data/lib/mongodoc/collection.rb +9 -9
- data/lib/mongodoc/criteria.rb +152 -161
- data/lib/mongodoc/cursor.rb +7 -5
- data/lib/mongodoc/document.rb +95 -31
- data/lib/mongodoc/finders.rb +29 -0
- data/lib/mongodoc/named_scope.rb +68 -0
- data/lib/mongodoc/parent_proxy.rb +15 -6
- data/lib/mongodoc/proxy.rb +22 -13
- data/lib/mongodoc.rb +3 -3
- data/mongodoc.gemspec +42 -14
- data/perf/mongodoc_runner.rb +90 -0
- data/perf/ruby_driver_runner.rb +64 -0
- data/spec/attributes_spec.rb +46 -12
- data/spec/collection_spec.rb +23 -23
- data/spec/criteria_spec.rb +124 -187
- data/spec/cursor_spec.rb +21 -17
- data/spec/document_ext.rb +2 -2
- data/spec/document_spec.rb +187 -218
- data/spec/embedded_save_spec.rb +104 -0
- data/spec/finders_spec.rb +81 -0
- data/spec/hash_matchers.rb +27 -0
- data/spec/named_scope_spec.rb +82 -0
- data/spec/new_record_spec.rb +216 -0
- data/spec/parent_proxy_spec.rb +8 -6
- data/spec/proxy_spec.rb +80 -0
- data/spec/spec_helper.rb +2 -0
- metadata +35 -7
- data/README.rdoc +0 -75
@@ -0,0 +1,68 @@
|
|
1
|
+
# Based on ActiveRecord::NamedScope
|
2
|
+
module MongoDoc
|
3
|
+
module NamedScope
|
4
|
+
def scopes
|
5
|
+
read_inheritable_attribute(:scopes) || write_inheritable_attribute(:scopes, {})
|
6
|
+
end
|
7
|
+
|
8
|
+
def named_scope(name, options = {}, &block)
|
9
|
+
name = name.to_sym
|
10
|
+
scopes[name] = lambda do |parent_scope, *args|
|
11
|
+
CriteriaProxy.new(parent_scope, Hash === options ? options : options.call(*args), &block)
|
12
|
+
end
|
13
|
+
(class << self; self; end).class_eval <<-EOT
|
14
|
+
def #{name}(*args)
|
15
|
+
scopes[:#{name}].call(self, *args)
|
16
|
+
end
|
17
|
+
EOT
|
18
|
+
end
|
19
|
+
|
20
|
+
class CriteriaProxy
|
21
|
+
attr_accessor :conditions, :klass, :parent_scope
|
22
|
+
|
23
|
+
delegate :scopes, :to => :parent_scope
|
24
|
+
|
25
|
+
def initialize(parent_scope, conditions, &block)
|
26
|
+
conditions ||= {}
|
27
|
+
[conditions.delete(:extend)].flatten.each { |extension| extend extension } if conditions.include?(:extend)
|
28
|
+
extend Module.new(&block) if block_given?
|
29
|
+
self.klass = parent_scope unless CriteriaProxy === parent_scope
|
30
|
+
self.parent_scope, self.conditions = parent_scope, conditions
|
31
|
+
end
|
32
|
+
|
33
|
+
def respond_to?(method, include_private = false)
|
34
|
+
super || if klass
|
35
|
+
proxy_found.respond_to?(method, include_private)
|
36
|
+
else
|
37
|
+
parent_scope.respond_to?(method, include_private)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
protected
|
42
|
+
|
43
|
+
def proxy_found
|
44
|
+
@found || load_found
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def method_missing(method, *args, &block)
|
50
|
+
if scopes.include?(method)
|
51
|
+
scopes[method].call(self, *args)
|
52
|
+
elsif klass
|
53
|
+
proxy_found.send(method, *args, &block)
|
54
|
+
else
|
55
|
+
parent_scope.criteria(conditions)
|
56
|
+
parent_scope.send(method, *args, &block)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def load_found
|
61
|
+
@found = Criteria.new(klass)
|
62
|
+
@found.criteria(conditions)
|
63
|
+
@found
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
@@ -9,12 +9,21 @@ module MongoDoc
|
|
9
9
|
@assoc_name = assoc_name
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
13
|
-
|
14
|
-
|
15
|
-
|
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
|
16
26
|
end
|
17
|
-
_parent.path_to_root(assoc_attrs)
|
18
27
|
end
|
19
28
|
|
20
29
|
private
|
@@ -32,4 +41,4 @@ module MongoDoc
|
|
32
41
|
end
|
33
42
|
end
|
34
43
|
end
|
35
|
-
end
|
44
|
+
end
|
data/lib/mongodoc/proxy.rb
CHANGED
@@ -39,15 +39,14 @@ module MongoDoc
|
|
39
39
|
end
|
40
40
|
|
41
41
|
alias_method :append, :<<
|
42
|
-
def <<(
|
43
|
-
|
44
|
-
|
45
|
-
item = collection_class.new(item) if Hash === item
|
46
|
-
raise NotADocumentError unless collection_class === item
|
47
|
-
append item
|
42
|
+
def <<(item)
|
43
|
+
item = build(item) if Hash === item
|
44
|
+
if Document === item
|
48
45
|
item._parent = self
|
49
46
|
item._root = _root
|
47
|
+
_root.send(:register_save_observer, item)
|
50
48
|
end
|
49
|
+
append item
|
51
50
|
self
|
52
51
|
end
|
53
52
|
alias_method :push, :<<
|
@@ -60,15 +59,25 @@ module MongoDoc
|
|
60
59
|
end
|
61
60
|
alias kind_of? is_a?
|
62
61
|
|
63
|
-
def
|
64
|
-
|
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)
|
65
69
|
end
|
66
70
|
|
67
|
-
|
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
|
68
78
|
|
69
|
-
def
|
70
|
-
|
71
|
-
false
|
79
|
+
def build(attrs)
|
80
|
+
collection_class.new(attrs)
|
72
81
|
end
|
73
82
|
end
|
74
|
-
end
|
83
|
+
end
|
data/lib/mongodoc.rb
CHANGED
data/mongodoc.gemspec
CHANGED
@@ -5,35 +5,45 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{mongodoc}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Les Hill"]
|
12
|
-
s.date = %q{
|
12
|
+
s.date = %q{2010-01-18}
|
13
13
|
s.description = %q{ODM for MongoDB}
|
14
14
|
s.email = %q{leshill@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE",
|
17
|
-
"README.
|
17
|
+
"README.textile"
|
18
18
|
]
|
19
19
|
s.files = [
|
20
20
|
".document",
|
21
21
|
".gitignore",
|
22
22
|
"LICENSE",
|
23
|
-
"README.
|
23
|
+
"README.textile",
|
24
24
|
"Rakefile",
|
25
25
|
"VERSION",
|
26
26
|
"data/.gitignore",
|
27
|
+
"examples/simple_document.rb",
|
28
|
+
"examples/simple_object.rb",
|
29
|
+
"features/finders.feature",
|
27
30
|
"features/mongodb.yml",
|
28
31
|
"features/mongodoc_base.feature",
|
32
|
+
"features/named_scopes.feature",
|
33
|
+
"features/new_record.feature",
|
34
|
+
"features/partial_updates.feature",
|
29
35
|
"features/saving_an_object.feature",
|
30
36
|
"features/step_definitions/collection_steps.rb",
|
31
37
|
"features/step_definitions/criteria_steps.rb",
|
32
38
|
"features/step_definitions/document_steps.rb",
|
33
39
|
"features/step_definitions/documents.rb",
|
40
|
+
"features/step_definitions/finder_steps.rb",
|
34
41
|
"features/step_definitions/json_steps.rb",
|
42
|
+
"features/step_definitions/named_scope_steps.rb",
|
35
43
|
"features/step_definitions/object_steps.rb",
|
36
44
|
"features/step_definitions/objects.rb",
|
45
|
+
"features/step_definitions/partial_update_steps.rb",
|
46
|
+
"features/step_definitions/query_steps.rb",
|
37
47
|
"features/step_definitions/util_steps.rb",
|
38
48
|
"features/support/support.rb",
|
39
49
|
"features/using_criteria.feature",
|
@@ -60,12 +70,16 @@ Gem::Specification.new do |s|
|
|
60
70
|
"lib/mongodoc/ext/string.rb",
|
61
71
|
"lib/mongodoc/ext/symbol.rb",
|
62
72
|
"lib/mongodoc/ext/time.rb",
|
73
|
+
"lib/mongodoc/finders.rb",
|
74
|
+
"lib/mongodoc/named_scope.rb",
|
63
75
|
"lib/mongodoc/parent_proxy.rb",
|
64
76
|
"lib/mongodoc/proxy.rb",
|
65
77
|
"lib/mongodoc/query.rb",
|
66
78
|
"mongod.example.yml",
|
67
79
|
"mongodb.example.yml",
|
68
80
|
"mongodoc.gemspec",
|
81
|
+
"perf/mongodoc_runner.rb",
|
82
|
+
"perf/ruby_driver_runner.rb",
|
69
83
|
"script/console",
|
70
84
|
"spec/attributes_spec.rb",
|
71
85
|
"spec/bson_matchers.rb",
|
@@ -76,9 +90,15 @@ Gem::Specification.new do |s|
|
|
76
90
|
"spec/cursor_spec.rb",
|
77
91
|
"spec/document_ext.rb",
|
78
92
|
"spec/document_spec.rb",
|
93
|
+
"spec/embedded_save_spec.rb",
|
94
|
+
"spec/finders_spec.rb",
|
95
|
+
"spec/hash_matchers.rb",
|
79
96
|
"spec/mongodb.yml",
|
80
97
|
"spec/mongodb_pairs.yml",
|
98
|
+
"spec/named_scope_spec.rb",
|
99
|
+
"spec/new_record_spec.rb",
|
81
100
|
"spec/parent_proxy_spec.rb",
|
101
|
+
"spec/proxy_spec.rb",
|
82
102
|
"spec/query_spec.rb",
|
83
103
|
"spec/spec.opts",
|
84
104
|
"spec/spec_helper.rb"
|
@@ -98,9 +118,17 @@ Gem::Specification.new do |s|
|
|
98
118
|
"spec/cursor_spec.rb",
|
99
119
|
"spec/document_ext.rb",
|
100
120
|
"spec/document_spec.rb",
|
121
|
+
"spec/embedded_save_spec.rb",
|
122
|
+
"spec/finders_spec.rb",
|
123
|
+
"spec/hash_matchers.rb",
|
124
|
+
"spec/named_scope_spec.rb",
|
125
|
+
"spec/new_record_spec.rb",
|
101
126
|
"spec/parent_proxy_spec.rb",
|
127
|
+
"spec/proxy_spec.rb",
|
102
128
|
"spec/query_spec.rb",
|
103
|
-
"spec/spec_helper.rb"
|
129
|
+
"spec/spec_helper.rb",
|
130
|
+
"examples/simple_document.rb",
|
131
|
+
"examples/simple_object.rb"
|
104
132
|
]
|
105
133
|
|
106
134
|
if s.respond_to? :specification_version then
|
@@ -108,24 +136,24 @@ Gem::Specification.new do |s|
|
|
108
136
|
s.specification_version = 3
|
109
137
|
|
110
138
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
111
|
-
s.add_runtime_dependency(%q<mongo>, ["= 0.18.
|
112
|
-
s.add_runtime_dependency(%q<mongo_ext>, ["= 0.18.
|
113
|
-
s.add_runtime_dependency(%q<durran-validatable>, ["= 1.8.
|
139
|
+
s.add_runtime_dependency(%q<mongo>, ["= 0.18.2"])
|
140
|
+
s.add_runtime_dependency(%q<mongo_ext>, ["= 0.18.2"])
|
141
|
+
s.add_runtime_dependency(%q<durran-validatable>, ["= 1.8.4"])
|
114
142
|
s.add_runtime_dependency(%q<leshill-will_paginate>, ["= 2.3.11"])
|
115
143
|
s.add_development_dependency(%q<rspec>, ["= 1.2.9"])
|
116
144
|
s.add_development_dependency(%q<cucumber>, ["= 0.4.4"])
|
117
145
|
else
|
118
|
-
s.add_dependency(%q<mongo>, ["= 0.18.
|
119
|
-
s.add_dependency(%q<mongo_ext>, ["= 0.18.
|
120
|
-
s.add_dependency(%q<durran-validatable>, ["= 1.8.
|
146
|
+
s.add_dependency(%q<mongo>, ["= 0.18.2"])
|
147
|
+
s.add_dependency(%q<mongo_ext>, ["= 0.18.2"])
|
148
|
+
s.add_dependency(%q<durran-validatable>, ["= 1.8.4"])
|
121
149
|
s.add_dependency(%q<leshill-will_paginate>, ["= 2.3.11"])
|
122
150
|
s.add_dependency(%q<rspec>, ["= 1.2.9"])
|
123
151
|
s.add_dependency(%q<cucumber>, ["= 0.4.4"])
|
124
152
|
end
|
125
153
|
else
|
126
|
-
s.add_dependency(%q<mongo>, ["= 0.18.
|
127
|
-
s.add_dependency(%q<mongo_ext>, ["= 0.18.
|
128
|
-
s.add_dependency(%q<durran-validatable>, ["= 1.8.
|
154
|
+
s.add_dependency(%q<mongo>, ["= 0.18.2"])
|
155
|
+
s.add_dependency(%q<mongo_ext>, ["= 0.18.2"])
|
156
|
+
s.add_dependency(%q<durran-validatable>, ["= 1.8.4"])
|
129
157
|
s.add_dependency(%q<leshill-will_paginate>, ["= 2.3.11"])
|
130
158
|
s.add_dependency(%q<rspec>, ["= 1.2.9"])
|
131
159
|
s.add_dependency(%q<cucumber>, ["= 0.4.4"])
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require "benchmark"
|
2
|
+
require "ruby-prof"
|
3
|
+
require "mongodoc"
|
4
|
+
|
5
|
+
class Person < MongoDoc::Document
|
6
|
+
key :birth_date
|
7
|
+
has_one :name
|
8
|
+
has_one :address
|
9
|
+
has_many :phones
|
10
|
+
end
|
11
|
+
|
12
|
+
class Name < MongoDoc::Document
|
13
|
+
key :given
|
14
|
+
key :family
|
15
|
+
key :middle
|
16
|
+
end
|
17
|
+
|
18
|
+
class Address < MongoDoc::Document
|
19
|
+
key :street
|
20
|
+
key :city
|
21
|
+
key :state
|
22
|
+
key :post_code
|
23
|
+
key :type
|
24
|
+
end
|
25
|
+
|
26
|
+
class Phone < MongoDoc::Document
|
27
|
+
key :country_code
|
28
|
+
key :number
|
29
|
+
key :type
|
30
|
+
end
|
31
|
+
|
32
|
+
class MongoDocRunner
|
33
|
+
def self.benchmark
|
34
|
+
MongoDoc.connect_to_database('mongodoc_perf_test')
|
35
|
+
MongoDoc.database.collection('people').drop
|
36
|
+
|
37
|
+
puts "Starting benchmark..."
|
38
|
+
|
39
|
+
10.times do |n|
|
40
|
+
person = Person.new(:birth_date => Date.new(1970, 1, 1))
|
41
|
+
name = Name.new(:given => "James", :family => "Kirk", :middle => "Tiberius")
|
42
|
+
address = Address.new(:street => "1 Starfleet Command Way", :city => "San Francisco", :state => "CA", :post_code => "94133", :type => "Work")
|
43
|
+
phone = Phone.new(:country_code => 1, :number => "415-555-1212", :type => "Mobile")
|
44
|
+
person.name = name
|
45
|
+
person.address = address
|
46
|
+
person.phones << phone
|
47
|
+
person.save
|
48
|
+
end
|
49
|
+
|
50
|
+
Benchmark.bm do |bm|
|
51
|
+
bm.report('MongoDoc') do
|
52
|
+
10000.times do |n|
|
53
|
+
person = Person.new(:birth_date => Date.new(1970, 1, 1))
|
54
|
+
name = Name.new(:given => "James", :family => "Kirk", :middle => "Tiberius")
|
55
|
+
address = Address.new(:street => "1 Starfleet Command Way", :city => "San Francisco", :state => "CA", :post_code => "94133", :type => "Work")
|
56
|
+
phone = Phone.new(:country_code => 1, :number => "415-555-1212", :type => "Mobile")
|
57
|
+
person.name = name
|
58
|
+
person.address = address
|
59
|
+
person.phones << phone
|
60
|
+
person.save
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.profile
|
68
|
+
MongoDoc.connect_to_database('mongodoc_perf_test')
|
69
|
+
MongoDoc.database.collection('people').drop
|
70
|
+
|
71
|
+
RubyProf.start
|
72
|
+
|
73
|
+
puts "Starting profiler..."
|
74
|
+
|
75
|
+
1000.times do |n|
|
76
|
+
person = Person.new(:birth_date => Date.new(1970, 1, 1))
|
77
|
+
name = Name.new(:given => "James", :family => "Kirk", :middle => "Tiberius")
|
78
|
+
address = Address.new(:street => "1 Starfleet Command Way", :city => "San Francisco", :state => "CA", :post_code => "94133", :type => "Work")
|
79
|
+
phone = Phone.new(:country_code => 1, :number => "415-555-1212", :type => "Mobile")
|
80
|
+
person.name = name
|
81
|
+
person.address = address
|
82
|
+
person.phones << phone
|
83
|
+
person.save
|
84
|
+
end
|
85
|
+
|
86
|
+
result = RubyProf.stop
|
87
|
+
printer = RubyProf::FlatPrinter.new(result)
|
88
|
+
printer.print(STDOUT, 0)
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "ruby-prof"
|
3
|
+
require "mongodoc"
|
4
|
+
|
5
|
+
class RubyDriverRunner
|
6
|
+
def self.benchmark
|
7
|
+
MongoDoc.connect_to_database('mongodoc_perf_test')
|
8
|
+
collection = MongoDoc.database.collection('people')
|
9
|
+
collection.drop
|
10
|
+
|
11
|
+
puts "Starting benchmark..."
|
12
|
+
|
13
|
+
10.times do |n|
|
14
|
+
person = {:birth_date => Date.new(1970, 1, 1).to_bson, :phones => []}
|
15
|
+
name = {:given => "James", :family => "Kirk", :middle => "Tiberius"}
|
16
|
+
address = {:street => "1 Starfleet Command Way", :city => "San Francisco", :state => "CA", :post_code => "94133", :type => "Work"}
|
17
|
+
phone = {:country_code => 1, :number => "415-555-1212", :type => "Mobile"}
|
18
|
+
person[:name] = name
|
19
|
+
person[:address] = address
|
20
|
+
person[:phones] << phone
|
21
|
+
collection.save(person)
|
22
|
+
end
|
23
|
+
|
24
|
+
Benchmark.bm do |bm|
|
25
|
+
bm.report('Driver') do
|
26
|
+
10000.times do |n|
|
27
|
+
person = {:birth_date => Date.new(1970, 1, 1).to_bson, :phones => []}
|
28
|
+
name = {:given => "James", :family => "Kirk", :middle => "Tiberius"}
|
29
|
+
address = {:street => "1 Starfleet Command Way", :city => "San Francisco", :state => "CA", :post_code => "94133", :type => "Work"}
|
30
|
+
phone = {:country_code => 1, :number => "415-555-1212", :type => "Mobile"}
|
31
|
+
person[:name] = name
|
32
|
+
person[:address] = address
|
33
|
+
person[:phones] << phone
|
34
|
+
collection.save(person)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.profile
|
41
|
+
MongoDoc.connect_to_database('mongodoc_perf_test')
|
42
|
+
collection = MongoDoc.database.collection('people')
|
43
|
+
collection.drop
|
44
|
+
|
45
|
+
RubyProf.start
|
46
|
+
|
47
|
+
puts "Starting profiler..."
|
48
|
+
|
49
|
+
1000.times do |n|
|
50
|
+
person = {:birth_date => Date.new(1970, 1, 1), :phones => []}
|
51
|
+
name = {:given => "James", :family => "Kirk", :middle => "Tiberius"}
|
52
|
+
address = { :street => "1 Starfleet Command Way", :city => "San Francisco", :state => "CA", :post_code => "94133", :type => "Work"}
|
53
|
+
phone = {:country_code => 1, :number => "415-555-1212", :type => "Mobile"}
|
54
|
+
person[:name] = name
|
55
|
+
person[:address] = address
|
56
|
+
person[:phones] << phone
|
57
|
+
collection.insert(person)
|
58
|
+
end
|
59
|
+
|
60
|
+
result = RubyProf.stop
|
61
|
+
printer = RubyProf::FlatPrinter.new(result)
|
62
|
+
printer.print(STDOUT, 0)
|
63
|
+
end
|
64
|
+
end
|
data/spec/attributes_spec.rb
CHANGED
@@ -1,8 +1,18 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
|
3
3
|
describe "MongoDoc::Attributes" do
|
4
|
+
class AttributesTest
|
5
|
+
include MongoDoc::Attributes
|
6
|
+
end
|
7
|
+
|
8
|
+
it "defines _id attribute" do
|
9
|
+
AttributesTest.new.should respond_to(:_id)
|
10
|
+
AttributesTest.new.should respond_to(:_id=)
|
11
|
+
end
|
12
|
+
|
4
13
|
context ".key" do
|
5
|
-
class TestKeys
|
14
|
+
class TestKeys
|
15
|
+
include MongoDoc::Document
|
6
16
|
end
|
7
17
|
|
8
18
|
it "adds its arguments to _keys" do
|
@@ -28,7 +38,9 @@ describe "MongoDoc::Attributes" do
|
|
28
38
|
end
|
29
39
|
|
30
40
|
describe "used with inheritance" do
|
31
|
-
class TestParent
|
41
|
+
class TestParent
|
42
|
+
include MongoDoc::Document
|
43
|
+
|
32
44
|
key :parent_attr
|
33
45
|
end
|
34
46
|
|
@@ -43,15 +55,23 @@ describe "MongoDoc::Attributes" do
|
|
43
55
|
it "has the keys from the parent class" do
|
44
56
|
TestChild._keys.should include(*TestParent._keys)
|
45
57
|
end
|
58
|
+
|
59
|
+
it "does not add keys to the parent class" do
|
60
|
+
TestParent._keys.should_not include(:child_attr)
|
61
|
+
end
|
46
62
|
end
|
47
63
|
end
|
48
64
|
|
49
65
|
context ".has_one" do
|
50
|
-
class TestDoc
|
66
|
+
class TestDoc
|
67
|
+
include MongoDoc::Document
|
68
|
+
|
51
69
|
has_one :subdoc
|
52
70
|
end
|
53
71
|
|
54
|
-
class SubDoc
|
72
|
+
class SubDoc
|
73
|
+
include MongoDoc::Document
|
74
|
+
|
55
75
|
key :data
|
56
76
|
end
|
57
77
|
|
@@ -77,7 +97,9 @@ describe "MongoDoc::Attributes" do
|
|
77
97
|
subdoc._root.should == doc
|
78
98
|
end
|
79
99
|
|
80
|
-
class HasOneValidationTest
|
100
|
+
class HasOneValidationTest
|
101
|
+
include MongoDoc::Document
|
102
|
+
|
81
103
|
key :data
|
82
104
|
validates_presence_of :data
|
83
105
|
end
|
@@ -90,7 +112,9 @@ describe "MongoDoc::Attributes" do
|
|
90
112
|
end
|
91
113
|
|
92
114
|
context "._attributes" do
|
93
|
-
class TestHasOneDoc
|
115
|
+
class TestHasOneDoc
|
116
|
+
include MongoDoc::Document
|
117
|
+
|
94
118
|
key :key
|
95
119
|
has_one :has_one
|
96
120
|
end
|
@@ -102,15 +126,21 @@ describe "MongoDoc::Attributes" do
|
|
102
126
|
|
103
127
|
context ".has_many" do
|
104
128
|
|
105
|
-
class SubHasManyDoc
|
129
|
+
class SubHasManyDoc
|
130
|
+
include MongoDoc::Document
|
131
|
+
|
106
132
|
key :data
|
107
133
|
end
|
108
134
|
|
109
|
-
class TestHasManyDoc
|
135
|
+
class TestHasManyDoc
|
136
|
+
include MongoDoc::Document
|
137
|
+
|
110
138
|
has_many :sub_docs, :class_name => 'SubHasManyDoc'
|
111
139
|
end
|
112
140
|
|
113
|
-
class TestImplicitHasManyDoc
|
141
|
+
class TestImplicitHasManyDoc
|
142
|
+
include MongoDoc::Document
|
143
|
+
|
114
144
|
has_many :sub_has_many_docs
|
115
145
|
end
|
116
146
|
|
@@ -135,12 +165,16 @@ describe "MongoDoc::Attributes" do
|
|
135
165
|
doc = TestImplicitHasManyDoc.new(:sub_has_many_docs => [subdoc])
|
136
166
|
end
|
137
167
|
|
138
|
-
class HasManyValidationChild
|
168
|
+
class HasManyValidationChild
|
169
|
+
include MongoDoc::Document
|
170
|
+
|
139
171
|
key :data
|
140
172
|
validates_presence_of :data
|
141
173
|
end
|
142
174
|
|
143
|
-
class HasManyValidationTest
|
175
|
+
class HasManyValidationTest
|
176
|
+
include MongoDoc::Document
|
177
|
+
|
144
178
|
has_many :subdocs, :class_name => 'HasManyValidationChild'
|
145
179
|
end
|
146
180
|
|
@@ -156,4 +190,4 @@ describe "MongoDoc::Attributes" do
|
|
156
190
|
invalid.should have(1).error_on(:data)
|
157
191
|
end
|
158
192
|
end
|
159
|
-
end
|
193
|
+
end
|