mongodoc 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/README.textile +143 -0
  2. data/Rakefile +35 -3
  3. data/VERSION +1 -1
  4. data/examples/simple_document.rb +35 -0
  5. data/examples/simple_object.rb +32 -0
  6. data/features/finders.feature +72 -0
  7. data/features/mongodoc_base.feature +12 -2
  8. data/features/named_scopes.feature +66 -0
  9. data/features/new_record.feature +36 -0
  10. data/features/partial_updates.feature +105 -0
  11. data/features/step_definitions/criteria_steps.rb +4 -41
  12. data/features/step_definitions/document_steps.rb +56 -5
  13. data/features/step_definitions/documents.rb +14 -3
  14. data/features/step_definitions/finder_steps.rb +15 -0
  15. data/features/step_definitions/named_scope_steps.rb +18 -0
  16. data/features/step_definitions/partial_update_steps.rb +32 -0
  17. data/features/step_definitions/query_steps.rb +51 -0
  18. data/features/using_criteria.feature +5 -1
  19. data/lib/mongodoc/attributes.rb +76 -63
  20. data/lib/mongodoc/collection.rb +9 -9
  21. data/lib/mongodoc/criteria.rb +152 -161
  22. data/lib/mongodoc/cursor.rb +7 -5
  23. data/lib/mongodoc/document.rb +95 -31
  24. data/lib/mongodoc/finders.rb +29 -0
  25. data/lib/mongodoc/named_scope.rb +68 -0
  26. data/lib/mongodoc/parent_proxy.rb +15 -6
  27. data/lib/mongodoc/proxy.rb +22 -13
  28. data/lib/mongodoc.rb +3 -3
  29. data/mongodoc.gemspec +42 -14
  30. data/perf/mongodoc_runner.rb +90 -0
  31. data/perf/ruby_driver_runner.rb +64 -0
  32. data/spec/attributes_spec.rb +46 -12
  33. data/spec/collection_spec.rb +23 -23
  34. data/spec/criteria_spec.rb +124 -187
  35. data/spec/cursor_spec.rb +21 -17
  36. data/spec/document_ext.rb +2 -2
  37. data/spec/document_spec.rb +187 -218
  38. data/spec/embedded_save_spec.rb +104 -0
  39. data/spec/finders_spec.rb +81 -0
  40. data/spec/hash_matchers.rb +27 -0
  41. data/spec/named_scope_spec.rb +82 -0
  42. data/spec/new_record_spec.rb +216 -0
  43. data/spec/parent_proxy_spec.rb +8 -6
  44. data/spec/proxy_spec.rb +80 -0
  45. data/spec/spec_helper.rb +2 -0
  46. metadata +35 -7
  47. data/README.rdoc +0 -75
