mongo_doc 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.textile CHANGED
@@ -1,8 +1,8 @@
1
1
  h1. MongoDoc
2
2
 
3
- Version: Turbulence (0.4.0) 2010/03/12
3
+ Version: Turbulence (0.4.1) 2010/03/17
4
4
 
5
- h2. What's New in Turbulence (0.4.0)
5
+ h2. What's New in Turbulence (0.4.1)
6
6
 
7
7
  API changes (@key@ and @has_*@ still supported, will be deprectated soon)
8
8
 
@@ -14,6 +14,10 @@ API changes (@key@ and @has_*@ still supported, will be deprectated soon)
14
14
  ** @embed_many@ was @has_many@
15
15
  ** @embed_hash@ was @has_hash@
16
16
 
17
+ Indexing suppport
18
+
19
+ * @MongoDoc::Document.index@
20
+
17
21
  h2. Notes
18
22
 
19
23
  * 2010-03-12 Thanks to weather in ATL, cleaned up attr_accessor and switched to embed association macros
data/Rakefile CHANGED
@@ -89,7 +89,7 @@ namespace :mongoid do
89
89
  src_dir = Pathname.new('../durran-mongoid/lib/mongoid')
90
90
  dest_dir = Pathname.new('lib/mongoid')
91
91
  dest_dir.mkpath
92
- %w(criteria.rb contexts/paging.rb criterion extensions/symbol/inflections.rb extensions/hash/criteria_helpers.rb matchers).each do |f|
92
+ %w(criteria.rb contexts/paging.rb contexts/enumerable.rb criterion extensions/symbol/inflections.rb extensions/hash/criteria_helpers.rb matchers).each do |f|
93
93
  src = src_dir + f
94
94
  if src.directory?
95
95
  FileUtils.cp_r(src, dest_dir)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.0
1
+ 0.4.1
@@ -0,0 +1,28 @@
1
+ Feature: Indexes
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
+
25
+ Scenario: Simple index
26
+ When I create an index named name on the Contact collection
27
+ Then there is an index on name on the Contact collection
28
+
@@ -0,0 +1,10 @@
1
+ When /^I create an index named (.*) on the (.*) collection$/ do |index_name, doc|
2
+ klass = doc.constantize
3
+ klass.index(index_name)
4
+ end
5
+
6
+ Then /^there is an index on (.*) on the (.*) collection$/ do |index_name, doc|
7
+ klass = doc.constantize
8
+ klass.collection.index_information.should include("#{index_name}_1")
9
+ end
10
+
@@ -1,4 +1,4 @@
1
- module MongoDoc
1
+ module Mongoid
2
2
  module Contexts
3
3
  module Ids
4
4
  # Return documents based on an id search. Will handle if a single id has
@@ -2,7 +2,7 @@ module MongoDoc
2
2
  module Contexts
3
3
  class Mongo
4
4
  include Mongoid::Contexts::Paging
5
- include MongoDoc::Contexts::Ids
5
+ include Mongoid::Contexts::Ids
6
6
 
7
7
  attr_reader :criteria, :cache
8
8
 
@@ -26,6 +26,25 @@ module MongoDoc
26
26
  collection.group(options[:fields], selector, { :count => 0 }, AGGREGATE_REDUCE, true)
27
27
  end
28
28
 
29
+ # Get the average value for the supplied field.
30
+ #
31
+ # This will take the internally built selector and options
32
+ # and pass them on to the Ruby driver's +group()+ method on the collection. The
33
+ # collection itself will be retrieved from the class provided, and once the
34
+ # query has returned it will provided a grouping of keys with averages.
35
+ #
36
+ # Example:
37
+ #
38
+ # <tt>context.avg(:age)</tt>
39
+ #
40
+ # Returns:
41
+ #
42
+ # A numeric value that is the average.
43
+ def avg(field)
44
+ total = sum(field)
45
+ total ? (total / count) : nil
46
+ end
47
+
29
48
  # Get the count of matching documents in the database for the context.
