mongoid 5.4.0 → 6.4.8
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/README.md +3 -3
- data/Rakefile +26 -0
- data/lib/config/locales/en.yml +40 -0
- data/lib/mongoid/atomic/modifiers.rb +2 -2
- data/lib/mongoid/atomic.rb +5 -5
- data/lib/mongoid/attributes/readonly.rb +22 -0
- data/lib/mongoid/attributes.rb +22 -21
- data/lib/mongoid/cacheable.rb +36 -0
- data/lib/mongoid/changeable.rb +36 -0
- data/lib/mongoid/clients/options.rb +55 -250
- data/lib/mongoid/clients/sessions.rb +113 -0
- data/lib/mongoid/clients/storage_options.rb +2 -69
- data/lib/mongoid/clients.rb +10 -63
- data/lib/mongoid/composable.rb +29 -2
- data/lib/mongoid/config.rb +1 -0
- data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
- data/lib/mongoid/contextual/atomic.rb +4 -4
- data/lib/mongoid/contextual/map_reduce.rb +7 -3
- data/lib/mongoid/contextual/memory.rb +9 -4
- data/lib/mongoid/contextual/mongo.rb +65 -30
- data/lib/mongoid/contextual/none.rb +12 -0
- data/lib/mongoid/copyable.rb +13 -6
- data/lib/mongoid/criteria/marshalable.rb +2 -2
- data/lib/mongoid/criteria/modifiable.rb +29 -3
- data/lib/mongoid/criteria/options.rb +25 -0
- data/lib/mongoid/criteria/queryable/aggregable.rb +120 -0
- data/lib/mongoid/criteria/queryable/extensions/array.rb +185 -0
- data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +37 -0
- data/lib/mongoid/criteria/queryable/extensions/boolean.rb +34 -0
- data/lib/mongoid/criteria/queryable/extensions/date.rb +63 -0
- data/lib/mongoid/criteria/queryable/extensions/date_time.rb +53 -0
- data/lib/mongoid/criteria/queryable/extensions/hash.rb +200 -0
- data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +86 -0
- data/lib/mongoid/criteria/queryable/extensions/numeric.rb +90 -0
- data/lib/mongoid/criteria/queryable/extensions/object.rb +206 -0
- data/lib/mongoid/criteria/queryable/extensions/range.rb +70 -0
- data/lib/mongoid/criteria/queryable/extensions/regexp.rb +79 -0
- data/lib/mongoid/criteria/queryable/extensions/set.rb +34 -0
- data/lib/mongoid/criteria/queryable/extensions/string.rb +137 -0
- data/lib/mongoid/criteria/queryable/extensions/symbol.rb +79 -0
- data/lib/mongoid/criteria/queryable/extensions/time.rb +60 -0
- data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +54 -0
- data/lib/mongoid/criteria/queryable/extensions.rb +28 -0
- data/lib/mongoid/criteria/queryable/forwardable.rb +65 -0
- data/lib/mongoid/criteria/queryable/key.rb +103 -0
- data/lib/mongoid/criteria/queryable/macroable.rb +27 -0
- data/lib/mongoid/criteria/queryable/mergeable.rb +273 -0
- data/lib/mongoid/criteria/queryable/optional.rb +429 -0
- data/lib/mongoid/criteria/queryable/options.rb +153 -0
- data/lib/mongoid/criteria/queryable/pipeline.rb +111 -0
- data/lib/mongoid/criteria/queryable/selectable.rb +689 -0
- data/lib/mongoid/criteria/queryable/selector.rb +212 -0
- data/lib/mongoid/criteria/queryable/smash.rb +104 -0
- data/lib/mongoid/criteria/queryable.rb +87 -0
- data/lib/mongoid/criteria.rb +6 -2
- data/lib/mongoid/document.rb +34 -41
- data/lib/mongoid/errors/ambiguous_relationship.rb +1 -1
- data/lib/mongoid/errors/in_memory_collation_not_supported.rb +1 -1
- data/lib/mongoid/errors/invalid_field.rb +2 -2
- data/lib/mongoid/errors/invalid_persistence_option.rb +29 -0
- data/lib/mongoid/errors/invalid_relation.rb +66 -0
- data/lib/mongoid/errors/invalid_session_use.rb +24 -0
- data/lib/mongoid/errors.rb +3 -0
- data/lib/mongoid/evolvable.rb +1 -1
- data/lib/mongoid/extensions/big_decimal.rb +17 -8
- data/lib/mongoid/extensions/date.rb +4 -1
- data/lib/mongoid/extensions/decimal128.rb +3 -3
- data/lib/mongoid/extensions/hash.rb +1 -0
- data/lib/mongoid/extensions/regexp.rb +1 -0
- data/lib/mongoid/extensions/string.rb +6 -3
- data/lib/mongoid/extensions/time.rb +4 -1
- data/lib/mongoid/extensions.rb +0 -4
- data/lib/mongoid/factory.rb +2 -1
- data/lib/mongoid/fields/validators/macro.rb +18 -0
- data/lib/mongoid/findable.rb +2 -2
- data/lib/mongoid/indexable.rb +16 -14
- data/lib/mongoid/interceptable.rb +9 -22
- data/lib/mongoid/matchable/all.rb +2 -2
- data/lib/mongoid/matchable/and.rb +3 -3
- data/lib/mongoid/matchable/default.rb +2 -2
- data/lib/mongoid/matchable/elem_match.rb +28 -0
- data/lib/mongoid/matchable/exists.rb +2 -2
- data/lib/mongoid/matchable/gt.rb +4 -2
- data/lib/mongoid/matchable/gte.rb +4 -2
- data/lib/mongoid/matchable/in.rb +2 -2
- data/lib/mongoid/matchable/lt.rb +4 -2
- data/lib/mongoid/matchable/lte.rb +4 -2
- data/lib/mongoid/matchable/ne.rb +2 -2
- data/lib/mongoid/matchable/nin.rb +2 -2
- data/lib/mongoid/matchable/nor.rb +37 -0
- data/lib/mongoid/matchable/or.rb +3 -3
- data/lib/mongoid/matchable/regexp.rb +3 -3
- data/lib/mongoid/matchable/size.rb +2 -2
- data/lib/mongoid/matchable.rb +16 -7
- data/lib/mongoid/persistable/creatable.rb +5 -3
- data/lib/mongoid/persistable/deletable.rb +5 -3
- data/lib/mongoid/persistable/destroyable.rb +1 -5
- data/lib/mongoid/persistable/settable.rb +5 -5
- data/lib/mongoid/persistable/updatable.rb +7 -14
- data/lib/mongoid/persistable/upsertable.rb +2 -1
- data/lib/mongoid/persistable.rb +4 -6
- data/lib/mongoid/persistence_context.rb +220 -0
- data/lib/mongoid/query_cache.rb +67 -23
- data/lib/mongoid/railtie.rb +17 -1
- data/lib/mongoid/railties/controller_runtime.rb +86 -0
- data/lib/mongoid/relations/accessors.rb +3 -0
- data/lib/mongoid/relations/auto_save.rb +12 -4
- data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +4 -4
- data/lib/mongoid/relations/counter_cache.rb +15 -5
- data/lib/mongoid/relations/eager/base.rb +3 -3
- data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +2 -2
- data/lib/mongoid/relations/eager/has_many.rb +1 -1
- data/lib/mongoid/relations/eager.rb +6 -11
- data/lib/mongoid/relations/embedded/batchable.rb +20 -18
- data/lib/mongoid/relations/embedded/in.rb +13 -1
- data/lib/mongoid/relations/embedded/many.rb +51 -10
- data/lib/mongoid/relations/embedded/one.rb +14 -1
- data/lib/mongoid/relations/macros.rb +9 -1
- data/lib/mongoid/relations/many.rb +4 -0
- data/lib/mongoid/relations/metadata.rb +3 -3
- data/lib/mongoid/relations/options.rb +2 -2
- data/lib/mongoid/relations/proxy.rb +1 -31
- data/lib/mongoid/relations/referenced/in.rb +19 -10
- data/lib/mongoid/relations/referenced/many.rb +30 -26
- data/lib/mongoid/relations/referenced/many_to_many.rb +20 -13
- data/lib/mongoid/relations/referenced/one.rb +15 -1
- data/lib/mongoid/relations/synchronization.rb +12 -12
- data/lib/mongoid/relations/targets/enumerable.rb +24 -4
- data/lib/mongoid/relations/touchable.rb +7 -4
- data/lib/mongoid/reloadable.rb +2 -2
- data/lib/mongoid/scopable.rb +3 -3
- data/lib/mongoid/serializable.rb +1 -1
- data/lib/mongoid/stateful.rb +1 -0
- data/lib/mongoid/tasks/database.rb +3 -2
- data/lib/mongoid/threaded.rb +74 -0
- data/lib/mongoid/traversable.rb +1 -1
- data/lib/mongoid/validatable/uniqueness.rb +1 -2
- data/lib/mongoid/version.rb +1 -1
- data/lib/mongoid.rb +6 -6
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +18 -3
- data/spec/app/models/agent.rb +2 -0
- data/spec/app/models/album.rb +5 -1
- data/spec/app/models/array_field.rb +7 -0
- data/spec/app/models/artist.rb +21 -0
- data/spec/app/models/band.rb +3 -0
- data/spec/app/models/book.rb +2 -1
- data/spec/app/models/delegating_patient.rb +16 -0
- data/spec/app/models/dokument.rb +1 -0
- data/spec/app/models/ordered_post.rb +5 -0
- data/spec/app/models/oscar.rb +1 -2
- data/spec/app/models/page.rb +1 -1
- data/spec/app/models/person.rb +3 -3
- data/spec/app/models/princess.rb +2 -0
- data/spec/app/models/record.rb +1 -0
- data/spec/app/models/subscription.rb +1 -0
- data/spec/app/models/thing.rb +1 -1
- data/spec/config/mongoid.yml +15 -0
- data/spec/integration/document_spec.rb +22 -0
- data/spec/mongoid/atomic/modifiers_spec.rb +3 -3
- data/spec/mongoid/atomic_spec.rb +5 -5
- data/spec/mongoid/attributes/nested_spec.rb +18 -14
- data/spec/mongoid/attributes/readonly_spec.rb +87 -44
- data/spec/mongoid/attributes_spec.rb +90 -5
- data/spec/mongoid/cacheable_spec.rb +112 -0
- data/spec/mongoid/changeable_spec.rb +58 -0
- data/spec/mongoid/clients/factory_spec.rb +80 -28
- data/spec/mongoid/clients/options_spec.rb +396 -95
- data/spec/mongoid/clients/sessions_spec.rb +334 -0
- data/spec/mongoid/clients_spec.rb +243 -101
- data/spec/mongoid/composable_spec.rb +7 -0
- data/spec/mongoid/config_spec.rb +67 -11
- data/spec/mongoid/contextual/atomic_spec.rb +3 -3
- data/spec/mongoid/contextual/geo_near_spec.rb +1 -0
- data/spec/mongoid/contextual/mongo_spec.rb +275 -22
- data/spec/mongoid/contextual/none_spec.rb +15 -0
- data/spec/mongoid/copyable_spec.rb +13 -4
- data/spec/mongoid/criteria/modifiable_spec.rb +297 -16
- data/spec/mongoid/criteria/options_spec.rb +29 -0
- data/spec/mongoid/criteria/queryable/aggregable_spec.rb +370 -0
- data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +523 -0
- data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +59 -0
- data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +58 -0
- data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +213 -0
- data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +330 -0
- data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +405 -0
- data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +58 -0
- data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +65 -0
- data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +327 -0
- data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +65 -0
- data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +77 -0
- data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +108 -0
- data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +309 -0
- data/spec/mongoid/{extensions/origin → criteria/queryable/extensions}/regexp_raw_spec.rb +2 -2
- data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +90 -0
- data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +39 -0
- data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +302 -0
- data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +167 -0
- data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +376 -0
- data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +347 -0
- data/spec/mongoid/criteria/queryable/forwardable_spec.rb +87 -0
- data/spec/mongoid/criteria/queryable/key_spec.rb +52 -0
- data/spec/mongoid/criteria/queryable/mergeable_spec.rb +49 -0
- data/spec/mongoid/criteria/queryable/optional_spec.rb +1799 -0
- data/spec/mongoid/criteria/queryable/options_spec.rb +360 -0
- data/spec/mongoid/criteria/queryable/pipeline_spec.rb +200 -0
- data/spec/mongoid/criteria/queryable/queryable_spec.rb +137 -0
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +4242 -0
- data/spec/mongoid/criteria/queryable/selector_spec.rb +844 -0
- data/spec/mongoid/criteria/queryable/smash_spec.rb +30 -0
- data/spec/mongoid/criteria/scopable_spec.rb +81 -0
- data/spec/mongoid/criteria_spec.rb +156 -22
- data/spec/mongoid/document_spec.rb +100 -90
- data/spec/mongoid/errors/invalid_relation_spec.rb +37 -0
- data/spec/mongoid/errors/mongoid_error_spec.rb +6 -3
- data/spec/mongoid/extensions/big_decimal_spec.rb +321 -19
- data/spec/mongoid/extensions/boolean_spec.rb +14 -0
- data/spec/mongoid/extensions/date_spec.rb +2 -6
- data/spec/mongoid/extensions/date_time_spec.rb +2 -6
- data/spec/mongoid/extensions/decimal128_spec.rb +1 -1
- data/spec/mongoid/extensions/float_spec.rb +8 -1
- data/spec/mongoid/extensions/hash_spec.rb +15 -0
- data/spec/mongoid/extensions/integer_spec.rb +8 -1
- data/spec/mongoid/extensions/object_spec.rb +11 -0
- data/spec/mongoid/extensions/regexp_spec.rb +23 -0
- data/spec/mongoid/extensions/string_spec.rb +53 -4
- data/spec/mongoid/extensions/time_spec.rb +2 -6
- data/spec/mongoid/extensions/time_with_zone_spec.rb +2 -6
- data/spec/mongoid/factory_spec.rb +11 -0
- data/spec/mongoid/fields_spec.rb +1 -1
- data/spec/mongoid/findable_spec.rb +47 -2
- data/spec/mongoid/indexable_spec.rb +15 -3
- data/spec/mongoid/interceptable_spec.rb +85 -19
- data/spec/mongoid/matchable/all_spec.rb +4 -4
- data/spec/mongoid/matchable/and_spec.rb +10 -10
- data/spec/mongoid/matchable/default_spec.rb +12 -12
- data/spec/mongoid/matchable/elem_match_spec.rb +86 -0
- data/spec/mongoid/matchable/exists_spec.rb +5 -5
- data/spec/mongoid/matchable/gt_spec.rb +18 -7
- data/spec/mongoid/matchable/gte_spec.rb +17 -7
- data/spec/mongoid/matchable/in_spec.rb +5 -5
- data/spec/mongoid/matchable/lt_spec.rb +18 -7
- data/spec/mongoid/matchable/lte_spec.rb +18 -7
- data/spec/mongoid/matchable/ne_spec.rb +5 -5
- data/spec/mongoid/matchable/nin_spec.rb +5 -5
- data/spec/mongoid/matchable/nor_spec.rb +209 -0
- data/spec/mongoid/matchable/or_spec.rb +7 -7
- data/spec/mongoid/matchable/regexp_spec.rb +5 -5
- data/spec/mongoid/matchable/size_spec.rb +3 -3
- data/spec/mongoid/matchable_spec.rb +199 -54
- data/spec/mongoid/persistable/creatable_spec.rb +7 -2
- data/spec/mongoid/persistable/deletable_spec.rb +35 -1
- data/spec/mongoid/persistable/destroyable_spec.rb +25 -2
- data/spec/mongoid/persistable/incrementable_spec.rb +6 -6
- data/spec/mongoid/persistable/savable_spec.rb +34 -29
- data/spec/mongoid/persistable/settable_spec.rb +77 -27
- data/spec/mongoid/persistable/updatable_spec.rb +182 -3
- data/spec/mongoid/persistable_spec.rb +16 -16
- data/spec/mongoid/persistence_context_spec.rb +694 -0
- data/spec/mongoid/positional_spec.rb +1 -1
- data/spec/mongoid/query_cache_spec.rb +170 -12
- data/spec/mongoid/relations/accessors_spec.rb +1 -1
- data/spec/mongoid/relations/auto_save_spec.rb +39 -6
- data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +4 -4
- data/spec/mongoid/relations/builders_spec.rb +37 -10
- data/spec/mongoid/relations/counter_cache_spec.rb +64 -3
- data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +16 -0
- data/spec/mongoid/relations/eager_spec.rb +40 -0
- data/spec/mongoid/relations/embedded/many_spec.rb +305 -59
- data/spec/mongoid/relations/embedded/one_spec.rb +2 -1
- data/spec/mongoid/relations/macros_spec.rb +415 -7
- data/spec/mongoid/relations/metadata_spec.rb +15 -1
- data/spec/mongoid/relations/proxy_spec.rb +27 -1
- data/spec/mongoid/relations/referenced/in_spec.rb +41 -1
- data/spec/mongoid/relations/referenced/many_spec.rb +35 -25
- data/spec/mongoid/relations/referenced/many_to_many_spec.rb +14 -26
- data/spec/mongoid/relations/synchronization_spec.rb +48 -2
- data/spec/mongoid/relations/targets/enumerable_spec.rb +108 -0
- data/spec/mongoid/relations/touchable_spec.rb +40 -0
- data/spec/mongoid/reloadable_spec.rb +51 -0
- data/spec/mongoid/scopable_spec.rb +13 -0
- data/spec/mongoid/serializable_spec.rb +0 -50
- data/spec/mongoid/threaded_spec.rb +68 -0
- data/spec/mongoid/validatable/presence_spec.rb +1 -1
- data/spec/mongoid/validatable/uniqueness_spec.rb +18 -9
- data/spec/mongoid/validatable_spec.rb +16 -0
- data/spec/rails/controller_extension/controller_runtime_spec.rb +110 -0
- data/spec/spec_helper.rb +101 -8
- data/spec/support/cluster_config.rb +158 -0
- data/spec/support/constraints.rb +101 -0
- data/spec/support/macros.rb +20 -0
- data/spec/support/session_registry.rb +50 -0
- data/spec/support/spec_config.rb +42 -0
- data.tar.gz.sig +0 -0
- metadata +163 -61
- metadata.gz.sig +0 -0
- data/lib/mongoid/clients/thread_options.rb +0 -19
- data/lib/mongoid/extensions/origin/regexp_raw.rb +0 -43
- data/lib/mongoid/railties/document.rb +0 -12
- data/spec/mongoid/railties/document_spec.rb +0 -24
@@ -0,0 +1,360 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Mongoid::Criteria::Queryable::Options do
|
4
|
+
|
5
|
+
describe "#__deep_copy__" do
|
6
|
+
|
7
|
+
let(:sort) do
|
8
|
+
[[ :name, :asc ]]
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:options) do
|
12
|
+
described_class.new
|
13
|
+
end
|
14
|
+
|
15
|
+
before do
|
16
|
+
options[:sort] = sort
|
17
|
+
end
|
18
|
+
|
19
|
+
let(:cloned) do
|
20
|
+
options.__deep_copy__
|
21
|
+
end
|
22
|
+
|
23
|
+
it "returns an equal copy" do
|
24
|
+
expect(cloned).to eq(options)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "performs a deep copy" do
|
28
|
+
expect(cloned[:sort]).to_not equal(sort)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#fields" do
|
33
|
+
|
34
|
+
let(:options) do
|
35
|
+
described_class.new
|
36
|
+
end
|
37
|
+
|
38
|
+
context "when field options exist" do
|
39
|
+
|
40
|
+
before do
|
41
|
+
options[:fields] = { name: 1 }
|
42
|
+
end
|
43
|
+
|
44
|
+
it "returns the field options" do
|
45
|
+
expect(options.fields).to eq({ "name" => 1 })
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "when field options do not exist" do
|
50
|
+
|
51
|
+
it "returns nil" do
|
52
|
+
expect(options.fields).to be_nil
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "#limit" do
|
58
|
+
|
59
|
+
let(:options) do
|
60
|
+
described_class.new
|
61
|
+
end
|
62
|
+
|
63
|
+
context "when limit options exist" do
|
64
|
+
|
65
|
+
before do
|
66
|
+
options[:limit] = 20
|
67
|
+
end
|
68
|
+
|
69
|
+
it "returns the limit options" do
|
70
|
+
expect(options.limit).to eq(20)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context "when limit options do not exist" do
|
75
|
+
|
76
|
+
it "returns nil" do
|
77
|
+
expect(options.limit).to be_nil
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "#skip" do
|
83
|
+
|
84
|
+
let(:options) do
|
85
|
+
described_class.new
|
86
|
+
end
|
87
|
+
|
88
|
+
context "when skip options exist" do
|
89
|
+
|
90
|
+
before do
|
91
|
+
options[:skip] = 100
|
92
|
+
end
|
93
|
+
|
94
|
+
it "returns the skip options" do
|
95
|
+
expect(options.skip).to eq(100)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context "when skip options do not exist" do
|
100
|
+
|
101
|
+
it "returns nil" do
|
102
|
+
expect(options.skip).to be_nil
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "#sort" do
|
108
|
+
|
109
|
+
let(:options) do
|
110
|
+
described_class.new
|
111
|
+
end
|
112
|
+
|
113
|
+
context "when sort options exist" do
|
114
|
+
|
115
|
+
before do
|
116
|
+
options[:sort] = { name: 1 }
|
117
|
+
end
|
118
|
+
|
119
|
+
it "returns the sort options" do
|
120
|
+
expect(options.sort).to eq({ "name" => 1 })
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context "when sort options do not exist" do
|
125
|
+
|
126
|
+
it "returns nil" do
|
127
|
+
expect(options.sort).to be_nil
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
[ :store, :[]= ].each do |method|
|
133
|
+
|
134
|
+
describe "##{method}" do
|
135
|
+
|
136
|
+
context "when aliases are provided" do
|
137
|
+
|
138
|
+
context "when the alias has no serializer" do
|
139
|
+
|
140
|
+
let(:options) do
|
141
|
+
described_class.new({ "id" => "_id" })
|
142
|
+
end
|
143
|
+
|
144
|
+
before do
|
145
|
+
options.send(method, :sort, { :id => 1 })
|
146
|
+
end
|
147
|
+
|
148
|
+
it "stores the field in the options by database name" do
|
149
|
+
expect(options[:sort]).to eq({ "_id" => 1 })
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
context "when no serializers are provided" do
|
155
|
+
|
156
|
+
let(:options) do
|
157
|
+
described_class.new
|
158
|
+
end
|
159
|
+
|
160
|
+
context "when provided a standard object" do
|
161
|
+
|
162
|
+
context "when the keys are strings" do
|
163
|
+
|
164
|
+
it "does not serialize values" do
|
165
|
+
expect(options.send(method, "limit", "5")).to eq("5")
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
context "when the keys are symbols" do
|
170
|
+
|
171
|
+
it "does not serialize values" do
|
172
|
+
expect(options.send(method, :limit, "5")).to eq("5")
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
context "when serializers are provided" do
|
179
|
+
|
180
|
+
context "when the serializer is not localized" do
|
181
|
+
|
182
|
+
before(:all) do
|
183
|
+
class Field
|
184
|
+
def localized?
|
185
|
+
false
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
after(:all) do
|
191
|
+
Object.send(:remove_const, :Field)
|
192
|
+
end
|
193
|
+
|
194
|
+
let(:options) do
|
195
|
+
described_class.new({}, { "key" => Field.new })
|
196
|
+
end
|
197
|
+
|
198
|
+
context "when the criterion is simple" do
|
199
|
+
|
200
|
+
before do
|
201
|
+
options.send(method, :limit, 1)
|
202
|
+
end
|
203
|
+
|
204
|
+
it "does not localize the keys" do
|
205
|
+
expect(options[:limit]).to eq(1)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
context "when the criterion is complex" do
|
210
|
+
|
211
|
+
before do
|
212
|
+
options.send(method, :sort, { :key => 1 })
|
213
|
+
end
|
214
|
+
|
215
|
+
it "does not localize the keys" do
|
216
|
+
expect(options[:sort]).to eq({ "key" => 1 })
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
context "when the serializer is localized" do
|
222
|
+
|
223
|
+
before(:all) do
|
224
|
+
class Field
|
225
|
+
def localized?
|
226
|
+
true
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
after(:all) do
|
232
|
+
Object.send(:remove_const, :Field)
|
233
|
+
::I18n.locale = :en
|
234
|
+
end
|
235
|
+
|
236
|
+
let(:options) do
|
237
|
+
described_class.new({}, { "key" => Field.new })
|
238
|
+
end
|
239
|
+
|
240
|
+
before do
|
241
|
+
::I18n.locale = :de
|
242
|
+
end
|
243
|
+
|
244
|
+
context "when the criterion is simple" do
|
245
|
+
|
246
|
+
before do
|
247
|
+
options.send(method, :limit, 1)
|
248
|
+
end
|
249
|
+
|
250
|
+
it "does not localize the keys" do
|
251
|
+
expect(options[:limit]).to eq(1)
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
context "when the criterion is complex" do
|
256
|
+
|
257
|
+
before do
|
258
|
+
options.send(method, :sort, { :key => 1 })
|
259
|
+
end
|
260
|
+
|
261
|
+
it "does not localize the keys" do
|
262
|
+
expect(options[:sort]).to eq({ "key.de" => 1 })
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
describe "#to_pipeline" do
|
271
|
+
|
272
|
+
let(:options) do
|
273
|
+
described_class.new
|
274
|
+
end
|
275
|
+
|
276
|
+
context "when no options exist" do
|
277
|
+
|
278
|
+
let(:pipeline) do
|
279
|
+
options.to_pipeline
|
280
|
+
end
|
281
|
+
|
282
|
+
it "returns an empty array" do
|
283
|
+
expect(pipeline).to be_empty
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
context "when multiple options exist" do
|
288
|
+
|
289
|
+
before do
|
290
|
+
options[:fields] = { "name" => 1 }
|
291
|
+
options[:skip] = 10
|
292
|
+
options[:limit] = 10
|
293
|
+
options[:sort] = { "name" => 1 }
|
294
|
+
end
|
295
|
+
|
296
|
+
let(:pipeline) do
|
297
|
+
options.to_pipeline
|
298
|
+
end
|
299
|
+
|
300
|
+
it "converts the option to a $sort" do
|
301
|
+
expect(pipeline).to eq([
|
302
|
+
{ "$skip" => 10 },
|
303
|
+
{ "$limit" => 10 },
|
304
|
+
{ "$sort" => { "name" => 1 }}
|
305
|
+
])
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
context "when a sort exists" do
|
310
|
+
|
311
|
+
before do
|
312
|
+
options[:sort] = { "name" => 1 }
|
313
|
+
end
|
314
|
+
|
315
|
+
let(:pipeline) do
|
316
|
+
options.to_pipeline
|
317
|
+
end
|
318
|
+
|
319
|
+
it "converts the option to a $sort" do
|
320
|
+
expect(pipeline).to eq([
|
321
|
+
{ "$sort" => { "name" => 1 }}
|
322
|
+
])
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
context "when a limit exists" do
|
327
|
+
|
328
|
+
before do
|
329
|
+
options[:limit] = 10
|
330
|
+
end
|
331
|
+
|
332
|
+
let(:pipeline) do
|
333
|
+
options.to_pipeline
|
334
|
+
end
|
335
|
+
|
336
|
+
it "converts the option to a $sort" do
|
337
|
+
expect(pipeline).to eq([
|
338
|
+
{ "$limit" => 10 }
|
339
|
+
])
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
context "when a skip exists" do
|
344
|
+
|
345
|
+
before do
|
346
|
+
options[:skip] = 10
|
347
|
+
end
|
348
|
+
|
349
|
+
let(:pipeline) do
|
350
|
+
options.to_pipeline
|
351
|
+
end
|
352
|
+
|
353
|
+
it "converts the option to a $sort" do
|
354
|
+
expect(pipeline).to eq([
|
355
|
+
{ "$skip" => 10 }
|
356
|
+
])
|
357
|
+
end
|
358
|
+
end
|
359
|
+
end
|
360
|
+
end
|
@@ -0,0 +1,200 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Mongoid::Criteria::Queryable::Pipeline do
|
4
|
+
|
5
|
+
describe "#__deep_copy" do
|
6
|
+
|
7
|
+
let(:project) do
|
8
|
+
{ "$project" => { "name" => 1 }}
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:pipeline) do
|
12
|
+
described_class.new
|
13
|
+
end
|
14
|
+
|
15
|
+
before do
|
16
|
+
pipeline.push(project)
|
17
|
+
end
|
18
|
+
|
19
|
+
let(:copied) do
|
20
|
+
pipeline.__deep_copy__
|
21
|
+
end
|
22
|
+
|
23
|
+
it "clones all the objects in the pipeline" do
|
24
|
+
expect(copied.first).to_not equal(project)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "clones the pipeline" do
|
28
|
+
expect(copied).to_not equal(pipeline)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#group" do
|
33
|
+
|
34
|
+
context "when the expression fields are not aliased" do
|
35
|
+
|
36
|
+
let(:pipeline) do
|
37
|
+
described_class.new
|
38
|
+
end
|
39
|
+
|
40
|
+
context "when using full notation" do
|
41
|
+
|
42
|
+
before do
|
43
|
+
pipeline.group(count: { "$sum" => 1 }, max: { "$max" => "likes" })
|
44
|
+
end
|
45
|
+
|
46
|
+
it "adds the group operation to the pipeline" do
|
47
|
+
expect(pipeline).to eq([
|
48
|
+
{ "$group" => { "count" => { "$sum" => 1 }, "max" => { "$max" => "likes" }}}
|
49
|
+
])
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context "when using symbol shortcuts" do
|
54
|
+
|
55
|
+
before do
|
56
|
+
pipeline.group(:count.sum => 1, :max.max => "likes")
|
57
|
+
end
|
58
|
+
|
59
|
+
it "adds the group operation to the pipeline" do
|
60
|
+
expect(pipeline).to eq([
|
61
|
+
{ "$group" => { "count" => { "$sum" => 1 }, "max" => { "$max" => "likes" }}}
|
62
|
+
])
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "#initialize" do
|
69
|
+
|
70
|
+
context "when provided aliases" do
|
71
|
+
|
72
|
+
let(:aliases) do
|
73
|
+
{ "id" => "_id" }
|
74
|
+
end
|
75
|
+
|
76
|
+
let(:pipeline) do
|
77
|
+
described_class.new(aliases)
|
78
|
+
end
|
79
|
+
|
80
|
+
it "sets the aliases" do
|
81
|
+
expect(pipeline.aliases).to eq(aliases)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context "when not provided aliases" do
|
86
|
+
|
87
|
+
let(:pipeline) do
|
88
|
+
described_class.new
|
89
|
+
end
|
90
|
+
|
91
|
+
it "sets the aliases to an empty hash" do
|
92
|
+
expect(pipeline.aliases).to be_empty
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "#project" do
|
98
|
+
|
99
|
+
let(:pipeline) do
|
100
|
+
described_class.new("id" => "_id")
|
101
|
+
end
|
102
|
+
|
103
|
+
context "when the field is not aliased" do
|
104
|
+
|
105
|
+
before do
|
106
|
+
pipeline.project(name: 1)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "sets the aliased projection" do
|
110
|
+
expect(pipeline).to eq([
|
111
|
+
{ "$project" => { "name" => 1 }}
|
112
|
+
])
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context "when the field is aliased" do
|
117
|
+
|
118
|
+
before do
|
119
|
+
pipeline.project(id: 1)
|
120
|
+
end
|
121
|
+
|
122
|
+
it "sets the aliased projection" do
|
123
|
+
expect(pipeline).to eq([
|
124
|
+
{ "$project" => { "_id" => 1 }}
|
125
|
+
])
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe "#unwind" do
|
131
|
+
|
132
|
+
let(:pipeline) do
|
133
|
+
described_class.new("alias" => "a")
|
134
|
+
end
|
135
|
+
|
136
|
+
context "when provided a symbol" do
|
137
|
+
|
138
|
+
context "when the symbol begins with $" do
|
139
|
+
|
140
|
+
before do
|
141
|
+
pipeline.unwind(:$author)
|
142
|
+
end
|
143
|
+
|
144
|
+
it "converts the symbol to a string" do
|
145
|
+
expect(pipeline).to eq([{ "$unwind" => "$author" }])
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context "when the symbol does not begin with $" do
|
150
|
+
|
151
|
+
before do
|
152
|
+
pipeline.unwind(:author)
|
153
|
+
end
|
154
|
+
|
155
|
+
it "converts the symbol to a string and prepends $" do
|
156
|
+
expect(pipeline).to eq([{ "$unwind" => "$author" }])
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
context "when provided a string" do
|
162
|
+
|
163
|
+
context "when the string begins with $" do
|
164
|
+
|
165
|
+
before do
|
166
|
+
pipeline.unwind("$author")
|
167
|
+
end
|
168
|
+
|
169
|
+
it "sets the string" do
|
170
|
+
expect(pipeline).to eq([{ "$unwind" => "$author" }])
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
context "when the string does not begin with $" do
|
175
|
+
|
176
|
+
before do
|
177
|
+
pipeline.unwind(:author)
|
178
|
+
end
|
179
|
+
|
180
|
+
it "prepends $ to the string" do
|
181
|
+
expect(pipeline).to eq([{ "$unwind" => "$author" }])
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
context "when provided a string alias" do
|
187
|
+
|
188
|
+
context "when the string does not begin with $" do
|
189
|
+
|
190
|
+
before do
|
191
|
+
pipeline.unwind(:alias)
|
192
|
+
end
|
193
|
+
|
194
|
+
it "prepends $ to the string" do
|
195
|
+
expect(pipeline).to eq([{ "$unwind" => "$a" }])
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Mongoid::Query do
|
4
|
+
|
5
|
+
describe "#==" do
|
6
|
+
|
7
|
+
let(:query) do
|
8
|
+
described_class.new
|
9
|
+
end
|
10
|
+
|
11
|
+
context "when the objects have the same selector" do
|
12
|
+
|
13
|
+
let(:other) do
|
14
|
+
described_class.new
|
15
|
+
end
|
16
|
+
|
17
|
+
context "when the options are the same" do
|
18
|
+
|
19
|
+
it "returns true" do
|
20
|
+
expect(query).to eq(other)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "when the options are different" do
|
25
|
+
|
26
|
+
before do
|
27
|
+
other.options[:skip] = 20
|
28
|
+
end
|
29
|
+
|
30
|
+
it "returns false" do
|
31
|
+
expect(query).to_not eq(other)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "when the objects have different selectors" do
|
37
|
+
|
38
|
+
let(:other) do
|
39
|
+
described_class.new do |query|
|
40
|
+
query.selector["field"] = "value"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
it "returns false" do
|
45
|
+
expect(query).to_not eq(other)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "when the objects are different types" do
|
50
|
+
|
51
|
+
let(:other) do
|
52
|
+
"Query"
|
53
|
+
end
|
54
|
+
|
55
|
+
it "returns false" do
|
56
|
+
expect(query).to_not eq(other)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "#initialize" do
|
62
|
+
|
63
|
+
context "when passed no arguments" do
|
64
|
+
|
65
|
+
let(:query) do
|
66
|
+
described_class.new
|
67
|
+
end
|
68
|
+
|
69
|
+
it "intializes the selector" do
|
70
|
+
expect(query.selector).to eq({})
|
71
|
+
end
|
72
|
+
|
73
|
+
it "initializes the options" do
|
74
|
+
expect(query.options).to eq({})
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "when passed a block" do
|
79
|
+
|
80
|
+
let(:query) do
|
81
|
+
described_class.new do |query|
|
82
|
+
query.selector["field"] = "value"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
it "yields to the block" do
|
87
|
+
expect(query.selector).to eq({ "field" => "value" })
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "#initialize_copy" do
|
93
|
+
|
94
|
+
let(:sort) do
|
95
|
+
{ "name" => 1 }
|
96
|
+
end
|
97
|
+
|
98
|
+
let(:query) do
|
99
|
+
described_class.new do |query|
|
100
|
+
query.selector["field"] = "value"
|
101
|
+
query.options["sort"] = { "field" => sort }
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
let!(:cloned) do
|
106
|
+
query.clone
|
107
|
+
end
|
108
|
+
|
109
|
+
it "returns a query" do
|
110
|
+
expect(cloned).to be_a(Mongoid::Query)
|
111
|
+
end
|
112
|
+
|
113
|
+
it "returns a new instance" do
|
114
|
+
expect(cloned).to_not equal(query)
|
115
|
+
end
|
116
|
+
|
117
|
+
it "retains the selector values" do
|
118
|
+
expect(cloned.selector).to eq({ "field" => "value" })
|
119
|
+
end
|
120
|
+
|
121
|
+
it "retains the option values" do
|
122
|
+
expect(cloned.options).to eq({ "sort" => { "field" => sort }})
|
123
|
+
end
|
124
|
+
|
125
|
+
it "deep copies the selector" do
|
126
|
+
expect(cloned.selector).to_not equal(query.selector)
|
127
|
+
end
|
128
|
+
|
129
|
+
it "deep copies the options" do
|
130
|
+
expect(cloned.options).to_not equal(query.options)
|
131
|
+
end
|
132
|
+
|
133
|
+
it "deep copies n levels deep" do
|
134
|
+
expect(cloned.options["sort"]["field"]).to_not equal(sort)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|