data/README.textile ADDED
@@ -0,0 +1,143 @@
1
+ h1. MongoDoc
2
+
3
+ Version: 0.2 1/18/10
4
+
5
+ h2. Introduction
6
+
7
+ MongoDoc is simple and easy to use ActiveRecord-like object mapper for "mongoDB":http://www.mongodb.org in Ruby.
8
+
9
+ MongoDoc is _also_ an extension of the "Mongo Ruby Driver":http://github.com/mongodb/mongo-ruby-driver making it a snap to get Ruby in and out of mongoDB.
10
+
11
+ MongoDoc is *not* ActiveRecord for mongoDB. We do not have callbacks, nor do we have dynamic finders. We do have associations, named scopes, and other features.
12
+
13
+ MongoDoc *is* simple, easy-to-use, and fast. And it works with Rails (2.3.x at the moment, 3 soonish?).
14
+
15
+ MongoDoc is designed to work with document data, if you are looking to map relational data in mongoDB, you will have to look elsewhere.
16
+
17
+ h2. Ruby objects in mongoDB
18
+
19
+ Lets just get right into it and save some Ruby objects in mongoDB!
20
+
21
+ bc.. class Contact
22
+ attr_accessor :name, :addresses, :interests
23
+ end
24
+
25
+ class Address
26
+ attr_accessor :street, :city, :state, :zip, :phone_number
27
+ end
28
+
29
+ p. With MongoDoc, instead of saving JSON[1], we can save an object directly:
30
+
31
+ bc.. contact = Contact.new
32
+ contact.name = 'Hashrocket'
33
+ contact.interests = ['ruby', 'rails', 'agile']
34
+
35
+ address = Address.new
36
+ address.street = '320 First Street North, #712'
37
+ address.city = 'Jacksonville Beach'
38
+ address.state = 'FL'
39
+ address.zip = '32250'
40
+ address.phone_number = '877 885 8846'
41
+ contact.addresses = [address]
42
+
43
+ collection.save(contact)
44
+
45
+ p. We can query using the powerful mongoDB query syntax, and have it return Ruby objects:
46
+
47
+ bc.. results = collection.find('addresses.state' => 'FL')
48
+ hashrocket = results.to_a.find {|contact| contact.name == 'Hashrocket'}
49
+ puts hashrocket.addresses.first.phone_number
50
+
51
+ p. Take a look in the examples directory for more code.
52
+
53
+ h2. Mapping Documents
54
+
55
+ MongoDoc provides ActiveRecord-like persistence, associations, named scopes, and validations (from "Validatable":http://github.com/durran/validatable) as well as a mongoDB query language (from "Mongoid":http://mongoid.org/home). MongoDoc also plays nicely with Rails.
56
+
57
+ @MongoDoc::Document@ provides all these features as a mixin. A @MongoDoc::Document@ can either be a top-level mongoDB document, or an embedded document contained within a top-level document. Top-level documents are stored in collections named after their class: @Contact@ objects are stored in the 'contacts' collection (much like ActiveRecord).
58
+
59
+ Lets define a @Contact@ document with an @Address@ embedded document:
60
+
61
+ bc.. class Address
62
+ include MongoDoc::Document
63
+
64
+ key :street
65
+ key :city
66
+ key :state
67
+ key :zip_code
68
+ key :phone_number
69
+ end
70
+
71
+ class Contact
72
+ include MongoDoc::Document
73
+
74
+ key :name
75
+ key :interests
76
+ has_many :addresses
77
+
78
+ named_scope :in_state, lambda {|state| {:where => {'addresses.state' => state}}}
79
+ end
80
+
81
+ p. Since a mongoDB document has no fixed schema, we define the composition of a document directly in our classes. Please note we do not specify types! We can also specify @has_one@ or @has_many@ associations.
82
+
83
+ Building and saving a document is easy:
84
+
85
+ bc.. contact = Contact.new(:name => 'Hashrocket', :interests => ['ruby', 'rails', 'agile'])
86
+ contact.addresses << Address.new(:street => '320 1st Street North, #712',
87
+ :city => 'Jacksonville Beach',
88
+ :state => 'FL',
89
+ :zip_code => '32250',
90
+ :phone_number => '877 885 8846')
91
+ contact.save
92
+
93
+ p. Now that we have some data, we can query using our named scope:
94
+
95
+ bc. hashrocket = Contact.in_state('FL').find {|contact| contact.name == 'Hashrocket'}
96
+
97
+ p. And we can even perform partial updates:
98
+
99
+ bc. hashrocket.addresses.first.update_attributes(:street => '320 First Street North, #712')
100
+
101
+ h2. Installation
102
+
103
+ bc. sudo gem install mongodoc
104
+
105
+ h2. Configuration
106
+
107
+ Configure your database connection in ./mongodb.yml, you do not need one if you are running on localhost with the default port
108
+
109
+ bc. name: test
110
+ host: localhost
111
+ port: 27017
112
+ options:
113
+ auto_reconnect: true
114
+
115
+ You can change the location of the configuration file:
116
+
117
+ bc. MongoDoc.config_path = './config/mongodb.yml'
118
+
119
+ h2. Credits
120
+
121
+ Les Hill, leshill on github
122
+
123
+ h3. Thanks
124
+
125
+ Thanks to Sandro and Durran for some great conversations and some lovely code.
126
+
127
+ h2. Note on Patches/Pull Requests
128
+
129
+ * Fork the project.
130
+ * Make your feature addition or bug fix.
131
+ * Add tests for it. This is important so I don't break it in a
132
+ future version unintentionally.
133
+ * Commit, do not mess with rakefile, version, or history.
134
+ (if you want to have your own version, that is fine but
135
+ bump version in a commit by itself I can ignore when I pull)
136
+ * Send me a pull request. Bonus points for topic branches.
137
+
138
+ h2. Copyright
139
+
140
+ Copyright (c) 2009 Les Hill. See LICENSE for details.
141
+
142
+ fn1. The Ruby driver exposes an API that understands JSON.
143
+
data/Rakefile CHANGED
@@ -10,9 +10,9 @@ begin
10
10
  gem.email = "leshill@gmail.com"
11
11
  gem.homepage = "http://github.com/leshill/mongodoc"
12
12
  gem.authors = ["Les Hill"]
13
- gem.add_dependency "mongo", "= 0.18.1"
14
- gem.add_dependency "mongo_ext", "= 0.18.1"
15
- gem.add_dependency "durran-validatable", "= 1.8.3"
13
+ gem.add_dependency "mongo", "= 0.18.2"
14
+ gem.add_dependency "mongo_ext", "= 0.18.2"
15
+ gem.add_dependency "durran-validatable", "= 1.8.4"
16
16
  gem.add_dependency "leshill-will_paginate", "= 2.3.11"
17
17
  gem.add_development_dependency "rspec", "= 1.2.9"
18
18
  gem.add_development_dependency "cucumber", "= 0.4.4"
@@ -80,3 +80,35 @@ namespace :mongo do
80
80
  puts "\n"
81
81
  end
82
82
  end
83
+
84
+ namespace :bench do
85
+ desc 'Run benchmark for MongoDoc'
86
+ task 'mongodoc' do
87
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'lib'))
88
+ require 'perf/mongodoc_runner'
89
+ MongoDocRunner.benchmark
90
+ end
91
+
92
+ desc 'Run profiler for driver'
93
+ task 'driver' do
94
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'lib'))
95
+ require 'perf/ruby_driver_runner'
96
+ RubyDriverRunner.benchmark
97
+ end
98
+ end
99
+
100
+ namespace :prof do
101
+ desc 'Run profiler for MongoDoc'
102
+ task 'mongodoc' do
103
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'lib'))
104
+ require 'perf/mongodoc_runner'
105
+ MongoDocRunner.profile
106
+ end
107
+
108
+ desc 'Run profiler for driver'
109
+ task 'driver' do
110
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), 'lib'))
111
+ require 'perf/ruby_driver_runner'
112
+ RubyDriverRunner.profile
113
+ end
114
+ end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.2
1
+ 0.2.0
@@ -0,0 +1,35 @@
1
+ require 'mongodoc'
2
+
3
+ class Address
4
+ include MongoDoc::Document
5
+
6
+ key :street
7
+ key :city
8
+ key :state
9
+ key :zip_code
10
+ key :phone_number
11
+ end
12
+
13
+ class Contact
14
+ include MongoDoc::Document
15
+
16
+ key :name
17
+ key :interests
18
+ has_many :addresses
19
+
20
+ named_scope :in_state, lambda {|state| {:where => {'addresses.state' => state}}}
21
+ end
22
+
23
+ MongoDoc.connect_to_database 'test'
24
+ Contact.collection.drop
25
+
26
+ contact = Contact.new(:name => 'Hashrocket', :interests => ['ruby', 'rails', 'agile'])
27
+ contact.addresses << Address.new(:street => '320 1st Street North, #712', :city => 'Jacksonville Beach', :state => 'FL', :zip_code => '32250', :phone_number => '877 885 8846')
28
+ contact.save
29
+
30
+ hashrocket = Contact.in_state('FL').find {|contact| contact.name == 'Hashrocket'}
31
+
32
+ hashrocket_address = hashrocket.addresses.first
33
+ hashrocket_address.update_attributes(:street => '320 First Street North, #712')
34
+
35
+ puts Contact.find_one(:where => {:name => 'Hashrocket'}).addresses.first.street
@@ -0,0 +1,32 @@
1
+ require 'mongodoc'
2
+
3
+ class Contact
4
+ attr_accessor :name, :addresses, :interests
5
+ end
6
+
7
+ class Address
8
+ attr_accessor :street, :city, :state, :zip, :phone_number
9
+ end
10
+
11
+ MongoDoc.connect_to_database 'test'
12
+
13
+ collection = MongoDoc::Collection.new('contacts')
14
+ collection.drop
15
+
16
+ contact = Contact.new
17
+ contact.name = 'Hashrocket'
18
+ contact.interests = ['ruby', 'rails', 'agile']
19
+
20
+ address = Address.new
21
+ address.street = '320 First Street North, #712'
22
+ address.city = 'Jacksonville Beach'
23
+ address.state = 'FL'
24
+ address.zip = '32250'
25
+ address.phone_number = '877 885 8846'
26
+ contact.addresses = [address]
27
+
28
+ collection.save(contact)
29
+
30
+ results = collection.find('addresses.state' => 'FL')
31
+ hashrocket = results.to_a.find {|contact| contact.name == 'Hashrocket'}
32
+ puts hashrocket.addresses.first.phone_number
@@ -0,0 +1,72 @@
1
+ Feature: Finders
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: All
55
+ When I query contacts with all
56
+ Then the query result has 3 documents
57
+
58
+ Scenario: Count
59
+ When I query contacts with count
60
+ Then the query result was 3 documents
61
+
62
+ Scenario: First
63
+ When I query contacts with first
64
+ Then the query result is the document 'hashrocket'
65
+
66
+ Scenario: Last
67
+ When I query contacts with last
68
+ Then the query result is the document 'contractor'
69
+
70
+ Scenario: Find One
71
+ When I query contacts to find_one with the id of the 'contractor' document
72
+ Then the query result is the document 'contractor'
@@ -74,7 +74,7 @@ Feature: MongoDoc::Base
74
74
  And the Contact collection should have 1 document
