mongo_doc 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +7 -0
- data/LICENSE +20 -0
- data/README.textile +174 -0
- data/Rakefile +135 -0
- data/TODO +31 -0
- data/VERSION +1 -0
- data/data/.gitignore +2 -0
- data/examples/simple_document.rb +35 -0
- data/examples/simple_object.rb +30 -0
- data/features/finders.feature +76 -0
- data/features/mongodb.yml +7 -0
- data/features/mongodoc_base.feature +128 -0
- data/features/new_record.feature +36 -0
- data/features/partial_updates.feature +105 -0
- data/features/removing_documents.feature +68 -0
- data/features/saving_an_object.feature +15 -0
- data/features/scopes.feature +66 -0
- data/features/step_definitions/collection_steps.rb +14 -0
- data/features/step_definitions/document_steps.rb +149 -0
- data/features/step_definitions/documents.rb +30 -0
- data/features/step_definitions/finder_steps.rb +15 -0
- data/features/step_definitions/json_steps.rb +9 -0
- data/features/step_definitions/object_steps.rb +50 -0
- data/features/step_definitions/objects.rb +24 -0
- data/features/step_definitions/partial_update_steps.rb +32 -0
- data/features/step_definitions/query_steps.rb +54 -0
- data/features/step_definitions/removing_documents_steps.rb +14 -0
- data/features/step_definitions/scope_steps.rb +18 -0
- data/features/step_definitions/util_steps.rb +7 -0
- data/features/support/support.rb +10 -0
- data/features/using_criteria.feature +128 -0
- data/lib/mongo_doc/associations/collection_proxy.rb +105 -0
- data/lib/mongo_doc/associations/document_proxy.rb +56 -0
- data/lib/mongo_doc/associations/hash_proxy.rb +98 -0
- data/lib/mongo_doc/associations/proxy_base.rb +53 -0
- data/lib/mongo_doc/attributes.rb +140 -0
- data/lib/mongo_doc/bson.rb +45 -0
- data/lib/mongo_doc/collection.rb +55 -0
- data/lib/mongo_doc/connection.rb +88 -0
- data/lib/mongo_doc/contexts/enumerable.rb +128 -0
- data/lib/mongo_doc/contexts/ids.rb +41 -0
- data/lib/mongo_doc/contexts/mongo.rb +232 -0
- data/lib/mongo_doc/contexts.rb +25 -0
- data/lib/mongo_doc/criteria.rb +38 -0
- data/lib/mongo_doc/cursor.rb +32 -0
- data/lib/mongo_doc/document.rb +216 -0
- data/lib/mongo_doc/ext/array.rb +5 -0
- data/lib/mongo_doc/ext/binary.rb +7 -0
- data/lib/mongo_doc/ext/boolean_class.rb +11 -0
- data/lib/mongo_doc/ext/date.rb +16 -0
- data/lib/mongo_doc/ext/date_time.rb +13 -0
- data/lib/mongo_doc/ext/dbref.rb +7 -0
- data/lib/mongo_doc/ext/hash.rb +7 -0
- data/lib/mongo_doc/ext/nil_class.rb +5 -0
- data/lib/mongo_doc/ext/numeric.rb +17 -0
- data/lib/mongo_doc/ext/object.rb +17 -0
- data/lib/mongo_doc/ext/object_id.rb +7 -0
- data/lib/mongo_doc/ext/regexp.rb +5 -0
- data/lib/mongo_doc/ext/string.rb +5 -0
- data/lib/mongo_doc/ext/symbol.rb +5 -0
- data/lib/mongo_doc/ext/time.rb +5 -0
- data/lib/mongo_doc/finders.rb +49 -0
- data/lib/mongo_doc/matchers.rb +35 -0
- data/lib/mongo_doc/query.rb +7 -0
- data/lib/mongo_doc/scope.rb +64 -0
- data/lib/mongo_doc/validations/macros.rb +11 -0
- data/lib/mongo_doc/validations/validates_embedded.rb +13 -0
- data/lib/mongo_doc.rb +19 -0
- data/lib/mongoid/contexts/paging.rb +42 -0
- data/lib/mongoid/criteria.rb +247 -0
- data/lib/mongoid/criterion/complex.rb +21 -0
- data/lib/mongoid/criterion/exclusion.rb +65 -0
- data/lib/mongoid/criterion/inclusion.rb +92 -0
- data/lib/mongoid/criterion/optional.rb +136 -0
- data/lib/mongoid/extensions/hash/criteria_helpers.rb +20 -0
- data/lib/mongoid/extensions/symbol/inflections.rb +36 -0
- data/lib/mongoid/matchers/all.rb +11 -0
- data/lib/mongoid/matchers/default.rb +26 -0
- data/lib/mongoid/matchers/exists.rb +13 -0
- data/lib/mongoid/matchers/gt.rb +11 -0
- data/lib/mongoid/matchers/gte.rb +11 -0
- data/lib/mongoid/matchers/in.rb +11 -0
- data/lib/mongoid/matchers/lt.rb +11 -0
- data/lib/mongoid/matchers/lte.rb +11 -0
- data/lib/mongoid/matchers/ne.rb +11 -0
- data/lib/mongoid/matchers/nin.rb +11 -0
- data/lib/mongoid/matchers/size.rb +11 -0
- data/mongo_doc.gemspec +205 -0
- data/mongod.example.yml +2 -0
- data/mongodb.example.yml +14 -0
- data/perf/mongo_doc_runner.rb +90 -0
- data/perf/ruby_driver_runner.rb +64 -0
- data/script/console +8 -0
- 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 +273 -0
- data/spec/bson_matchers.rb +54 -0
- data/spec/bson_spec.rb +196 -0
- data/spec/collection_spec.rb +161 -0
- data/spec/connection_spec.rb +147 -0
- data/spec/contexts/enumerable_spec.rb +274 -0
- data/spec/contexts/ids_spec.rb +49 -0
- data/spec/contexts/mongo_spec.rb +198 -0
- data/spec/contexts_spec.rb +28 -0
- data/spec/criteria_spec.rb +33 -0
- data/spec/cursor_spec.rb +91 -0
- data/spec/document_ext.rb +9 -0
- data/spec/document_spec.rb +664 -0
- data/spec/embedded_save_spec.rb +109 -0
- data/spec/finders_spec.rb +73 -0
- data/spec/hash_matchers.rb +27 -0
- data/spec/matchers_spec.rb +342 -0
- data/spec/mongodb.yml +6 -0
- data/spec/mongodb_pairs.yml +8 -0
- data/spec/new_record_spec.rb +128 -0
- data/spec/query_spec.rb +12 -0
- data/spec/scope_spec.rb +79 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +13 -0
- metadata +290 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
Feature: New record
|
2
|
+
|
3
|
+
Scenario: saving a has_many children document
|
4
|
+
Given an empty Contact document collection
|
5
|
+
And a Contact document named 'hashrocket' :
|
6
|
+
| Name |
|
7
|
+
| Hashrocket |
|
8
|
+
And 'hashrocket' has many addresses :
|
9
|
+
| Street | City | State | Zip Code |
|
10
|
+
| 320 First Street North | Jacksonville Beach | FL | 32250 |
|
11
|
+
| 1 Main Street | Santiago | Chile | |
|
12
|
+
When I save the document 'hashrocket'
|
13
|
+
Then the first address of 'hashrocket' is not a new record
|
14
|
+
|
15
|
+
Scenario: saving a has_one child document
|
16
|
+
Given an empty Place document collection
|
17
|
+
And a Place document named 'hashrocket' :
|
18
|
+
| Name |
|
19
|
+
| Hashrocket |
|
20
|
+
And 'hashrocket' has one Address as address :
|
21
|
+
| Street | City | State | Zip Code |
|
22
|
+
| 320 First Street North | Jacksonville Beach | FL | 32250 |
|
23
|
+
When I save the document 'hashrocket'
|
24
|
+
Then the address of 'hashrocket' is not a new record
|
25
|
+
|
26
|
+
Scenario: id is roundtripped when saving a has_one child document
|
27
|
+
Given an empty Place document collection
|
28
|
+
And a Place document named 'hashrocket' :
|
29
|
+
| Name |
|
30
|
+
| Hashrocket |
|
31
|
+
And 'hashrocket' has one Address as address :
|
32
|
+
| Street | City | State | Zip Code |
|
33
|
+
| 320 First Street North | Jacksonville Beach | FL | 32250 |
|
34
|
+
When I save the document 'hashrocket'
|
35
|
+
Then the address of 'hashrocket' roundtrips
|
36
|
+
|
@@ -0,0 +1,105 @@
|
|
1
|
+
Feature: Partial Updates
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given an empty Contact document collection
|
5
|
+
And a Contact document named 'hashrocket' :
|
6
|
+
| Name | Type | Note |
|
7
|
+
| Hashrocket | company | Premier Rails development shop! |
|
8
|
+
And 'hashrocket' has interests, an array of:
|
9
|
+
| Interest |
|
10
|
+
| ruby |
|
11
|
+
| rails |
|
12
|
+
| employment |
|
13
|
+
| contract work |
|
14
|
+
| restaurants |
|
15
|
+
| hotels |
|
16
|
+
| flights |
|
17
|
+
| car rentals |
|
18
|
+
And 'hashrocket' has many addresses :
|
19
|
+
| Street | City | State | Zip Code |
|
20
|
+
| 320 First Street North | Jacksonville Beach | FL | 32250 |
|
21
|
+
| 1 Lake Michigan Street | Chicago | IL | 60611 |
|
22
|
+
| 1 Main Street | Santiago | Chile | |
|
23
|
+
And I save the document 'hashrocket'
|
24
|
+
And a Contact document named 'rocketeer' :
|
25
|
+
| Name | Note |
|
26
|
+
| Rocketeer Mike | Fantastic developer |
|
27
|
+
And 'rocketeer' has interests, an array of:
|
28
|
+
| Interest |
|
29
|
+
| ruby |
|
30
|
+
| rails |
|
31
|
+
| restaurants |
|
32
|
+
| employment |
|
33
|
+
And 'rocketeer' has many addresses :
|
34
|
+
| Street | City | State | Zip Code |
|
35
|
+
| 1 Main Street | Atlantic Beach | FL | 32233 |
|
36
|
+
And I save the document 'rocketeer'
|
37
|
+
And a Contact document named 'contractor' :
|
38
|
+
| Name | Note |
|
39
|
+
| Contractor Joe | Knows MongoDB |
|
40
|
+
And 'contractor' has interests, an array of:
|
41
|
+
| Interest |
|
42
|
+
| ruby |
|
43
|
+
| rails |
|
44
|
+
| contract work |
|
45
|
+
| flights |
|
46
|
+
| car rentals |
|
47
|
+
| hotels |
|
48
|
+
| restaurants |
|
49
|
+
And 'contractor' has many addresses :
|
50
|
+
| Street | City | State | Zip Code |
|
51
|
+
| 1 Main St. | Jacksonville | FL | 32218 |
|
52
|
+
And I save the document 'contractor'
|
53
|
+
And an empty Place document collection
|
54
|
+
And a Place document named 'hashrocket_hq' :
|
55
|
+
| Name | Type |
|
56
|
+
| Hashrocket | company |
|
57
|
+
And 'hashrocket_hq' has one Address as address (identified by 'hq_address'):
|
58
|
+
| Street | City | State | Zip Code |
|
59
|
+
| 1 Main St. | Jacksonville | FL | 32218 |
|
60
|
+
And I save the document 'hashrocket_hq'
|
61
|
+
|
62
|
+
Scenario: Naive Update
|
63
|
+
When I update the 'note' for 'contractor' to 'Knows MongoDB and MongoDoc'
|
64
|
+
Then the document 'contractor' roundtrips
|
65
|
+
|
66
|
+
Scenario: Naive Update on a has one
|
67
|
+
When I update the 'street' for 'hq_address' to '320 1st Street North'
|
68
|
+
Then the document 'hashrocket_hq' roundtrips
|
69
|
+
|
70
|
+
Scenario: Naive Update on a has many
|
71
|
+
When 'hq_address' is the first address of 'hashrocket'
|
72
|
+
And I update the 'street' for 'hq_address' to '320 1st Street North'
|
73
|
+
Then the document 'hashrocket' roundtrips
|
74
|
+
|
75
|
+
Scenario: Strict Update
|
76
|
+
When I strict update the 'note' for 'contractor' to 'Knows MongoDB and MongoDoc'
|
77
|
+
Then the document 'contractor' roundtrips
|
78
|
+
|
79
|
+
Scenario: Strict Update on a has one
|
80
|
+
When I strict update the 'street' for 'hq_address' to '320 1st Street North'
|
81
|
+
Then the document 'hashrocket_hq' roundtrips
|
82
|
+
|
83
|
+
Scenario: Strict Update on a has many
|
84
|
+
When 'hq_address' is the first address of 'hashrocket'
|
85
|
+
And I strict update the 'street' for 'hq_address' to '320 1st Street North'
|
86
|
+
Then the document 'hashrocket' roundtrips
|
87
|
+
|
88
|
+
Scenario: Failing Strict Update on a has one
|
89
|
+
When someone else changes the Address 'address' of 'hashrocket_hq' to
|
90
|
+
| Street | City | State | Zip Code |
|
91
|
+
| 1 Ocean Blvd. | Jacksonville | FL | 32218 |
|
92
|
+
And I strict update the 'street' for 'hq_address' to '320 1st Street North'
|
93
|
+
Then the last return value is false
|
94
|
+
And the document 'hashrocket_hq' does not roundtrip
|
95
|
+
|
96
|
+
Scenario: Failing Strict Update on a has many
|
97
|
+
When 'hq_address' is the first address of 'hashrocket'
|
98
|
+
And someone else changes the addresses of 'hashrocket':
|
99
|
+
| Street | City | State | Zip Code |
|
100
|
+
| 320 1st N, #712 | Jacksonville Beach | FL | 32250 |
|
101
|
+
| 1001 Mulligan Street | Chicago | IL | 60611 |
|
102
|
+
| 345 Avenida Grande | Santiago | Chile | |
|
103
|
+
And I strict update the 'street' for 'hq_address' to '320 1st Street North'
|
104
|
+
Then the last return value is false
|
105
|
+
And the document 'hashrocket' does not roundtrip
|
@@ -0,0 +1,68 @@
|
|
1
|
+
Feature: Removing Documents
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given an empty Contact document collection
|
5
|
+
And a Contact document named 'hashrocket' :
|
6
|
+
| Name | Type | Note |
|
7
|
+
| Hashrocket | company | Premier Rails development shop! |
|
8
|
+
And 'hashrocket' has interests, an array of:
|
9
|
+
| Interest |
|
10
|
+
| ruby |
|
11
|
+
| rails |
|
12
|
+
| employment |
|
13
|
+
| contract work |
|
14
|
+
| restaurants |
|
15
|
+
| hotels |
|
16
|
+
| flights |
|
17
|
+
| car rentals |
|
18
|
+
And 'hashrocket' has many addresses :
|
19
|
+
| Street | City | State | Zip Code |
|
20
|
+
| 320 First Street North | Jacksonville Beach | FL | 32250 |
|
21
|
+
| 1 Lake Michigan Street | Chicago | IL | 60611 |
|
22
|
+
| 1 Main Street | Santiago | Chile | |
|
23
|
+
And I save the document 'hashrocket'
|
24
|
+
And a Contact document named 'rocketeer' :
|
25
|
+
| Name | Note |
|
26
|
+
| Rocketeer Mike | Fantastic developer |
|
27
|
+
And 'rocketeer' has interests, an array of:
|
28
|
+
| Interest |
|
29
|
+
| ruby |
|
30
|
+
| rails |
|
31
|
+
| restaurants |
|
32
|
+
| employment |
|
33
|
+
And 'rocketeer' has many addresses :
|
34
|
+
| Street | City | State | Zip Code |
|
35
|
+
| 1 Main Street | Atlantic Beach | FL | 32233 |
|
36
|
+
And I save the document 'rocketeer'
|
37
|
+
And a Contact document named 'contractor' :
|
38
|
+
| Name | Note |
|
39
|
+
| Contractor Joe | Knows MongoDB |
|
40
|
+
And 'contractor' has interests, an array of:
|
41
|
+
| Interest |
|
42
|
+
| ruby |
|
43
|
+
| rails |
|
44
|
+
| contract work |
|
45
|
+
| flights |
|
46
|
+
| car rentals |
|
47
|
+
| hotels |
|
48
|
+
| restaurants |
|
49
|
+
And 'contractor' has many addresses :
|
50
|
+
| Street | City | State | Zip Code |
|
51
|
+
| 1 Main St. | Jacksonville | FL | 32218 |
|
52
|
+
And I save the document 'contractor'
|
53
|
+
And a Place document named 'hashrocket_hq' :
|
54
|
+
| Name | Type |
|
55
|
+
| Hashrocket | company |
|
56
|
+
And 'hashrocket_hq' has one Address as address (identified by 'hq_address'):
|
57
|
+
| Street | City | State | Zip Code |
|
58
|
+
| 1 Main St. | Jacksonville | FL | 32218 |
|
59
|
+
And I save the document 'hashrocket_hq'
|
60
|
+
|
61
|
+
Scenario: Simple Remove
|
62
|
+
Given the document 'contractor' roundtrips
|
63
|
+
When I remove 'contractor'
|
64
|
+
Then the document 'contractor' is not found
|
65
|
+
|
66
|
+
Scenario: Embedded Remove
|
67
|
+
When the document 'hashrocket_hq' roundtrips
|
68
|
+
Then an exception is raised if I remove 'hq_address'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Feature: saving an object
|
2
|
+
|
3
|
+
Scenario: saving simple json
|
4
|
+
Given a new collection named 'test'
|
5
|
+
When I save the json '{"name":"name"}'
|
6
|
+
Then the collection should have 1 document
|
7
|
+
And the json '{"name":"name"}' roundtrips
|
8
|
+
|
9
|
+
Scenario: saving a ruby object
|
10
|
+
Given a new collection named 'test'
|
11
|
+
And an object 'movie'
|
12
|
+
When I save the object 'movie'
|
13
|
+
Then the collection should have 1 document
|
14
|
+
And the object 'movie' roundtrips
|
15
|
+
|
@@ -0,0 +1,66 @@
|
|
1
|
+
Feature: Named Scopes
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given an empty Contact document collection
|
5
|
+
And a Contact document named 'hashrocket' :
|
6
|
+
| Name | Type |
|
7
|
+
| Hashrocket | company |
|
8
|
+
And 'hashrocket' has interests, an array of:
|
9
|
+
| Interest |
|
10
|
+
| ruby |
|
11
|
+
| rails |
|
12
|
+
| employment |
|
13
|
+
| contract work |
|
14
|
+
| restaurants |
|
15
|
+
| hotels |
|
16
|
+
| flights |
|
17
|
+
| car rentals |
|
18
|
+
And 'hashrocket' has many addresses :
|
19
|
+
| Street | City | State | Zip Code |
|
20
|
+
| 320 First Street North | Jacksonville Beach | FL | 32250 |
|
21
|
+
| 1 Lake Michigan Street | Chicago | IL | 60611 |
|
22
|
+
| 1 Main Street | Santiago | Chile | |
|
23
|
+
And I save the document 'hashrocket'
|
24
|
+
And a Contact document named 'rocketeer' :
|
25
|
+
| Name |
|
26
|
+
| Rocketeer Mike |
|
27
|
+
And 'rocketeer' has interests, an array of:
|
28
|
+
| Interest |
|
29
|
+
| ruby |
|
30
|
+
| rails |
|
31
|
+
| restaurants |
|
32
|
+
| employment |
|
33
|
+
And 'rocketeer' has many addresses :
|
34
|
+
| Street | City | State | Zip Code |
|
35
|
+
| 1 Main Street | Atlantic Beach | FL | 32233 |
|
36
|
+
And I save the document 'rocketeer'
|
37
|
+
And a Contact document named 'contractor' :
|
38
|
+
| Name |
|
39
|
+
| Contractor Joe |
|
40
|
+
And 'contractor' has interests, an array of:
|
41
|
+
| Interest |
|
42
|
+
| ruby |
|
43
|
+
| rails |
|
44
|
+
| contract work |
|
45
|
+
| flights |
|
46
|
+
| car rentals |
|
47
|
+
| hotels |
|
48
|
+
| restaurants |
|
49
|
+
And 'contractor' has many addresses :
|
50
|
+
| Street | City | State | Zip Code |
|
51
|
+
| 1 Main St. | Jacksonville | FL | 32218 |
|
52
|
+
And I save the document 'contractor'
|
53
|
+
|
54
|
+
Scenario: Simple named scope
|
55
|
+
When I query contacts with scope 'rubyists'
|
56
|
+
Then the query result has 3 documents
|
57
|
+
|
58
|
+
Scenario: Simple chained scope
|
59
|
+
When I query contacts with scopes 'rubyists, contract_work'
|
60
|
+
Then the query result has 2 documents
|
61
|
+
And one of the query results is the document 'contractor'
|
62
|
+
|
63
|
+
Scenario: Named scope with lambda
|
64
|
+
When I query contacts with lambda scope 'in_state' with parameters 'IL'
|
65
|
+
Then the query result has 1 documents
|
66
|
+
And one of the query results is the document 'hashrocket'
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Given /a new collection named '(.*)'/ do |name|
|
2
|
+
MongoDoc::Connection.database.drop_collection(name)
|
3
|
+
@collection = MongoDoc::Collection.new(name)
|
4
|
+
end
|
5
|
+
|
6
|
+
Given /^an empty (\w+) collection$/ do |name|
|
7
|
+
MongoDoc::Connection.database.drop_collection(name)
|
8
|
+
MongoDoc::Connection.database.create_collection(name, :strict => true)
|
9
|
+
end
|
10
|
+
|
11
|
+
Then /the collection should have (\d+) documents?/ do |count|
|
12
|
+
@collection.count.should == count.to_i
|
13
|
+
end
|
14
|
+
|
@@ -0,0 +1,149 @@
|
|
1
|
+
Given /^an empty (\w+) document collection$/ do |doc|
|
2
|
+
klass = doc.constantize
|
3
|
+
Given "an empty #{klass.collection_name} collection"
|
4
|
+
end
|
5
|
+
|
6
|
+
Given /^an? (\w+) document named '(.*)' :$/ do |doc, name, table|
|
7
|
+
@all = []
|
8
|
+
klass = doc.constantize
|
9
|
+
table.hashes.each do |hash|
|
10
|
+
@last = klass.new
|
11
|
+
hash.each do |attr, value|
|
12
|
+
@last.send("#{attr.underscore.gsub(' ', '_')}=", value)
|
13
|
+
end
|
14
|
+
@all << @last
|
15
|
+
end
|
16
|
+
instance_variable_set("@#{name}", @last)
|
17
|
+
end
|
18
|
+
|
19
|
+
Given /^'(.*)' has one (.*?) as (.*) :$/ do |doc_name, class_name, assoc_name, table|
|
20
|
+
doc = instance_variable_get("@#{doc_name}")
|
21
|
+
obj = class_name.constantize.new
|
22
|
+
table.hashes.each do |hash|
|
23
|
+
hash.each do |key, value|
|
24
|
+
obj.send("#{key.underscore.gsub(' ', '_')}=", value)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
doc.send("#{assoc_name.underscore.gsub(' ', '_')}=", obj)
|
28
|
+
@last = obj
|
29
|
+
end
|
30
|
+
|
31
|
+
Given /^'(.*)' has (?:a|an|many) (.*) :$/ do |doc_name, assoc_name, table|
|
32
|
+
doc = instance_variable_get("@#{doc_name}")
|
33
|
+
table.hashes.each do |hash|
|
34
|
+
doc.send(assoc_name).build(hash.inject({}) do |attrs, (attr, value)|
|
35
|
+
attrs["#{attr.underscore.gsub(' ', '_')}"] = value
|
36
|
+
attrs
|
37
|
+
end)
|
38
|
+
end
|
39
|
+
@all = doc.send(assoc_name)
|
40
|
+
@last = @all.last
|
41
|
+
end
|
42
|
+
|
43
|
+
Given /^I set the id on the document '(.*)' to (.*)$/ do |doc_name, value|
|
44
|
+
doc = instance_variable_get("@#{doc_name}")
|
45
|
+
doc._id = Mongo::ObjectID.from_string("%024x" % value.to_i(16))
|
46
|
+
end
|
47
|
+
|
48
|
+
Given /^'(.+)' has one (.+?) as (.+?) \(identified by '(.+)'\):$/ do |doc_name, class_name, assoc_name, var_name, table|
|
49
|
+
doc = instance_variable_get("@#{doc_name}")
|
50
|
+
obj = class_name.constantize.new
|
51
|
+
table.hashes.each do |hash|
|
52
|
+
hash.each do |key, value|
|
53
|
+
obj.send("#{key.underscore.gsub(' ', '_')}=", value)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
instance_variable_set("@#{var_name}", obj)
|
57
|
+
doc.send("#{assoc_name.underscore.gsub(' ', '_')}=", obj)
|
58
|
+
@last = obj
|
59
|
+
end
|
60
|
+
|
61
|
+
When /^I save the document '(.*)'$/ do |name|
|
62
|
+
object = instance_variable_get("@#{name}")
|
63
|
+
@last_return = object.save
|
64
|
+
end
|
65
|
+
|
66
|
+
When /^I save the last document$/ do
|
67
|
+
@last_return = @last.save
|
68
|
+
end
|
69
|
+
|
70
|
+
When /^I create an (.*) '(.*)' from the hash '(.*)'$/ do |doc, name, hash|
|
71
|
+
klass = doc.constantize
|
72
|
+
attrs = instance_variable_get("@#{hash}")
|
73
|
+
instance_variable_set("@#{name}", klass.create(attrs))
|
74
|
+
end
|
75
|
+
|
76
|
+
When /^I update the document '(.*)' with the hash named '(.*)'$/ do |doc_name, hash_name|
|
77
|
+
doc = instance_variable_get("@#{doc_name}")
|
78
|
+
attrs = instance_variable_get("@#{hash_name}")
|
79
|
+
@last_return = doc.update_attributes(attrs)
|
80
|
+
end
|
81
|
+
|
82
|
+
When /^I query (.*) with criteria (.*)$/ do |doc, criteria_text|
|
83
|
+
klass = doc.singularize.camelize
|
84
|
+
@query = @last_return = eval("#{klass}.criteria.#{criteria_text}")
|
85
|
+
end
|
86
|
+
|
87
|
+
When /^I query (.*) with the '(.*)' id$/ do |doc, name|
|
88
|
+
klass = doc.singularize.camelize.constantize
|
89
|
+
doc = instance_variable_get("@#{name}")
|
90
|
+
@query = @last_return = klass.criteria.id(doc.id).entries
|
91
|
+
end
|
92
|
+
|
93
|
+
When /^I find a (.*) using the id of '(.*)'$/ do |type, doc_name|
|
94
|
+
klass = type.camelize.constantize
|
95
|
+
doc = instance_variable_get("@#{doc_name}")
|
96
|
+
@last_return = klass.find(doc.id)
|
97
|
+
end
|
98
|
+
|
99
|
+
When /^'(.+)' is the first (.+?) of '(.+)'$/ do |var_name, single_assoc, doc_name|
|
100
|
+
doc = instance_variable_get("@#{doc_name}")
|
101
|
+
instance_variable_set("@#{var_name}", doc.send(single_assoc.pluralize).first)
|
102
|
+
end
|
103
|
+
|
104
|
+
Then /^'(.*)' is not a new record$/ do |name|
|
105
|
+
instance_variable_get("@#{name}").new_record?.should be_false
|
106
|
+
end
|
107
|
+
|
108
|
+
Then /the (.*) collection should have (\d+) documents?/ do |doc, count|
|
109
|
+
klass = doc.constantize
|
110
|
+
klass.count.should == count.to_i
|
111
|
+
end
|
112
|
+
|
113
|
+
Then /^the document '(.*)' roundtrips$/ do |name|
|
114
|
+
object = instance_variable_get("@#{name}")
|
115
|
+
from_db = object.class.find_one(object._id)
|
116
|
+
from_db.should == object
|
117
|
+
instance_variable_set("@#{name}", from_db)
|
118
|
+
end
|
119
|
+
|
120
|
+
Then /^the document '(.+)' does not roundtrip$/ do |name|
|
121
|
+
object = instance_variable_get("@#{name}")
|
122
|
+
from_db = object.class.find_one(object._id)
|
123
|
+
from_db.should_not == object
|
124
|
+
end
|
125
|
+
|
126
|
+
Then /^the last return value is (.+)$/ do |bool_val|
|
127
|
+
@last_return.should send("be_#{bool_val}")
|
128
|
+
end
|
129
|
+
|
130
|
+
Then /^the first (.*) of '(.*)' is not a new record$/ do |assoc, name|
|
131
|
+
object = instance_variable_get("@#{name}")
|
132
|
+
plural = assoc.pluralize
|
133
|
+
object.send(plural).first.should_not be_new_record
|
134
|
+
end
|
135
|
+
|
136
|
+
Then /^the (\w*) of '(.*)' is not a new record$/ do |assoc, name|
|
137
|
+
object = instance_variable_get("@#{name}")
|
138
|
+
object.send(assoc).should_not be_new_record
|
139
|
+
end
|
140
|
+
|
141
|
+
Then /^the (\w*) of '(.*)' roundtrips$/ do |assoc, name|
|
142
|
+
object = instance_variable_get("@#{name}")
|
143
|
+
from_db = object.class.find_one(object._id)
|
144
|
+
object.send(assoc).id.should == from_db.send(assoc).id
|
145
|
+
end
|
146
|
+
|
147
|
+
Then /^the size of the last return value is (.*)$/ do |count|
|
148
|
+
@last_return.size.should == count.to_i
|
149
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class Address
|
2
|
+
include MongoDoc::Document
|
3
|
+
|
4
|
+
key :street
|
5
|
+
key :city
|
6
|
+
key :state
|
7
|
+
key :zip_code
|
8
|
+
end
|
9
|
+
|
10
|
+
class Place
|
11
|
+
include MongoDoc::Document
|
12
|
+
|
13
|
+
key :name
|
14
|
+
key :type
|
15
|
+
has_one :address
|
16
|
+
end
|
17
|
+
|
18
|
+
class Contact
|
19
|
+
include MongoDoc::Document
|
20
|
+
|
21
|
+
key :name
|
22
|
+
key :type
|
23
|
+
key :note
|
24
|
+
key :interests
|
25
|
+
has_many :addresses
|
26
|
+
|
27
|
+
scope :rubyists, any_in(:interests => ['ruby'])
|
28
|
+
scope :contract_work, any_in(:interests => ['contract work'])
|
29
|
+
scope :in_state, lambda {|state| where('addresses.state' => state)}
|
30
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
def finder_query=(finder)
|
2
|
+
@query = finder
|
3
|
+
end
|
4
|
+
|
5
|
+
When /^I query (.+) with (\w+)$/ do |doc, finder|
|
6
|
+
self.finder_query = klass(doc).send(finder)
|
7
|
+
end
|
8
|
+
|
9
|
+
When /^I query (.+) to find_one with the (.+) of the '(.+)' document$/ do |collection, id, doc_name|
|
10
|
+
self.finder_query = klass(collection).find_one(instance_variable_get("@#{doc_name}").send(id))
|
11
|
+
end
|
12
|
+
|
13
|
+
Then /^the query result was (\d+) documents$/ do |count|
|
14
|
+
query.should == count.to_i
|
15
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
When /^I save the json '(\{.*\})'$/ do |json_text|
|
2
|
+
json = JSON.parse(json_text)
|
3
|
+
@last_save = @collection.save(json)
|
4
|
+
end
|
5
|
+
|
6
|
+
Then /^the json '(\{.*\})' roundtrips$/ do |json_text|
|
7
|
+
json = JSON.parse(json_text)
|
8
|
+
@collection.find_one(@last_save).should be_mongo_eql(json, false)
|
9
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
Given /^an object '(.*)'$/ do |name|
|
2
|
+
@movie = Movie.new
|
3
|
+
@movie.title = 'Gone with the Wind'
|
4
|
+
@movie.director = 'Victor Fleming'
|
5
|
+
@movie.writers = ['Sidney Howard']
|
6
|
+
@director = Director.new
|
7
|
+
@director.name = 'Victor Fleming'
|
8
|
+
@award = AcademyAward.new
|
9
|
+
@award.year = '1940'
|
10
|
+
@award.category = 'Best Director'
|
11
|
+
@director.awards = [@award]
|
12
|
+
@movie.director = @director
|
13
|
+
end
|
14
|
+
|
15
|
+
Given /^a hash named '(.*)':$/ do |name, table|
|
16
|
+
@all = []
|
17
|
+
table.hashes.each do |hash|
|
18
|
+
@last = hash.inject({}) do |h, (key, value)|
|
19
|
+
h["#{key.underscore.gsub(' ', '_')}"] = value
|
20
|
+
h
|
21
|
+
end
|
22
|
+
@all << @last
|
23
|
+
end
|
24
|
+
instance_variable_set("@#{name}", @last)
|
25
|
+
end
|
26
|
+
|
27
|
+
Given /^'(.*)' has (.*), an array of:$/ do |name, attribute, table|
|
28
|
+
object = instance_variable_get("@#{name}")
|
29
|
+
object.send(attribute + "=", [])
|
30
|
+
table.hashes.each do |hash|
|
31
|
+
hash.each {|key, value| object.send(attribute) << value}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
When /^I save the object '(.*)'$/ do |name|
|
37
|
+
object = instance_variable_get("@#{name}")
|
38
|
+
@last_save = @collection.save(object)
|
39
|
+
end
|
40
|
+
|
41
|
+
Then /^the object '(.*)' roundtrips$/ do |name|
|
42
|
+
object = instance_variable_get("@#{name}")
|
43
|
+
object.instance_variable_set("@_id", @last_save)
|
44
|
+
@collection.find_one(@last_save).should == object
|
45
|
+
end
|
46
|
+
|
47
|
+
Then /^the attribute '(.*)' of '(.*)' is '(.*)'$/ do |attr, var, value|
|
48
|
+
object = instance_variable_get("@#{var}")
|
49
|
+
object.send(attr).to_s.should == value
|
50
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module ValueEquals
|
2
|
+
def ==(other)
|
3
|
+
return false unless instance_variables.size == other.instance_variables.size
|
4
|
+
instance_variables.all? {|var| self.instance_variable_get(var) == other.instance_variable_get(var)}
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
class Movie
|
9
|
+
include ValueEquals
|
10
|
+
|
11
|
+
attr_accessor :title, :director, :writers
|
12
|
+
end
|
13
|
+
|
14
|
+
class Director
|
15
|
+
include ValueEquals
|
16
|
+
|
17
|
+
attr_accessor :name, :awards
|
18
|
+
end
|
19
|
+
|
20
|
+
class AcademyAward
|
21
|
+
include ValueEquals
|
22
|
+
|
23
|
+
attr_accessor :year, :category
|
24
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
When /^I(\sstrict\s|\s)update the '(.+)' for '(.+)' to '(.+)'$/ do |strict, attr, doc_name, value|
|
2
|
+
doc = instance_variable_get("@#{doc_name}")
|
3
|
+
attrs = {attr => value}
|
4
|
+
attrs.merge!(:__strict__ => true) unless strict.blank?
|
5
|
+
@last_return = doc.update_attributes(attrs)
|
6
|
+
end
|
7
|
+
|
8
|
+
When /^someone else changes the (.+?) '(.+)' of '(.+)' to$/ do |assoc_klass, assoc_name, name, table|
|
9
|
+
orig = instance_variable_get("@#{name}")
|
10
|
+
doc = orig.class.find_one(orig._id)
|
11
|
+
obj = assoc_klass.constantize.new
|
12
|
+
table.hashes.each do |hash|
|
13
|
+
hash.each do |key, value|
|
14
|
+
obj.send("#{key.underscore.gsub(' ', '_')}=", value)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
doc.send("#{assoc_name.underscore.gsub(' ', '_')}=", obj)
|
18
|
+
doc.save
|
19
|
+
end
|
20
|
+
|
21
|
+
When /^someone else changes the (.+) of '(.+)':$/ do |assoc_name, name, table|
|
22
|
+
orig = instance_variable_get("@#{name}")
|
23
|
+
doc = orig.class.find_one(orig._id)
|
24
|
+
doc.send(assoc_name).clear
|
25
|
+
table.hashes.each do |hash|
|
26
|
+
doc.send(assoc_name) << hash.inject({}) do |attrs, (attr, value)|
|
27
|
+
attrs["#{attr.underscore.gsub(' ', '_')}"] = value
|
28
|
+
attrs
|
29
|
+
end
|
30
|
+
end
|
31
|
+
doc.save
|
32
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
def klass(klass_name = nil)
|
2
|
+
@klass ||= klass_name.singularize.camelize.constantize
|
3
|
+
end
|
4
|
+
|
5
|
+
def query(klass_name = nil)
|
6
|
+
@query ||= klass(klass_name).criteria
|
7
|
+
end
|
8
|
+
|
9
|
+
Then /^the query result is equal to the document '(.*)'$/ do |name|
|
10
|
+
doc = instance_variable_get("@#{name}")
|
11
|
+
query.should == doc
|
12
|
+
end
|
13
|
+
|
14
|
+
Then /^one of the query results is the document '(.*)'$/ do |name|
|
15
|
+
doc = instance_variable_get("@#{name}")
|
16
|
+
query.any? {|d| d == doc}.should be_true
|
17
|
+
end
|
18
|
+
|
19
|
+
Then /^the query result with "(.*)" == "(.*)" has a count of (.*)$/ do |key, value, count|
|
20
|
+
query.find {|r| r.has_key?(key) and r[key] == value }['count'].should == count.to_i
|
21
|
+
end
|
22
|
+
|
23
|
+
Then /^the query result with "([^\"]*)" == "([^\"]*)" has the document '(.*)'$/ do |key, value, name|
|
24
|
+
doc = instance_variable_get("@#{name}")
|
25
|
+
query.find {|r| r.has_key?(key) and r[key] == value }['group'].should include(doc)
|
26
|
+
end
|
27
|
+
|
28
|
+
Then /^the query result has (.*) documents*$/ do |count|
|
29
|
+
if query.respond_to?(:size)
|
30
|
+
query.size.should == count.to_i
|
31
|
+
else
|
32
|
+
query.count.should == count.to_i
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
Then /^the (first|last) query result is the document '(.*)'$/ do |position, name|
|
37
|
+
doc = instance_variable_get("@#{name}")
|
38
|
+
query.entries.send(position).should == doc
|
39
|
+
end
|
40
|
+
|
41
|
+
Then /^the size of the query result is (.*)$/ do |count|
|
42
|
+
query.to_a.size.should == count.to_i
|
43
|
+
end
|
44
|
+
|
45
|
+
Then /^the query result is the document '(.*)'$/ do |name|
|
46
|
+
object = instance_variable_get("@#{name}")
|
47
|
+
if query.kind_of?(Array)
|
48
|
+
query.size.should == 1
|
49
|
+
query.first.should == object
|
50
|
+
else
|
51
|
+
query.should == object
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|