30
49
  #
31
50
  # Example:
@@ -39,6 +58,16 @@ module MongoDoc
39
58
  @count ||= collection.find(selector, options).count
40
59
  end
41
60
 
61
+ # Gets an array of distinct values for the supplied field across the
62
+ # entire collection or the susbset given the criteria.
63
+ #
64
+ # Example:
65
+ #
66
+ # <tt>context.distinct(:title)</tt>
67
+ def distinct(field)
68
+ collection.distinct(field, selector)
69
+ end
70
+
42
71
  # Determine if the context is empty or blank given the criteria. Will
43
72
  # perform a quick find_one asking only for the id.
44
73
  #
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
  require "mongoid/contexts/paging"
3
3
  require "mongo_doc/contexts/ids"
4
- require "mongo_doc/contexts/enumerable"
4
+ require "mongoid/contexts/enumerable"
5
5
  require "mongo_doc/contexts/mongo"
6
6
 
7
7
  module Mongoid
@@ -19,7 +19,7 @@ module Mongoid
19
19
  # <tt>Contexts.context_for(criteria)</tt>
20
20
  def self.context_for(criteria)
21
21
  if criteria.klass.respond_to?(:_append)
22
- return MongoDoc::Contexts::Enumerable.new(criteria)
22
+ return Mongoid::Contexts::Enumerable.new(criteria)
23
23
  elsif criteria.klass.respond_to?(:collection)
24
24
  return MongoDoc::Contexts::Mongo.new(criteria)
25
25
  else
@@ -4,6 +4,7 @@ require 'mongo_doc/attributes'
4
4
  require 'mongo_doc/associations'
5
5
  require 'mongo_doc/criteria'
6
6
  require 'mongo_doc/finders'
7
+ require 'mongo_doc/index'
7
8
  require 'mongo_doc/scope'
8
9
  require 'mongo_doc/validations/macros'
9
10
 
@@ -21,6 +22,7 @@ module MongoDoc
21
22
  extend ClassMethods
22
23
  extend Criteria
23
24
  extend Finders
25
+ extend Index
24
26
  extend Scope
25
27
  include ::Validatable
26
28
  extend Validations::Macros
@@ -0,0 +1,27 @@
1
+ module MongoDoc
2
+ module Index
3
+
4
+ # Create an index on a collection. For a unique index, pass the unique
5
+ # option +:unique => true+. For compound indexes, pass pairs of fields and
6
+ # directions (+:asc+, +:desc+) as a hash.
7
+ #
8
+ # <tt>Person.index(:last_name)</tt>
9
+ # <tt>Person.index(:ssn, :unique => true)</tt>
10
+ # <tt>Person.index(:first_name => :asc, :last_name => :asc)</tt>
11
+ # <tt>Person.index(:first_name => :asc, :last_name => :asc, :unique => true)</tt>
12
+ def index(*args)
13
+ options_and_fields = args.extract_options!
14
+ unique = options_and_fields.delete(:unique) || false
15
+ if args.any?
16
+ collection.create_index(args.first, unique)
17
+ else
18
+ collection.create_index(to_mongo_direction(options_and_fields), unique)
19
+ end
20
+ end
21
+
22
+ protected
23
+ def to_mongo_direction(fields_hash)
24
+ fields_hash.to_a.map {|field| [field.first, field.last == :desc ? Mongo::DESCENDING : Mongo::ASCENDING]}
25
+ end
26
+ end
27
+ end
data/lib/mongo_doc.rb CHANGED
@@ -4,7 +4,7 @@ require 'validatable'
4
4
  require 'will_paginate/collection'
5
5
 
6
6
  module MongoDoc
7
- VERSION = '0.4.0'
7
+ VERSION = '0.4.1'
8
8
  end
9
9
 
10
10
  require 'mongo_doc/connection'