75
75
  And the document 'hashrocket' roundtrips
76
76
 
77
- Scenario: failing to update attributes from a has_many child document
77
+ Scenario: Update attributes from a has_many child document
78
78
  Given an empty Contact document collection
79
79
  And a Contact document named 'hashrocket' :
80
80
  | Name |
@@ -89,7 +89,8 @@ Feature: MongoDoc::Base
89
89
  | Street |
90
90
  | 1a Calle |
91
91
  When I update the document 'chile' with the hash named 'street'
92
- Then the last return value is false
92
+ Then the last return value is true
93
+ And the document 'hashrocket' roundtrips
93
94
 
94
95
  Scenario: update attributes from a has_one child document
95
96
  Given an empty Place document collection
@@ -107,3 +108,12 @@ Feature: MongoDoc::Base
107
108
  When I update the document 'address' with the hash named 'street'
108
109
  Then the Place collection should have 1 document
109
110
  And the document 'hashrocket' roundtrips
111
+
112
+ Scenario: Finder
113
+ Given an empty Contact document collection
114
+ And a Contact document named 'hashrocket' :
115
+ | Name | Type |
116
+ | Hashrocket | company |
117
+ And I save the last document
118
+ When I query contacts with find {:where => {'type' => 'company'}}
119
+ Then the size of the last return value is 1
@@ -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,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
@@ -1,17 +1,10 @@
1
- def query(klass_name = nil)
2
- return @query if @query or klass_name.nil?
3
- klass = klass_name.singularize.camelize.constantize
4
- @query = klass.criteria
1
+ When /^I query (.*) with 'all'$/ do |doc|
2
+ query(doc).all
5
3
  end
