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.
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
-