mongoid_monkey 0.1.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.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +40 -0
- data/lib/mongoid_monkey.rb +15 -0
- data/lib/patches/atomic.rb +109 -0
- data/lib/patches/big_decimal.rb +38 -0
- data/lib/patches/instrument.rb +45 -0
- data/lib/patches/list_collections.rb +14 -0
- data/lib/patches/reorder.rb +11 -0
- data/lib/version.rb +3 -0
- data/spec/config/mongodb-mmapv1.conf +2 -0
- data/spec/config/mongodb-wiredtiger.conf +2 -0
- data/spec/gemfile/mongoid3.gemfile +5 -0
- data/spec/gemfile/mongoid4.gemfile +5 -0
- data/spec/gemfile/mongoid5.gemfile +5 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/unit/atomic_spec.rb +1067 -0
- data/spec/unit/big_decimal_spec.rb +461 -0
- data/spec/unit/instrument_spec.rb +12 -0
- data/spec/unit/list_collections_spec.rb +62 -0
- data/spec/unit/reorder_spec.rb +30 -0
- metadata +119 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 35ce26c7c1fa842774c1c8724d3060e63d14bcc3
|
4
|
+
data.tar.gz: 73b16e660f5088a4ef8f7a07b0ad37a1731ead1c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1b98576cffc2d498853d06b1dbffaef9a5ea53d5c184c6884e7fe146261a5da5cea89a90b2d633d0d7d0264edea9cfd1b3d2a49bcf63a2fa34319e1e045cad55
|
7
|
+
data.tar.gz: f07e78cc1905d110a4042dac8f8f15448dc5d8d39dd7412c1ad1f8a693c59d5f39e12ffebe449a0da7030651fad95500308bd156970f5fec3e07b4846b6fc38b
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Johnny Shields
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# Mongoid Monkey
|
2
|
+
|
3
|
+
### Monkey Patches for Mongoid
|
4
|
+
|
5
|
+
Mongoid Monkey is a collection of monkey patches for Mongoid 3, 4, 5, including feature
|
6
|
+
backports, fixes, and forward compatibility.
|
7
|
+
|
8
|
+
### Warning
|
9
|
+
|
10
|
+
The patches in this gem will change/override the behavior of Mongoid. While effort has been
|
11
|
+
made to be as backward compatible as possible, use at your own risk.
|
12
|
+
|
13
|
+
### Installation
|
14
|
+
|
15
|
+
In your Gemfile, require this gem **after** requiring `mongoid`.
|
16
|
+
|
17
|
+
### Version Requirement
|
18
|
+
|
19
|
+
* Works with Mongoid 3, 4, 5
|
20
|
+
* Due to the `list_collections` patch, this gem requires **at least MongoDB 3.0.** Other patches will work on older MongoDB versions.
|
21
|
+
|
22
|
+
### Patch List
|
23
|
+
|
24
|
+
Installing this gem will apply all monkey patches for the Mongoid version you are using.
|
25
|
+
If you would only like some of the patches, please copy and paste the code to your app directly
|
26
|
+
(e.g. `/config/initializers` if using Rails.)
|
27
|
+
|
28
|
+
| File | Description | 3 | 4 | 5 |
|
29
|
+
| --- | --- | --- | --- | --- |
|
30
|
+
| `atomic.rb` | Backport syntax change of atomic query methods. | ● | | |
|
31
|
+
| `big_decimal.rb` | Fixes buggy BigDecimal behavior. | ● | ● | ● |
|
32
|
+
| `instrument.rb` | Backport instrumentation change to Moped 1. | ● | | |
|
33
|
+
| `list_collections.rb` | Fetch collections via `listCollections` command; required for WiredTiger. | ● | ● | |
|
34
|
+
| `reorder.rb` | Backport `Criteria#reorder` method. | ● | | |
|
35
|
+
|
36
|
+
### License
|
37
|
+
|
38
|
+
* This project is licensed under the MIT License.
|
39
|
+
* Some code in this repo is adapted from the fantastic work of Durran Jordan, et. al. on Mongoid.
|
40
|
+
* (c) Copyright 2016 Johnny Shields.
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'version'
|
2
|
+
|
3
|
+
if Mongoid::VERSION =~ /\A3\./
|
4
|
+
require 'patches/atomic'
|
5
|
+
require 'patches/reorder'
|
6
|
+
end
|
7
|
+
|
8
|
+
if Mongoid::VERSION =~ /\A[345]\./
|
9
|
+
require 'patches/big_decimal'
|
10
|
+
end
|
11
|
+
|
12
|
+
if defined?(Moped)
|
13
|
+
require 'patches/instrument' if Moped::VERSION =~ /\A1\./
|
14
|
+
require 'patches/list_collections'
|
15
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module Contextual
|
3
|
+
module Atomic
|
4
|
+
|
5
|
+
def add_to_set_with_mongoid4(*args)
|
6
|
+
if args.length == 1 && args.first.is_a?(Hash)
|
7
|
+
query.update_all("$addToSet" => collect_operations(args.first))
|
8
|
+
else
|
9
|
+
add_to_set_without_mongoid4(*args)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
alias_method_chain :add_to_set, :mongoid4
|
13
|
+
|
14
|
+
def bit_with_mongoid4(*args)
|
15
|
+
if args.length == 1 && args.first.is_a?(Hash)
|
16
|
+
query.update_all("$bit" => collect_operations(args.first))
|
17
|
+
else
|
18
|
+
bit_without_mongoid4(*args)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
alias_method_chain :bit, :mongoid4
|
22
|
+
|
23
|
+
def inc_with_mongoid4(*args)
|
24
|
+
if args.length == 1 && args.first.is_a?(Hash)
|
25
|
+
query.update_all("$inc" => collect_operations(args.first))
|
26
|
+
else
|
27
|
+
inc_without_mongoid4(*args)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
alias_method_chain :inc, :mongoid4
|
31
|
+
|
32
|
+
def pop_with_mongoid4(*args)
|
33
|
+
if args.length == 1 && args.first.is_a?(Hash)
|
34
|
+
query.update_all("$pop" => collect_operations(args.first))
|
35
|
+
else
|
36
|
+
pop_without_mongoid4(*args)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
alias_method_chain :pop, :mongoid4
|
40
|
+
|
41
|
+
def pull_with_mongoid4(*args)
|
42
|
+
if args.length == 1 && args.first.is_a?(Hash)
|
43
|
+
query.update_all("$pull" => collect_operations(args.first))
|
44
|
+
else
|
45
|
+
pull_without_mongoid4(*args)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
alias_method_chain :pull, :mongoid4
|
49
|
+
|
50
|
+
def pull_all_with_mongoid4(*args)
|
51
|
+
if args.length == 1 && args.first.is_a?(Hash)
|
52
|
+
query.update_all("$pullAll" => collect_operations(args.first))
|
53
|
+
else
|
54
|
+
pull_all_without_mongoid4(*args)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
alias_method_chain :pull_all, :mongoid4
|
58
|
+
|
59
|
+
def push_with_mongoid4(*args)
|
60
|
+
if args.length == 1 && args.first.is_a?(Hash)
|
61
|
+
query.update_all("$push" => collect_operations(args.first))
|
62
|
+
else
|
63
|
+
push_without_mongoid4(*args)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
alias_method_chain :push, :mongoid4
|
67
|
+
|
68
|
+
def push_all_with_mongoid4(*args)
|
69
|
+
if args.length == 1 && args.first.is_a?(Hash)
|
70
|
+
query.update_all("$pushAll" => collect_operations(args.first))
|
71
|
+
else
|
72
|
+
push_all_without_mongoid4(*args)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
alias_method_chain :push_all, :mongoid4
|
76
|
+
|
77
|
+
def rename_with_mongoid4(*args)
|
78
|
+
if args.length == 1 && args.first.is_a?(Hash)
|
79
|
+
operations = args.first.inject({}) do |ops, (old_name, new_name)|
|
80
|
+
ops[old_name] = new_name.to_s
|
81
|
+
ops
|
82
|
+
end
|
83
|
+
query.update_all("$rename" => collect_operations(operations))
|
84
|
+
else
|
85
|
+
rename_without_mongoid4(*args)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
alias_method_chain :rename, :mongoid4
|
89
|
+
|
90
|
+
def set_with_mongoid4(*args)
|
91
|
+
if args.length == 1 && args.first.is_a?(Hash)
|
92
|
+
query.update_all("$set" => collect_operations(args.first))
|
93
|
+
else
|
94
|
+
set_without_mongoid4(*args)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
alias_method_chain :set, :mongoid4
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
def collect_operations(ops)
|
102
|
+
ops.inject({}) do |operations, (field, value)|
|
103
|
+
operations[database_field_name(field)] = value.mongoize
|
104
|
+
operations
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# Fixes inconsistent behavior of BigDecimal. This can be removed after
|
2
|
+
# https://github.com/mongodb/mongoid/pull/4164 is merged, planned for Mongoid 6.
|
3
|
+
|
4
|
+
module MongoidMonkey
|
5
|
+
module Mongoid
|
6
|
+
module Extensions
|
7
|
+
module BigDecimal
|
8
|
+
|
9
|
+
def numeric?
|
10
|
+
true
|
11
|
+
end
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
|
15
|
+
def demongoize(object)
|
16
|
+
object && object.numeric? ? ::BigDecimal.new(object.to_s) : nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def mongoize(object)
|
20
|
+
object && object.numeric? ? object.to_s : nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module String
|
26
|
+
|
27
|
+
def numeric?
|
28
|
+
true if Float(self) rescue (self =~ /^NaN|\-?Infinity$/)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
::BigDecimal.__send__(:include, MongoidMonkey::Mongoid::Extensions::BigDecimal)
|
36
|
+
::BigDecimal.extend(MongoidMonkey::Mongoid::Extensions::BigDecimal::ClassMethods)
|
37
|
+
|
38
|
+
::String.__send__(:include, MongoidMonkey::Mongoid::Extensions::String)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# Instrument Moped 1.x same as Moped 2.x.
|
2
|
+
# Useful for integration with third-party services.
|
3
|
+
|
4
|
+
module Moped
|
5
|
+
module Instrumentable
|
6
|
+
class Noop
|
7
|
+
|
8
|
+
class << self
|
9
|
+
|
10
|
+
# Do not instrument anything.
|
11
|
+
def instrument(name, payload = {})
|
12
|
+
yield payload if block_given?
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
module Moped
|
20
|
+
module Instrumentable
|
21
|
+
|
22
|
+
TOPIC = "query.moped"
|
23
|
+
|
24
|
+
def instrumenter
|
25
|
+
@instrumenter ||= Moped::Instrumentable::Noop
|
26
|
+
end
|
27
|
+
|
28
|
+
def instrument(name, payload = {}, &block)
|
29
|
+
instrumenter.instrument(name, payload, &block)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
module Moped
|
35
|
+
class Node
|
36
|
+
include Moped::Instrumentable
|
37
|
+
|
38
|
+
def logging_with_instrument(operations, &block)
|
39
|
+
instrument(TOPIC, prefix: " MOPED: #{resolved_address}", ops: operations) do
|
40
|
+
logging_without_instrument(operations, &block)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
alias_method_chain :logging, :instrument
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Get collection_names via for MongoDB 3.0+ listCollections command.
|
2
|
+
# Required to use Moped (Mongoid 3/4) with WiredTiger.
|
3
|
+
|
4
|
+
module Moped
|
5
|
+
class Database
|
6
|
+
|
7
|
+
def collection_names
|
8
|
+
namespaces = Collection.new(self, "$cmd").find(listCollections: 1, filter: { name: { "$not" => /system\.|\$/ } }).first
|
9
|
+
namespaces["cursor"]["firstBatch"].map do |doc|
|
10
|
+
doc["name"]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/version.rb
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
|
4
|
+
require 'mongoid'
|
5
|
+
require 'mongoid_monkey'
|
6
|
+
require 'rspec'
|
7
|
+
|
8
|
+
Mongoid.configure do |config|
|
9
|
+
config.connect_to 'mongoid_monkey_test'
|
10
|
+
end
|
11
|
+
|
12
|
+
Mongoid.logger.level = Logger::INFO
|
13
|
+
Mongo::Logger.logger.level = Logger::INFO unless Mongoid::VERSION =~ /\A[34]\./
|
14
|
+
|
15
|
+
RSpec.configure do |config|
|
16
|
+
config.after(:all) do
|
17
|
+
if Mongoid::VERSION =~ /\A[34]\./
|
18
|
+
Mongoid.default_session.drop
|
19
|
+
else
|
20
|
+
Mongoid::Clients.default.database.drop
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,1067 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
if Mongoid::VERSION =~ /\A3\./
|
4
|
+
|
5
|
+
class Band
|
6
|
+
include Mongoid::Document
|
7
|
+
field :name, type: String
|
8
|
+
field :genres, type: Array
|
9
|
+
field :mems, as: :members, type: Array
|
10
|
+
field :likes, type: Integer
|
11
|
+
field :y, as: :years, type: Integer
|
12
|
+
end
|
13
|
+
|
14
|
+
# Mongoid 3
|
15
|
+
describe Mongoid::Contextual::Atomic do
|
16
|
+
|
17
|
+
describe "#add_to_set" do
|
18
|
+
|
19
|
+
let!(:depeche_mode) do
|
20
|
+
Band.create(members: [ "Dave" ])
|
21
|
+
end
|
22
|
+
|
23
|
+
let!(:new_order) do
|
24
|
+
Band.create(members: [ "Peter" ])
|
25
|
+
end
|
26
|
+
|
27
|
+
let!(:smiths) do
|
28
|
+
Band.create
|
29
|
+
end
|
30
|
+
|
31
|
+
context "when the criteria has no sorting" do
|
32
|
+
|
33
|
+
let(:criteria) do
|
34
|
+
Band.all
|
35
|
+
end
|
36
|
+
|
37
|
+
let(:context) do
|
38
|
+
Mongoid::Contextual::Mongo.new(criteria)
|
39
|
+
end
|
40
|
+
|
41
|
+
before do
|
42
|
+
context.add_to_set(:members, "Dave")
|
43
|
+
end
|
44
|
+
|
45
|
+
it "does not add duplicates" do
|
46
|
+
depeche_mode.reload.members.should eq([ "Dave" ])
|
47
|
+
end
|
48
|
+
|
49
|
+
it "adds unique values" do
|
50
|
+
new_order.reload.members.should eq([ "Peter", "Dave" ])
|
51
|
+
end
|
52
|
+
|
53
|
+
it "adds to non initialized fields" do
|
54
|
+
smiths.reload.members.should eq([ "Dave" ])
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "when the criteria has sorting" do
|
59
|
+
|
60
|
+
let(:criteria) do
|
61
|
+
Band.asc(:name)
|
62
|
+
end
|
63
|
+
|
64
|
+
let(:context) do
|
65
|
+
Mongoid::Contextual::Mongo.new(criteria)
|
66
|
+
end
|
67
|
+
|
68
|
+
before do
|
69
|
+
context.add_to_set(:members, "Dave")
|
70
|
+
end
|
71
|
+
|
72
|
+
it "does not add duplicates" do
|
73
|
+
depeche_mode.reload.members.should eq([ "Dave" ])
|
74
|
+
end
|
75
|
+
|
76
|
+
it "adds unique values" do
|
77
|
+
new_order.reload.members.should eq([ "Peter", "Dave" ])
|
78
|
+
end
|
79
|
+
|
80
|
+
it "adds to non initialized fields" do
|
81
|
+
smiths.reload.members.should eq([ "Dave" ])
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "#bit" do
|
87
|
+
|
88
|
+
let!(:depeche_mode) do
|
89
|
+
Band.create(likes: 60)
|
90
|
+
end
|
91
|
+
|
92
|
+
let!(:smiths) do
|
93
|
+
Band.create
|
94
|
+
end
|
95
|
+
|
96
|
+
let(:criteria) do
|
97
|
+
Band.all
|
98
|
+
end
|
99
|
+
|
100
|
+
let(:context) do
|
101
|
+
Mongoid::Contextual::Mongo.new(criteria)
|
102
|
+
end
|
103
|
+
|
104
|
+
context "when performing a bitwise and" do
|
105
|
+
|
106
|
+
before do
|
107
|
+
context.bit(:likes, { and: 13 })
|
108
|
+
end
|
109
|
+
|
110
|
+
it "performs the bitwise operation on initialized fields" do
|
111
|
+
depeche_mode.reload.likes.should eq(12)
|
112
|
+
end
|
113
|
+
|
114
|
+
it "does not error on non initialized fields" do
|
115
|
+
smiths.reload.likes.should eq(0)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context "when performing a bitwise or" do
|
120
|
+
|
121
|
+
before do
|
122
|
+
context.bit(:likes, { or: 13 })
|
123
|
+
end
|
124
|
+
|
125
|
+
it "performs the bitwise operation on initialized fields" do
|
126
|
+
depeche_mode.reload.likes.should eq(61)
|
127
|
+
end
|
128
|
+
|
129
|
+
it "does not error on non initialized fields" do
|
130
|
+
smiths.reload.likes.should eq(13)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
context "when chaining bitwise operations" do
|
135
|
+
|
136
|
+
before do
|
137
|
+
context.bit(:likes, { and: 13, or: 10 })
|
138
|
+
end
|
139
|
+
|
140
|
+
it "performs the bitwise operation on initialized fields" do
|
141
|
+
depeche_mode.reload.likes.should eq(14)
|
142
|
+
end
|
143
|
+
|
144
|
+
it "does not error on non initialized fields" do
|
145
|
+
smiths.reload.likes.should eq(10)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
describe "#inc" do
|
151
|
+
|
152
|
+
let!(:depeche_mode) do
|
153
|
+
Band.create(likes: 60)
|
154
|
+
end
|
155
|
+
|
156
|
+
let!(:smiths) do
|
157
|
+
Band.create
|
158
|
+
end
|
159
|
+
|
160
|
+
let!(:beatles) do
|
161
|
+
Band.create(years: 2)
|
162
|
+
end
|
163
|
+
|
164
|
+
let(:criteria) do
|
165
|
+
Band.all
|
166
|
+
end
|
167
|
+
|
168
|
+
let(:context) do
|
169
|
+
Mongoid::Contextual::Mongo.new(criteria)
|
170
|
+
end
|
171
|
+
|
172
|
+
before do
|
173
|
+
context.inc(:likes, 10)
|
174
|
+
end
|
175
|
+
|
176
|
+
context "when the field exists" do
|
177
|
+
|
178
|
+
it "incs the value" do
|
179
|
+
depeche_mode.reload.likes.should eq(70)
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
context "when the field does not exist" do
|
184
|
+
|
185
|
+
it "does not error on the inc" do
|
186
|
+
smiths.likes.should be_nil
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
context "when using the alias" do
|
191
|
+
|
192
|
+
before do
|
193
|
+
context.inc(:years, 1)
|
194
|
+
end
|
195
|
+
|
196
|
+
it "incs the value and read from alias" do
|
197
|
+
beatles.reload.years.should eq(3)
|
198
|
+
end
|
199
|
+
|
200
|
+
it "incs the value and read from field" do
|
201
|
+
beatles.reload.y.should eq(3)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
describe "#pop" do
|
207
|
+
|
208
|
+
let!(:depeche_mode) do
|
209
|
+
Band.create(members: [ "Dave", "Martin" ])
|
210
|
+
end
|
211
|
+
|
212
|
+
let!(:smiths) do
|
213
|
+
Band.create
|
214
|
+
end
|
215
|
+
|
216
|
+
let(:criteria) do
|
217
|
+
Band.all
|
218
|
+
end
|
219
|
+
|
220
|
+
let(:context) do
|
221
|
+
Mongoid::Contextual::Mongo.new(criteria)
|
222
|
+
end
|
223
|
+
|
224
|
+
context "when popping from the front" do
|
225
|
+
|
226
|
+
before do
|
227
|
+
context.pop(:members, -1)
|
228
|
+
end
|
229
|
+
|
230
|
+
it "pops the first element off the array" do
|
231
|
+
depeche_mode.reload.members.should eq([ "Martin" ])
|
232
|
+
end
|
233
|
+
|
234
|
+
it "does not error on uninitialized fields" do
|
235
|
+
smiths.reload.members.should be_nil
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
context "when popping from the rear" do
|
240
|
+
|
241
|
+
before do
|
242
|
+
context.pop(:members, 1)
|
243
|
+
end
|
244
|
+
|
245
|
+
it "pops the last element off the array" do
|
246
|
+
depeche_mode.reload.members.should eq([ "Dave" ])
|
247
|
+
end
|
248
|
+
|
249
|
+
it "does not error on uninitialized fields" do
|
250
|
+
smiths.reload.members.should be_nil
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
describe "#pull" do
|
256
|
+
|
257
|
+
let!(:depeche_mode) do
|
258
|
+
Band.create(members: [ "Dave", "Alan" ])
|
259
|
+
end
|
260
|
+
|
261
|
+
let!(:smiths) do
|
262
|
+
Band.create
|
263
|
+
end
|
264
|
+
|
265
|
+
let(:criteria) do
|
266
|
+
Band.all
|
267
|
+
end
|
268
|
+
|
269
|
+
let(:context) do
|
270
|
+
Mongoid::Contextual::Mongo.new(criteria)
|
271
|
+
end
|
272
|
+
|
273
|
+
before do
|
274
|
+
context.pull(:members, "Alan")
|
275
|
+
end
|
276
|
+
|
277
|
+
it "pulls when the value is found" do
|
278
|
+
depeche_mode.reload.members.should eq([ "Dave" ])
|
279
|
+
end
|
280
|
+
|
281
|
+
it "does not error on non existant fields" do
|
282
|
+
smiths.reload.members.should be_nil
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
describe "#pull_all" do
|
287
|
+
|
288
|
+
let!(:depeche_mode) do
|
289
|
+
Band.create(members: [ "Dave", "Alan", "Fletch" ])
|
290
|
+
end
|
291
|
+
|
292
|
+
let!(:smiths) do
|
293
|
+
Band.create
|
294
|
+
end
|
295
|
+
|
296
|
+
let(:criteria) do
|
297
|
+
Band.all
|
298
|
+
end
|
299
|
+
|
300
|
+
let(:context) do
|
301
|
+
Mongoid::Contextual::Mongo.new(criteria)
|
302
|
+
end
|
303
|
+
|
304
|
+
before do
|
305
|
+
context.pull_all(:members, [ "Alan", "Dave" ])
|
306
|
+
end
|
307
|
+
|
308
|
+
it "pulls when the values are found" do
|
309
|
+
depeche_mode.reload.members.should eq([ "Fletch" ])
|
310
|
+
end
|
311
|
+
|
312
|
+
it "does not error on non existant fields" do
|
313
|
+
smiths.reload.members.should be_nil
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
describe "#push" do
|
318
|
+
|
319
|
+
let!(:depeche_mode) do
|
320
|
+
Band.create(members: [ "Dave" ])
|
321
|
+
end
|
322
|
+
|
323
|
+
let!(:smiths) do
|
324
|
+
Band.create
|
325
|
+
end
|
326
|
+
|
327
|
+
let(:criteria) do
|
328
|
+
Band.all
|
329
|
+
end
|
330
|
+
|
331
|
+
let(:context) do
|
332
|
+
Mongoid::Contextual::Mongo.new(criteria)
|
333
|
+
end
|
334
|
+
|
335
|
+
before do
|
336
|
+
context.push(:members, "Alan")
|
337
|
+
end
|
338
|
+
|
339
|
+
it "pushes the value to existing arrays" do
|
340
|
+
depeche_mode.reload.members.should eq([ "Dave", "Alan" ])
|
341
|
+
end
|
342
|
+
|
343
|
+
it "pushes to non existant fields" do
|
344
|
+
smiths.reload.members.should eq([ "Alan" ])
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
describe "#push_all" do
|
349
|
+
|
350
|
+
let!(:depeche_mode) do
|
351
|
+
Band.create(members: [ "Dave" ])
|
352
|
+
end
|
353
|
+
|
354
|
+
let!(:smiths) do
|
355
|
+
Band.create
|
356
|
+
end
|
357
|
+
|
358
|
+
let(:criteria) do
|
359
|
+
Band.all
|
360
|
+
end
|
361
|
+
|
362
|
+
let(:context) do
|
363
|
+
Mongoid::Contextual::Mongo.new(criteria)
|
364
|
+
end
|
365
|
+
|
366
|
+
before do
|
367
|
+
context.push_all(:members, [ "Alan", "Fletch" ])
|
368
|
+
end
|
369
|
+
|
370
|
+
it "pushes the values to existing arrays" do
|
371
|
+
depeche_mode.reload.members.should eq([ "Dave", "Alan", "Fletch" ])
|
372
|
+
end
|
373
|
+
|
374
|
+
it "pushes to non existant fields" do
|
375
|
+
smiths.reload.members.should eq([ "Alan", "Fletch" ])
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
describe "#rename" do
|
380
|
+
|
381
|
+
let!(:depeche_mode) do
|
382
|
+
Band.create(members: [ "Dave" ])
|
383
|
+
end
|
384
|
+
|
385
|
+
let!(:smiths) do
|
386
|
+
Band.create
|
387
|
+
end
|
388
|
+
|
389
|
+
let(:criteria) do
|
390
|
+
Band.all
|
391
|
+
end
|
392
|
+
|
393
|
+
let(:context) do
|
394
|
+
Mongoid::Contextual::Mongo.new(criteria)
|
395
|
+
end
|
396
|
+
|
397
|
+
before do
|
398
|
+
context.rename(:members, :artists)
|
399
|
+
end
|
400
|
+
|
401
|
+
it "renames existing fields" do
|
402
|
+
depeche_mode.reload.artists.should eq([ "Dave" ])
|
403
|
+
end
|
404
|
+
|
405
|
+
it "does not rename non existant fields" do
|
406
|
+
smiths.reload.should_not respond_to(:artists)
|
407
|
+
end
|
408
|
+
end
|
409
|
+
|
410
|
+
describe "#set" do
|
411
|
+
|
412
|
+
let!(:depeche_mode) do
|
413
|
+
Band.create(name: "Depeche Mode")
|
414
|
+
end
|
415
|
+
|
416
|
+
let!(:smiths) do
|
417
|
+
Band.create
|
418
|
+
end
|
419
|
+
|
420
|
+
let(:criteria) do
|
421
|
+
Band.all
|
422
|
+
end
|
423
|
+
|
424
|
+
let(:context) do
|
425
|
+
Mongoid::Contextual::Mongo.new(criteria)
|
426
|
+
end
|
427
|
+
|
428
|
+
before do
|
429
|
+
context.set(:name, "Recoil")
|
430
|
+
end
|
431
|
+
|
432
|
+
it "sets existing fields" do
|
433
|
+
depeche_mode.reload.name.should eq("Recoil")
|
434
|
+
end
|
435
|
+
|
436
|
+
it "sets non existant fields" do
|
437
|
+
smiths.reload.name.should eq("Recoil")
|
438
|
+
end
|
439
|
+
end
|
440
|
+
|
441
|
+
describe "#unset" do
|
442
|
+
|
443
|
+
context "when unsetting a single field" do
|
444
|
+
|
445
|
+
let!(:depeche_mode) do
|
446
|
+
Band.create(name: "Depeche Mode", years: 10)
|
447
|
+
end
|
448
|
+
|
449
|
+
let!(:new_order) do
|
450
|
+
Band.create(name: "New Order", years: 10)
|
451
|
+
end
|
452
|
+
|
453
|
+
let(:criteria) do
|
454
|
+
Band.all
|
455
|
+
end
|
456
|
+
|
457
|
+
let(:context) do
|
458
|
+
Mongoid::Contextual::Mongo.new(criteria)
|
459
|
+
end
|
460
|
+
|
461
|
+
context "when the field is not aliased" do
|
462
|
+
|
463
|
+
before do
|
464
|
+
context.unset(:name)
|
465
|
+
end
|
466
|
+
|
467
|
+
it "unsets the first existing field" do
|
468
|
+
depeche_mode.reload.name.should be_nil
|
469
|
+
end
|
470
|
+
|
471
|
+
it "unsets the last existing field" do
|
472
|
+
new_order.reload.name.should be_nil
|
473
|
+
end
|
474
|
+
end
|
475
|
+
|
476
|
+
context "when the field is aliased" do
|
477
|
+
|
478
|
+
before do
|
479
|
+
context.unset(:years)
|
480
|
+
end
|
481
|
+
|
482
|
+
it "unsets the first existing field" do
|
483
|
+
depeche_mode.reload.years.should be_nil
|
484
|
+
end
|
485
|
+
|
486
|
+
it "unsets the last existing field" do
|
487
|
+
new_order.reload.years.should be_nil
|
488
|
+
end
|
489
|
+
end
|
490
|
+
end
|
491
|
+
|
492
|
+
context "when unsetting multiple fields" do
|
493
|
+
|
494
|
+
let!(:new_order) do
|
495
|
+
Band.create(name: "New Order", genres: [ "electro", "dub" ], years: 10)
|
496
|
+
end
|
497
|
+
|
498
|
+
let(:criteria) do
|
499
|
+
Band.all
|
500
|
+
end
|
501
|
+
|
502
|
+
let(:context) do
|
503
|
+
Mongoid::Contextual::Mongo.new(criteria)
|
504
|
+
end
|
505
|
+
|
506
|
+
context "when the field is not aliased" do
|
507
|
+
|
508
|
+
before do
|
509
|
+
context.unset(:name, :genres)
|
510
|
+
end
|
511
|
+
|
512
|
+
it "unsets name field" do
|
513
|
+
new_order.reload.name.should be_nil
|
514
|
+
end
|
515
|
+
|
516
|
+
it "unsets genres field" do
|
517
|
+
new_order.reload.genres.should be_nil
|
518
|
+
end
|
519
|
+
end
|
520
|
+
|
521
|
+
context "when the field is aliased" do
|
522
|
+
|
523
|
+
before do
|
524
|
+
context.unset(:name, :years)
|
525
|
+
end
|
526
|
+
|
527
|
+
it "unsets the unaliased field" do
|
528
|
+
new_order.reload.name.should be_nil
|
529
|
+
end
|
530
|
+
|
531
|
+
it "unsets the aliased field" do
|
532
|
+
new_order.reload.years.should be_nil
|
533
|
+
end
|
534
|
+
end
|
535
|
+
end
|
536
|
+
end
|
537
|
+
end
|
538
|
+
|
539
|
+
# Mongoid 4
|
540
|
+
describe Mongoid::Contextual::Atomic do
|
541
|
+
|
542
|
+
describe "#add_to_set" do
|
543
|
+
|
544
|
+
let!(:depeche_mode) do
|
545
|
+
Band.create(members: [ "Dave" ])
|
546
|
+
end
|
547
|
+
|
548
|
+
let!(:new_order) do
|
549
|
+
Band.create(members: [ "Peter" ])
|
550
|
+
end
|
551
|
+
|
552
|
+
let!(:smiths) do
|
553
|
+
Band.create
|
554
|
+
end
|
555
|
+
|
556
|
+
context "when the criteria has no sorting" do
|
557
|
+
|
558
|
+
let(:criteria) do
|
559
|
+
Band.all
|
560
|
+
end
|
561
|
+
|
562
|
+
let(:context) do
|
563
|
+
Mongoid::Contextual::Mongo.new(criteria)
|
564
|
+
end
|
565
|
+
|
566
|
+
before do
|
567
|
+
context.add_to_set(members: "Dave")
|
568
|
+
end
|
569
|
+
|
570
|
+
it "does not add duplicates" do
|
571
|
+
expect(depeche_mode.reload.members).to eq([ "Dave" ])
|
572
|
+
end
|
573
|
+
|
574
|
+
it "adds unique values" do
|
575
|
+
expect(new_order.reload.members).to eq([ "Peter", "Dave" ])
|
576
|
+
end
|
577
|
+
|
578
|
+
it "adds to non initialized fields" do
|
579
|
+
expect(smiths.reload.members).to eq([ "Dave" ])
|
580
|
+
end
|
581
|
+
end
|
582
|
+
|
583
|
+
context "when the criteria has sorting" do
|
584
|
+
|
585
|
+
let(:criteria) do
|
586
|
+
Band.asc(:name)
|
587
|
+
end
|
588
|
+
|
589
|
+
let(:context) do
|
590
|
+
Mongoid::Contextual::Mongo.new(criteria)
|
591
|
+
end
|
592
|
+
|
593
|
+
before do
|
594
|
+
context.add_to_set(members: "Dave", genres: "Electro")
|
595
|
+
end
|
596
|
+
|
597
|
+
it "does not add duplicates" do
|
598
|
+
expect(depeche_mode.reload.members).to eq([ "Dave" ])
|
599
|
+
end
|
600
|
+
|
601
|
+
it "adds multiple operations" do
|
602
|
+
expect(depeche_mode.reload.genres).to eq([ "Electro" ])
|
603
|
+
end
|
604
|
+
|
605
|
+
it "adds unique values" do
|
606
|
+
expect(new_order.reload.members).to eq([ "Peter", "Dave" ])
|
607
|
+
end
|
608
|
+
|
609
|
+
it "adds to non initialized fields" do
|
610
|
+
expect(smiths.reload.members).to eq([ "Dave" ])
|
611
|
+
end
|
612
|
+
end
|
613
|
+
end
|
614
|
+
|
615
|
+
describe "#bit" do
|
616
|
+
|
617
|
+
let!(:depeche_mode) do
|
618
|
+
Band.create(likes: 60)
|
619
|
+
end
|
620
|
+
|
621
|
+
let!(:smiths) do
|
622
|
+
Band.create
|
623
|
+
end
|
624
|
+
|
625
|
+
let(:criteria) do
|
626
|
+
Band.all
|
627
|
+
end
|
628
|
+
|
629
|
+
let(:context) do
|
630
|
+
Mongoid::Contextual::Mongo.new(criteria)
|
631
|
+
end
|
632
|
+
|
633
|
+
context "when performing a bitwise and" do
|
634
|
+
|
635
|
+
before do
|
636
|
+
context.bit(likes: { and: 13 })
|
637
|
+
end
|
638
|
+
|
639
|
+
it "performs the bitwise operation on initialized fields" do
|
640
|
+
expect(depeche_mode.reload.likes).to eq(12)
|
641
|
+
end
|
642
|
+
|
643
|
+
it "does not error on non initialized fields" do
|
644
|
+
expect(smiths.reload.likes).to eq(0)
|
645
|
+
end
|
646
|
+
end
|
647
|
+
|
648
|
+
context "when performing a bitwise or" do
|
649
|
+
|
650
|
+
before do
|
651
|
+
context.bit(likes: { or: 13 })
|
652
|
+
end
|
653
|
+
|
654
|
+
it "performs the bitwise operation on initialized fields" do
|
655
|
+
expect(depeche_mode.reload.likes).to eq(61)
|
656
|
+
end
|
657
|
+
|
658
|
+
it "does not error on non initialized fields" do
|
659
|
+
expect(smiths.reload.likes).to eq(13)
|
660
|
+
end
|
661
|
+
end
|
662
|
+
|
663
|
+
context "when chaining bitwise operations" do
|
664
|
+
|
665
|
+
before do
|
666
|
+
context.bit(likes: { and: 13, or: 10 })
|
667
|
+
end
|
668
|
+
|
669
|
+
it "performs the bitwise operation on initialized fields" do
|
670
|
+
expect(depeche_mode.reload.likes).to eq(14)
|
671
|
+
end
|
672
|
+
|
673
|
+
it "does not error on non initialized fields" do
|
674
|
+
expect(smiths.reload.likes).to eq(10)
|
675
|
+
end
|
676
|
+
end
|
677
|
+
end
|
678
|
+
|
679
|
+
describe "#inc" do
|
680
|
+
|
681
|
+
let!(:depeche_mode) do
|
682
|
+
Band.create(likes: 60)
|
683
|
+
end
|
684
|
+
|
685
|
+
let!(:smiths) do
|
686
|
+
Band.create
|
687
|
+
end
|
688
|
+
|
689
|
+
let!(:beatles) do
|
690
|
+
Band.create(years: 2)
|
691
|
+
end
|
692
|
+
|
693
|
+
let(:criteria) do
|
694
|
+
Band.all
|
695
|
+
end
|
696
|
+
|
697
|
+
let(:context) do
|
698
|
+
Mongoid::Contextual::Mongo.new(criteria)
|
699
|
+
end
|
700
|
+
|
701
|
+
before do
|
702
|
+
context.inc(likes: 10)
|
703
|
+
end
|
704
|
+
|
705
|
+
context "when the field exists" do
|
706
|
+
|
707
|
+
it "incs the value" do
|
708
|
+
expect(depeche_mode.reload.likes).to eq(70)
|
709
|
+
end
|
710
|
+
end
|
711
|
+
|
712
|
+
context "when the field does not exist" do
|
713
|
+
|
714
|
+
it "does not error on the inc" do
|
715
|
+
expect(smiths.likes).to be_nil
|
716
|
+
end
|
717
|
+
end
|
718
|
+
|
719
|
+
context "when using the alias" do
|
720
|
+
|
721
|
+
before do
|
722
|
+
context.inc(years: 1)
|
723
|
+
end
|
724
|
+
|
725
|
+
it "incs the value and read from alias" do
|
726
|
+
expect(beatles.reload.years).to eq(3)
|
727
|
+
end
|
728
|
+
|
729
|
+
it "incs the value and read from field" do
|
730
|
+
expect(beatles.reload.y).to eq(3)
|
731
|
+
end
|
732
|
+
end
|
733
|
+
end
|
734
|
+
|
735
|
+
describe "#pop" do
|
736
|
+
|
737
|
+
let!(:depeche_mode) do
|
738
|
+
Band.create(members: [ "Dave", "Martin" ])
|
739
|
+
end
|
740
|
+
|
741
|
+
let!(:smiths) do
|
742
|
+
Band.create
|
743
|
+
end
|
744
|
+
|
745
|
+
let(:criteria) do
|
746
|
+
Band.all
|
747
|
+
end
|
748
|
+
|
749
|
+
let(:context) do
|
750
|
+
Mongoid::Contextual::Mongo.new(criteria)
|
751
|
+
end
|
752
|
+
|
753
|
+
context "when popping from the front" do
|
754
|
+
|
755
|
+
before do
|
756
|
+
context.pop(members: -1)
|
757
|
+
end
|
758
|
+
|
759
|
+
it "pops the first element off the array" do
|
760
|
+
expect(depeche_mode.reload.members).to eq([ "Martin" ])
|
761
|
+
end
|
762
|
+
|
763
|
+
it "does not error on uninitialized fields" do
|
764
|
+
expect(smiths.reload.members).to be_nil
|
765
|
+
end
|
766
|
+
end
|
767
|
+
|
768
|
+
context "when popping from the rear" do
|
769
|
+
|
770
|
+
before do
|
771
|
+
context.pop(members: 1)
|
772
|
+
end
|
773
|
+
|
774
|
+
it "pops the last element off the array" do
|
775
|
+
expect(depeche_mode.reload.members).to eq([ "Dave" ])
|
776
|
+
end
|
777
|
+
|
778
|
+
it "does not error on uninitialized fields" do
|
779
|
+
expect(smiths.reload.members).to be_nil
|
780
|
+
end
|
781
|
+
end
|
782
|
+
end
|
783
|
+
|
784
|
+
describe "#pull" do
|
785
|
+
|
786
|
+
let!(:depeche_mode) do
|
787
|
+
Band.create(members: [ "Dave", "Alan" ])
|
788
|
+
end
|
789
|
+
|
790
|
+
let!(:smiths) do
|
791
|
+
Band.create
|
792
|
+
end
|
793
|
+
|
794
|
+
let(:criteria) do
|
795
|
+
Band.all
|
796
|
+
end
|
797
|
+
|
798
|
+
let(:context) do
|
799
|
+
Mongoid::Contextual::Mongo.new(criteria)
|
800
|
+
end
|
801
|
+
|
802
|
+
before do
|
803
|
+
context.pull(members: "Alan")
|
804
|
+
end
|
805
|
+
|
806
|
+
it "pulls when the value is found" do
|
807
|
+
expect(depeche_mode.reload.members).to eq([ "Dave" ])
|
808
|
+
end
|
809
|
+
|
810
|
+
it "does not error on non existant fields" do
|
811
|
+
expect(smiths.reload.members).to be_nil
|
812
|
+
end
|
813
|
+
end
|
814
|
+
|
815
|
+
describe "#pull_all" do
|
816
|
+
|
817
|
+
let!(:depeche_mode) do
|
818
|
+
Band.create(members: [ "Dave", "Alan", "Fletch" ])
|
819
|
+
end
|
820
|
+
|
821
|
+
let!(:smiths) do
|
822
|
+
Band.create
|
823
|
+
end
|
824
|
+
|
825
|
+
let(:criteria) do
|
826
|
+
Band.all
|
827
|
+
end
|
828
|
+
|
829
|
+
let(:context) do
|
830
|
+
Mongoid::Contextual::Mongo.new(criteria)
|
831
|
+
end
|
832
|
+
|
833
|
+
before do
|
834
|
+
context.pull_all(members: [ "Alan", "Dave" ])
|
835
|
+
end
|
836
|
+
|
837
|
+
it "pulls when the values are found" do
|
838
|
+
expect(depeche_mode.reload.members).to eq([ "Fletch" ])
|
839
|
+
end
|
840
|
+
|
841
|
+
it "does not error on non existant fields" do
|
842
|
+
expect(smiths.reload.members).to be_nil
|
843
|
+
end
|
844
|
+
end
|
845
|
+
|
846
|
+
describe "#push" do
|
847
|
+
|
848
|
+
let!(:depeche_mode) do
|
849
|
+
Band.create(members: [ "Dave" ])
|
850
|
+
end
|
851
|
+
|
852
|
+
let!(:smiths) do
|
853
|
+
Band.create
|
854
|
+
end
|
855
|
+
|
856
|
+
let(:criteria) do
|
857
|
+
Band.all
|
858
|
+
end
|
859
|
+
|
860
|
+
let(:context) do
|
861
|
+
Mongoid::Contextual::Mongo.new(criteria)
|
862
|
+
end
|
863
|
+
|
864
|
+
before do
|
865
|
+
context.push(members: "Alan")
|
866
|
+
end
|
867
|
+
|
868
|
+
it "pushes the value to existing arrays" do
|
869
|
+
expect(depeche_mode.reload.members).to eq([ "Dave", "Alan" ])
|
870
|
+
end
|
871
|
+
|
872
|
+
it "pushes to non existant fields" do
|
873
|
+
expect(smiths.reload.members).to eq([ "Alan" ])
|
874
|
+
end
|
875
|
+
end
|
876
|
+
|
877
|
+
describe "#push_all" do
|
878
|
+
|
879
|
+
let!(:depeche_mode) do
|
880
|
+
Band.create(members: [ "Dave" ])
|
881
|
+
end
|
882
|
+
|
883
|
+
let!(:smiths) do
|
884
|
+
Band.create
|
885
|
+
end
|
886
|
+
|
887
|
+
let(:criteria) do
|
888
|
+
Band.all
|
889
|
+
end
|
890
|
+
|
891
|
+
let(:context) do
|
892
|
+
Mongoid::Contextual::Mongo.new(criteria)
|
893
|
+
end
|
894
|
+
|
895
|
+
before do
|
896
|
+
context.push_all(members: [ "Alan", "Fletch" ])
|
897
|
+
end
|
898
|
+
|
899
|
+
it "pushes the values to existing arrays" do
|
900
|
+
expect(depeche_mode.reload.members).to eq([ "Dave", "Alan", "Fletch" ])
|
901
|
+
end
|
902
|
+
|
903
|
+
it "pushes to non existant fields" do
|
904
|
+
expect(smiths.reload.members).to eq([ "Alan", "Fletch" ])
|
905
|
+
end
|
906
|
+
end
|
907
|
+
|
908
|
+
describe "#rename" do
|
909
|
+
|
910
|
+
let!(:depeche_mode) do
|
911
|
+
Band.create(members: [ "Dave" ])
|
912
|
+
end
|
913
|
+
|
914
|
+
let!(:smiths) do
|
915
|
+
Band.create
|
916
|
+
end
|
917
|
+
|
918
|
+
let(:criteria) do
|
919
|
+
Band.all
|
920
|
+
end
|
921
|
+
|
922
|
+
let(:context) do
|
923
|
+
Mongoid::Contextual::Mongo.new(criteria)
|
924
|
+
end
|
925
|
+
|
926
|
+
before do
|
927
|
+
context.rename(members: :artists)
|
928
|
+
end
|
929
|
+
|
930
|
+
it "renames existing fields" do
|
931
|
+
expect(depeche_mode.reload.artists).to eq([ "Dave" ])
|
932
|
+
end
|
933
|
+
|
934
|
+
it "does not rename non existant fields" do
|
935
|
+
expect(smiths.reload).to_not respond_to(:artists)
|
936
|
+
end
|
937
|
+
end
|
938
|
+
|
939
|
+
describe "#set" do
|
940
|
+
|
941
|
+
let!(:depeche_mode) do
|
942
|
+
Band.create(name: "Depeche Mode")
|
943
|
+
end
|
944
|
+
|
945
|
+
let!(:smiths) do
|
946
|
+
Band.create
|
947
|
+
end
|
948
|
+
|
949
|
+
let(:criteria) do
|
950
|
+
Band.all
|
951
|
+
end
|
952
|
+
|
953
|
+
let(:context) do
|
954
|
+
Mongoid::Contextual::Mongo.new(criteria)
|
955
|
+
end
|
956
|
+
|
957
|
+
before do
|
958
|
+
context.set(name: "Recoil")
|
959
|
+
end
|
960
|
+
|
961
|
+
it "sets existing fields" do
|
962
|
+
expect(depeche_mode.reload.name).to eq("Recoil")
|
963
|
+
end
|
964
|
+
|
965
|
+
it "sets non existant fields" do
|
966
|
+
expect(smiths.reload.name).to eq("Recoil")
|
967
|
+
end
|
968
|
+
end
|
969
|
+
|
970
|
+
describe "#unset" do
|
971
|
+
|
972
|
+
context "when unsetting a single field" do
|
973
|
+
|
974
|
+
let!(:depeche_mode) do
|
975
|
+
Band.create(name: "Depeche Mode", years: 10)
|
976
|
+
end
|
977
|
+
|
978
|
+
let!(:new_order) do
|
979
|
+
Band.create(name: "New Order", years: 10)
|
980
|
+
end
|
981
|
+
|
982
|
+
let(:criteria) do
|
983
|
+
Band.all
|
984
|
+
end
|
985
|
+
|
986
|
+
let(:context) do
|
987
|
+
Mongoid::Contextual::Mongo.new(criteria)
|
988
|
+
end
|
989
|
+
|
990
|
+
context "when the field is not aliased" do
|
991
|
+
|
992
|
+
before do
|
993
|
+
context.unset(:name)
|
994
|
+
end
|
995
|
+
|
996
|
+
it "unsets the first existing field" do
|
997
|
+
expect(depeche_mode.reload.name).to be_nil
|
998
|
+
end
|
999
|
+
|
1000
|
+
it "unsets the last existing field" do
|
1001
|
+
expect(new_order.reload.name).to be_nil
|
1002
|
+
end
|
1003
|
+
end
|
1004
|
+
|
1005
|
+
context "when the field is aliased" do
|
1006
|
+
|
1007
|
+
before do
|
1008
|
+
context.unset(:years)
|
1009
|
+
end
|
1010
|
+
|
1011
|
+
it "unsets the first existing field" do
|
1012
|
+
expect(depeche_mode.reload.years).to be_nil
|
1013
|
+
end
|
1014
|
+
|
1015
|
+
it "unsets the last existing field" do
|
1016
|
+
expect(new_order.reload.years).to be_nil
|
1017
|
+
end
|
1018
|
+
end
|
1019
|
+
end
|
1020
|
+
|
1021
|
+
context "when unsetting multiple fields" do
|
1022
|
+
|
1023
|
+
let!(:new_order) do
|
1024
|
+
Band.create(name: "New Order", genres: [ "electro", "dub" ], years: 10)
|
1025
|
+
end
|
1026
|
+
|
1027
|
+
let(:criteria) do
|
1028
|
+
Band.all
|
1029
|
+
end
|
1030
|
+
|
1031
|
+
let(:context) do
|
1032
|
+
Mongoid::Contextual::Mongo.new(criteria)
|
1033
|
+
end
|
1034
|
+
|
1035
|
+
context "when the field is not aliased" do
|
1036
|
+
|
1037
|
+
before do
|
1038
|
+
context.unset(:name, :genres)
|
1039
|
+
end
|
1040
|
+
|
1041
|
+
it "unsets name field" do
|
1042
|
+
expect(new_order.reload.name).to be_nil
|
1043
|
+
end
|
1044
|
+
|
1045
|
+
it "unsets genres field" do
|
1046
|
+
expect(new_order.reload.genres).to be_nil
|
1047
|
+
end
|
1048
|
+
end
|
1049
|
+
|
1050
|
+
context "when the field is aliased" do
|
1051
|
+
|
1052
|
+
before do
|
1053
|
+
context.unset(:name, :years)
|
1054
|
+
end
|
1055
|
+
|
1056
|
+
it "unsets the unaliased field" do
|
1057
|
+
expect(new_order.reload.name).to be_nil
|
1058
|
+
end
|
1059
|
+
|
1060
|
+
it "unsets the aliased field" do
|
1061
|
+
expect(new_order.reload.years).to be_nil
|
1062
|
+
end
|
1063
|
+
end
|
1064
|
+
end
|
1065
|
+
end
|
1066
|
+
end
|
1067
|
+
end
|