6
4
 
7
- # When /^I query (.*) with all "([^\"]*)"$/ do |doc, selections_text|
8
- # selections = eval(selections_text)
9
- # query(doc).all(selections)
10
- # end
11
-
12
5
  When /^I query (.*) to select fields? "([^\"]*)"$/ do |doc, fields|
13
6
  fields = fields.split
14
- query(doc).select(*fields)
7
+ query(doc).only(*fields)
15
8
  end
16
9
 
17
10
  When /^I query (.*) where "([^\"]*)"$/ do |doc, where_text|
@@ -34,7 +27,7 @@ When /^I query (.*) with (every|not in|in) "([^\"]*)"$/ do |doc, op, hash_text|
34
27
  query(doc).send(op.gsub(' ', '_'), hash)
35
28
  end
36
29
 
37
- When /^I query (.*) with '(.*)' id$/ do |doc, name|
30
+ When /^I query (.*) with the '(.*)' id$/ do |doc, name|
38
31
  object = instance_variable_get("@#{name}")
39
32
  query(doc).id(object.id)
40
33
  end
@@ -47,33 +40,3 @@ When /^I order the (.*) query by "([^\"]*)"$/ do |doc, order_text|
47
40
  order = eval(order_text)
48
41
  query(doc).order_by(order)
49
42
  end
50
-
51
- Then /^the (first|last) query result is equal to the document '(.*)'$/ do |position, name|
52
- object = instance_variable_get("@#{name}")
53
- query.send(position).should == object
54
- end
55
-
56
- Then /^one of the query results is the document '(.*)'$/ do |name|
57
- object = instance_variable_get("@#{name}")
58
- query.any? {|doc| doc == object}
59
- end
60
-
61
- Then /^the aggregate query result with "(.*)" == "(.*)" has a count of (.*)$/ do |key, value, count|
62
- result = query.aggregate
63
- result.find {|r| r.has_key?(key) and r[key] == value }['count'].should == count.to_i
64
- end
65
-
66
- Then /^the query result has (.*) documents*$/ do |count|
67
- query.count.should == count.to_i
68
- end
69
-
70
- Then /^the size of the query result is (.*)$/ do |count|
71
- query.to_a.size.should == count.to_i
72
- end
73
-
74
- Then /^the group query result with "([^\"]*)" == "([^\"]*)" has the document '(.*)'$/ do |key, value, name|
75
- object = instance_variable_get("@#{name}")
76
- result = query.group
77
- result.find {|r| r.has_key?(key) and r[key] == value }['group'].should include(object)
78
- end
79
-