@@ -1,13 +1,11 @@
1
1
  # encoding: utf-8
2
- module MongoDoc #:nodoc:
2
+ module Mongoid #:nodoc:
3
3
  module Contexts #:nodoc:
4
4
  class Enumerable
5
- include Mongoid::Contexts::Paging
6
- include MongoDoc::Contexts::Ids
7
-
5
+ include Ids, Paging
8
6
  attr_reader :criteria
9
7
 
10
- delegate :first, :last, :to => :execute
8
+ delegate :blank?, :empty?, :first, :last, :to => :execute
11
9
  delegate :documents, :options, :selector, :to => :criteria
12
10
 
13
11
  # Return aggregation counts of the grouped documents. This will count by
@@ -22,19 +20,33 @@ module MongoDoc #:nodoc:
22
20
  counts
23
21
  end
24
22
 
23
+ # Get the average value for the supplied field.
24
+ #
25
+ # Example:
26
+ #
27
+ # <tt>context.avg(:age)</tt>
28
+ #
29
+ # Returns:
30
+ #
31
+ # A numeric value that is the average.
32
+ def avg(field)
33
+ total = sum(field)
34
+ total ? (total.to_f / count) : nil
35
+ end
36
+
25
37
  # Gets the number of documents in the array. Delegates to size.
26
38
  def count
27
39
  @count ||= documents.size
28
40
  end
29
41
 
30
- # Groups the documents by the first field supplied in the field options.
42
+ # Gets an array of distinct values for the supplied field across the
43
+ # entire array or the susbset given the criteria.
31
44
  #
32
- # Returns:
45
+ # Example:
33
46
  #
34
- # A +Hash+ with field values as keys, arrays of documents as values.
35
- def group
36
- field = options[:fields].first
37
- documents.group_by { |doc| doc.send(field) }
47
+ # <tt>context.distinct(:title)</tt>
48
+ def distinct(field)
49
+ execute.collect { |doc| doc.send(field) }.uniq
38
50
  end
39
51
 
40
52
  # Enumerable implementation of execute. Returns matching documents for
@@ -47,13 +59,23 @@ module MongoDoc #:nodoc:
47
59
  limit(documents.select { |document| document.matches?(selector) })
48
60
  end
49
61
 
62
+ # Groups the documents by the first field supplied in the field options.
63
+ #
64
+ # Returns:
65
+ #
66
+ # A +Hash+ with field values as keys, arrays of documents as values.
67
+ def group
68
+ field = options[:fields].first
69
+ documents.group_by { |doc| doc.send(field) }
70
+ end
71
+
50
72
  # Create the new enumerable context. This will need the selector and
51
73
  # options from a +Criteria+ and a documents array that is the underlying
52
74
  # array of embedded documents from a has many association.
53
75
  #
54
76
  # Example:
55
77
  #
56
- # <tt>MongoDoc::Contexts::Enumerable.new(criteria)</tt>
78
+ # <tt>Mongoid::Contexts::Enumerable.new(criteria)</tt>
57
79
  def initialize(criteria)
58
80
  @criteria = criteria
59
81
  end
@@ -119,10 +141,11 @@ module MongoDoc #:nodoc:
119
141
  skip, limit = options[:skip], options[:limit]
120
142
  if skip && limit
121
143
  return documents.slice(skip, limit)
144
+ elsif limit
145
+ return documents.first(limit)
122
146
  end
123
147
  documents
124
148
  end
125
149
  end
126
150
  end
127
151
  end
128
-
@@ -26,13 +26,14 @@ module Mongoid #:nodoc:
26
26
  include Enumerable
27
27
 
28
28
  attr_reader :collection, :ids, :klass, :options, :selector
29
-
30
29
  attr_accessor :documents
31
30
 
32
31
  delegate \
33
32
  :aggregate,
33
+ :avg,
34
34
  :blank?,
35
35
  :count,
36
+ :distinct,
36
37
  :empty?,
37
38
  :execute,
38
39
  :first,
data/mongo_doc.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{mongo_doc}
8
- s.version = "0.4.0"
8
+ s.version = "0.4.1"
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{2010-03-13}
12
+ s.date = %q{2010-03-17}
13
13
  s.description = %q{ODM for MongoDB}
14
14
  s.email = %q{leshill@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -30,6 +30,7 @@ Gem::Specification.new do |s|
30
30
  "examples/simple_object.rb",
31
31
  "features/collections.feature",
32
32
  "features/finders.feature",
33
+ "features/indexes.feature",
33
34
  "features/mongodb.yml",
34
35
  "features/mongodoc_base.feature",
35
36
  "features/new_record.feature",
@@ -41,6 +42,7 @@ Gem::Specification.new do |s|
41
42
  "features/step_definitions/document_steps.rb",
42
43
  "features/step_definitions/documents.rb",
43
44
  "features/step_definitions/finder_steps.rb",
45
+ "features/step_definitions/index_steps.rb",
44
46
  "features/step_definitions/json_steps.rb",
45
47
  "features/step_definitions/object_steps.rb",
46
48
  "features/step_definitions/objects.rb",
@@ -64,7 +66,6 @@ Gem::Specification.new do |s|
64
66
  "lib/mongo_doc/collection.rb",
65
67
  "lib/mongo_doc/connection.rb",
66
68
  "lib/mongo_doc/contexts.rb",
67
- "lib/mongo_doc/contexts/enumerable.rb",
68
69
  "lib/mongo_doc/contexts/ids.rb",
69
70
  "lib/mongo_doc/contexts/mongo.rb",
70
71
  "lib/mongo_doc/criteria.rb",
@@ -87,11 +88,13 @@ Gem::Specification.new do |s|
87
88
  "lib/mongo_doc/ext/symbol.rb",
88
89
  "lib/mongo_doc/ext/time.rb",
89
90
  "lib/mongo_doc/finders.rb",
91
+ "lib/mongo_doc/index.rb",
90
92
  "lib/mongo_doc/matchers.rb",
91
93
  "lib/mongo_doc/query.rb",
92
94
  "lib/mongo_doc/scope.rb",
93
95
  "lib/mongo_doc/validations/macros.rb",
94
96
  "lib/mongo_doc/validations/validates_embedded.rb",
97
+ "lib/mongoid/contexts/enumerable.rb",
95
98
  "lib/mongoid/contexts/paging.rb",
96
99
  "lib/mongoid/criteria.rb",
97
100
  "lib/mongoid/criterion/complex.rb",
@@ -127,7 +130,6 @@ Gem::Specification.new do |s|
127
130
  "spec/bson_spec.rb",
128
131
  "spec/collection_spec.rb",
129
132
  "spec/connection_spec.rb",
130
- "spec/contexts/enumerable_spec.rb",
131
133
  "spec/contexts/ids_spec.rb",
132
134
  "spec/contexts/mongo_spec.rb",
133
135
  "spec/contexts_spec.rb",
@@ -139,6 +141,7 @@ Gem::Specification.new do |s|
139
141
  "spec/ext_spec.rb",
140
142
  "spec/finders_spec.rb",
141
143
  "spec/hash_matchers.rb",
144
+ "spec/index_spec.rb",
142
145
  "spec/matchers_spec.rb",
143
146
  "spec/mongodb.yml",
144
147
  "spec/mongodb_pairs.yml",
@@ -164,7 +167,6 @@ Gem::Specification.new do |s|
164
167
  "spec/bson_spec.rb",
165
168
  "spec/collection_spec.rb",
166
169
  "spec/connection_spec.rb",
167
- "spec/contexts/enumerable_spec.rb",
168
170
  "spec/contexts/ids_spec.rb",
169
171
  "spec/contexts/mongo_spec.rb",
170
172
  "spec/contexts_spec.rb",
@@ -176,6 +178,7 @@ Gem::Specification.new do |s|
176
178
  "spec/ext_spec.rb",
177
179
  "spec/finders_spec.rb",
178
180
  "spec/hash_matchers.rb",
181
+ "spec/index_spec.rb",
179
182
  "spec/matchers_spec.rb",
180
183
  "spec/new_record_spec.rb",
181
184
  "spec/query_spec.rb",
@@ -39,6 +39,19 @@ describe "MongoDoc::Contexts::Mongo" do
39
39
  end
40
40
  end
41
41
 
42
+ context "#avg" do
43
+ it "is the sum/count" do
44
+ context.should_receive(:count).and_return(1)
45
+ context.should_receive(:sum).with(:field_name).and_return(1)
46
+ context.avg(:field_name)
47
+ end
48
+
49
+ it "returns nil if there is no sum" do
50
+ context.stub(:sum).and_return(nil)
51
+ context.avg(:field_name).should be_nil
52
+ end
53
+ end
54
+
42
55
  context "#count" do
43
56
  it "uses find and count" do
44
57
  result = stub('result')
@@ -48,6 +61,13 @@ describe "MongoDoc::Contexts::Mongo" do
48
61
  end
49
62
  end
50
63
 
64
+ context "#distinct" do
65
+ it "uses distinct" do
66
+ collection.should_receive(:distinct).with(:field_name, {})
67
+ context.distinct(:field_name)
68
+ end
69
+ end
70
+
51
71
  context "#execute" do
52
72
  it "uses find" do
53
73
  collection.should_receive(:find)
@@ -24,7 +24,7 @@ describe MongoDoc::Contexts do
24
24
  let(:klass) { ContextTest.new.children }
25
25
 
26
26
  it "creates an Enumerable context" do
27
- MongoDoc::Contexts::Enumerable.should_receive(:new).with(criteria)
27
+ Mongoid::Contexts::Enumerable.should_receive(:new).with(criteria)
28
28
  Mongoid::Contexts.context_for(criteria)
29
29
  end
30
30
  end
@@ -0,0 +1,70 @@
1
+ require "spec_helper.rb"
2
+
3
+ describe MongoDoc::Index do
4
+ class Address
5
+ include MongoDoc::Document
6
+
7
+ attr_accessor :state
8
+ end
9
+
10
+ class IndexTest
11
+ include MongoDoc::Document
12
+
13
+ attr_accessor :ssn
14
+ attr_accessor :first_name
15
+ attr_accessor :last_name
16
+ attr_accessor :birthdate, :type => Date
17
+ attr_accessor :notes
18
+
19
+ embed :addresses
20
+
21
+ # This is the API we are testing, commented out to avoid firing before
22
+ # specs are run
23
+ #
24
+ # index :birthdate
25
+ # index :ssn, :unique => true
26
+ # index :first_name => :asc, :last_name => :asc
27
+ # index :last_name => :asc, :first_name => :asc, :unique => true
28
+ # index "addresses.state"
29
+ end
30
+
31
+ let(:collection) { stub('collection') }
32
+
33
+ before do
34
+ IndexTest.stub(:collection).and_return(collection)
35
+ end
36
+
37
+ context "Simple index" do
38
+
39
+ it "creates an index for the field" do
40
+ collection.should_receive(:create_index).with(:birthdate, false)
41
+ IndexTest.index(:birthdate)
42
+ end
43
+
44
+ it "creates a unique index for the field" do
45
+ collection.should_receive(:create_index).with(:birthdate, true)
46
+ IndexTest.index(:birthdate, :unique => true)
47
+ end
48
+
49
+ end
50
+
51
+ context "Compound index" do
52
+
53
+ it "creates a compound index" do
54
+ collection.should_receive(:create_index).with([[:first_name, Mongo::ASCENDING], [:last_name, Mongo::ASCENDING]], false)
55
+ IndexTest.index(:first_name => :asc, :last_name => :asc)
56
+ end
57
+
58
+ it "creates a unique compound index" do
59
+ collection.should_receive(:create_index).with([[:first_name, Mongo::ASCENDING], [:last_name, Mongo::ASCENDING]], true)
60
+ IndexTest.index(:first_name => :asc, :last_name => :asc, :unique => true)
61
+ end
62
+ end
63
+
64
+ context "Nested index" do
65
+ it "creates an index for the field" do
66
+ collection.should_receive(:create_index).with("addresses.state", false)
67
+ IndexTest.index("addresses.state")
68
+ end
69
+ end
70
+ end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 4
8
- - 0
9
- version: 0.4.0
8
+ - 1
9
+ version: 0.4.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - Les Hill
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-03-13 00:00:00 -05:00
17
+ date: 2010-03-17 00:00:00 -04:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -136,6 +136,7 @@ files:
136
136
  - examples/simple_object.rb
137
137
  - features/collections.feature
138
138
  - features/finders.feature
139
+ - features/indexes.feature
139
140
  - features/mongodb.yml
140
141
  - features/mongodoc_base.feature
141
142
  - features/new_record.feature
@@ -147,6 +148,7 @@ files:
147
148
  - features/step_definitions/document_steps.rb
148
149
  - features/step_definitions/documents.rb
149
150
  - features/step_definitions/finder_steps.rb
151
+ - features/step_definitions/index_steps.rb
150
152
  - features/step_definitions/json_steps.rb
151
153
  - features/step_definitions/object_steps.rb
152
154
  - features/step_definitions/objects.rb
@@ -170,7 +172,6 @@ files:
170
172
  - lib/mongo_doc/collection.rb
171
173
  - lib/mongo_doc/connection.rb
172
174
  - lib/mongo_doc/contexts.rb
173
- - lib/mongo_doc/contexts/enumerable.rb
174
175
  - lib/mongo_doc/contexts/ids.rb
175
176
  - lib/mongo_doc/contexts/mongo.rb
176
177
  - lib/mongo_doc/criteria.rb
@@ -193,11 +194,13 @@ files:
193
194
  - lib/mongo_doc/ext/symbol.rb
194
195
  - lib/mongo_doc/ext/time.rb
195
196
  - lib/mongo_doc/finders.rb
197
+ - lib/mongo_doc/index.rb
196
198
  - lib/mongo_doc/matchers.rb
197
199
  - lib/mongo_doc/query.rb
198
200
  - lib/mongo_doc/scope.rb
199
201
  - lib/mongo_doc/validations/macros.rb
200
202
  - lib/mongo_doc/validations/validates_embedded.rb
203
+ - lib/mongoid/contexts/enumerable.rb
201
204
  - lib/mongoid/contexts/paging.rb
202
205
  - lib/mongoid/criteria.rb
203
206
  - lib/mongoid/criterion/complex.rb
@@ -233,7 +236,6 @@ files:
233
236
  - spec/bson_spec.rb
234
237
  - spec/collection_spec.rb
235
238
  - spec/connection_spec.rb
236
- - spec/contexts/enumerable_spec.rb
237
239
  - spec/contexts/ids_spec.rb
238
240
  - spec/contexts/mongo_spec.rb
239
241
  - spec/contexts_spec.rb
@@ -245,6 +247,7 @@ files:
245
247
  - spec/ext_spec.rb
246
248
  - spec/finders_spec.rb
247
249
  - spec/hash_matchers.rb
250
+ - spec/index_spec.rb
248
251
  - spec/matchers_spec.rb
249
252
  - spec/mongodb.yml
250
253
  - spec/mongodb_pairs.yml
@@ -294,7 +297,6 @@ test_files:
294
297
  - spec/bson_spec.rb
295
298
  - spec/collection_spec.rb
296
299
  - spec/connection_spec.rb
297
- - spec/contexts/enumerable_spec.rb
298
300
  - spec/contexts/ids_spec.rb
299
301
  - spec/contexts/mongo_spec.rb
300
302
  - spec/contexts_spec.rb
@@ -306,6 +308,7 @@ test_files:
306
308
  - spec/ext_spec.rb
307
309
  - spec/finders_spec.rb
308
310
  - spec/hash_matchers.rb
311
+ - spec/index_spec.rb
309
312
  - spec/matchers_spec.rb
310
313
  - spec/new_record_spec.rb
311
314
  - spec/query_spec.rb
@@ -1,274 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe MongoDoc::Contexts::Enumerable do
4
-
5
- class Address
6
- include MongoDoc::Document
7
- include MongoDoc::Matchers
8
-
9
- attr_accessor :number
10
- attr_accessor :street
11
- end
12
-
13
- before do
14
- @london = Address.new(:number => 1, :street => "Bond Street")
15
- @shanghai = Address.new(:number => 10, :street => "Nan Jing Dong Lu")
16
- @melbourne = Address.new(:number => 20, :street => "Bourke Street")
17
- @new_york = Address.new(:number => 20, :street => "Broadway")
18
- @docs = [ @london, @shanghai, @melbourne, @new_york ]
19
- @criteria = Mongoid::Criteria.new(Address)
20
- @criteria.documents = @docs
21
- @criteria.where(:street => "Bourke Street").only(:number)
22
- @context = MongoDoc::Contexts::Enumerable.new(@criteria)
23
- end
24
-
25
- describe "#aggregate" do
26
-
27
- before do
28
- @counts = @context.aggregate
29
- end
30
-
31
- it "groups by the fields provided in the options" do
32
- @counts.size.should == 3
33
- end
34
-
35
- it "stores the counts in proper groups" do
36
- @counts[1].should == 1
37
- @counts[10].should == 1
38
- @counts[20].should == 2
39
- end
40
- end
41
-
42
- describe "#count" do
43
-
44
- it "returns the size of the enumerable" do
45
- @context.count.should == 4
46
- end
47
-
48
- end
49
-
50
- describe "#execute" do
51
-
52
- before do
53
- @criteria = Mongoid::Criteria.new(Address)
54
- @criteria.documents = @docs
55
- end
56
-
57
- it "returns the matching documents from the array" do
58
- @context.execute.should == [ @melbourne ]
59
- end
60
-
61
- context "when selector is empty" do
62
-
63
- before do
64
- @criteria.only(:number)
65
- @context = MongoDoc::Contexts::Enumerable.new(@criteria)
66
- end
67
-
68
- it "returns all the documents" do
69
- @context.execute.should == @docs
70
- end
71
- end
72
-
73
- context "when skip and limit are in the options" do
74
-
75
- before do
76
- @criteria.skip(2).limit(2)
77
- @context = MongoDoc::Contexts::Enumerable.new(@criteria)
78
- end
79
-
80
- it "properly narrows down the matching results" do
81
- @context.execute.should == [ @melbourne, @new_york ]
82
- end
83
- end
84
-
85
- end
86
-
87
- describe "#first" do
88
-
89
- context "when a selector is present" do
90
-
91
- it "returns the first that matches the selector" do
92
- @context.first.should == @melbourne
93
- end
94
- end
95
-
96
- end
97
-
98
- describe "#group" do
99
-
100
- before do
101
- @group = @context.group
102
- end
103
-
104
- it "groups by the fields provided in the options" do
105
- @group.size.should == 3
106
- end
107
-
108
- it "stores the documents in proper groups" do
109
- @group[1].should == [ @london ]
110
- @group[10].should == [ @shanghai ]
111
- @group[20].should == [ @melbourne, @new_york ]
112
- end
113
-
114
- end
115
-
116
- describe "#initialize" do
117
-
118
- let(:selector) { { :field => "value" } }
119
- let(:options) { { :skip => 20 } }
120
- let(:documents) { [stub] }
121
-
122
- before do
123
- @criteria = Mongoid::Criteria.new(Address)
124
- @criteria.documents = documents
125
- @criteria.where(selector).skip(20)
126
- @context = MongoDoc::Contexts::Enumerable.new(@criteria)
127
- end
128
-
129
- it "sets the selector" do
130
- @context.selector.should == selector
131
- end
132
-
133
- it "sets the options" do
134
- @context.options.should == options
135
- end
136
-
137
- it "sets the documents" do
138
- @context.documents.should == documents
139
- end
140
-
141
- end
142
-
143
- describe "#iterator" do
144
-
145
- before do
146
- @criteria.where(:street => "Bourke Street")
147
- @criteria.documents = @docs
148
- @context = MongoDoc::Contexts::Enumerable.new(@criteria)
149
- end
150
-
151
- it "executes the criteria" do
152
- acc = []
153
- @context.iterate do |doc|
154
- acc << doc
155
- end
156
- acc.should == [@melbourne]
157
- end
158
-
159
- end
160
-
161
- describe "#last" do
162
-
163
- it "returns the last matching in the enumerable" do
164
- @context.last.should == @melbourne
165
- end
166
-
167
- end
168
-
169
- describe "#max" do
170
-
171
- it "returns the max value for the supplied field" do
172
- @context.max(:number).should == 20
173
- end
174
-
175
- end
176
-
177
- describe "#min" do
178
-
179
- it "returns the min value for the supplied field" do
180
- @context.min(:number).should == 1
181
- end
182
-
183
- end
184
-
185
- describe "#one" do
186
-
187
- it "returns the first matching in the enumerable" do
188
- @context.one.should == @melbourne
189
- end
190
-
191
- end
192
-
193
- describe "#page" do
194
-
195
- context "when the page option exists" do
196
-
197
- before do
198
- @criteria = Mongoid::Criteria.new(Address).extras({ :page => 5 })
199
- @criteria.documents = []
200
- @context = MongoDoc::Contexts::Enumerable.new(@criteria)
201
- end
202
-
203
- it "returns the page option" do
204
- @context.page.should == 5
205
- end
206
-
207
- end
208
-
209
- context "when the page option does not exist" do
210
-
211
- before do
212
- @criteria = Mongoid::Criteria.new(Address)
213
- @criteria.documents = []
214
- @context = MongoDoc::Contexts::Enumerable.new(@criteria)
215
- end
216
-
217
- it "returns 1" do
218
- @context.page.should == 1
219
- end
220
-
221
- end
222
-
223
- end
224
-
225
- describe "#paginate" do
226
-
227
- before do
228
- @criteria = Mongoid::Criteria.new(Address).skip(2).limit(2)
229
- @context = MongoDoc::Contexts::Enumerable.new(@criteria)
230
- @results = @context.paginate
231
- end
232
-
233
- it "executes and paginates the results" do
234
- @results.current_page.should == 2
235
- @results.per_page.should == 2
236
- end
237
-
238
- end
239
-
240
- describe "#per_page" do
241
-
242
- context "when a limit option exists" do
243
-
244
- it "returns 20" do
245
- @context.per_page.should == 20
246
- end
247
-
248
- end
249
-
250
- context "when a limit option does not exist" do
251
-
252
- before do
253
- @criteria = Mongoid::Criteria.new(Address).limit(50)
254
- @criteria.documents = []
255
- @context = MongoDoc::Contexts::Enumerable.new(@criteria)
256
- end
257
-
258
- it "returns the limit" do
259
- @context.per_page.should == 50
260
- end
261
-
262
- end
263
-
264
- end
265
-
266
- describe "#sum" do
267
-
268
- it "returns the sum of all the field values" do
269
- @context.sum(:number).should == 51
270
- end
271
-
272
- end
273
-
274
- end