plucky 0.5.2 → 0.6.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.
- data/.bundle/config +4 -0
- data/.gitignore +3 -1
- data/.travis.yml +2 -2
- data/Gemfile +13 -3
- data/Guardfile +13 -0
- data/README.md +1 -1
- data/Rakefile +3 -17
- data/examples/query.rb +1 -1
- data/lib/plucky.rb +13 -0
- data/lib/plucky/criteria_hash.rb +85 -56
- data/lib/plucky/normalizers/criteria_hash_key.rb +17 -0
- data/lib/plucky/normalizers/criteria_hash_value.rb +83 -0
- data/lib/plucky/normalizers/fields_value.rb +26 -0
- data/lib/plucky/normalizers/integer.rb +19 -0
- data/lib/plucky/normalizers/options_hash_key.rb +23 -0
- data/lib/plucky/normalizers/options_hash_value.rb +85 -0
- data/lib/plucky/normalizers/sort_value.rb +55 -0
- data/lib/plucky/options_hash.rb +56 -85
- data/lib/plucky/pagination/decorator.rb +3 -2
- data/lib/plucky/pagination/paginator.rb +15 -6
- data/lib/plucky/query.rb +93 -51
- data/lib/plucky/version.rb +1 -1
- data/script/criteria_hash.rb +21 -0
- data/{test → spec}/helper.rb +12 -8
- data/spec/plucky/criteria_hash_spec.rb +166 -0
- data/spec/plucky/normalizers/criteria_hash_key_spec.rb +37 -0
- data/spec/plucky/normalizers/criteria_hash_value_spec.rb +193 -0
- data/spec/plucky/normalizers/fields_value_spec.rb +45 -0
- data/spec/plucky/normalizers/integer_spec.rb +24 -0
- data/spec/plucky/normalizers/options_hash_key_spec.rb +23 -0
- data/spec/plucky/normalizers/options_hash_value_spec.rb +99 -0
- data/spec/plucky/normalizers/sort_value_spec.rb +94 -0
- data/spec/plucky/options_hash_spec.rb +64 -0
- data/{test/plucky/pagination/test_decorator.rb → spec/plucky/pagination/decorator_spec.rb} +8 -10
- data/spec/plucky/pagination/paginator_spec.rb +118 -0
- data/spec/plucky/query_spec.rb +839 -0
- data/spec/plucky_spec.rb +68 -0
- data/{test/test_symbol_operator.rb → spec/symbol_operator_spec.rb} +14 -16
- data/spec/symbol_spec.rb +9 -0
- metadata +58 -23
- data/test/plucky/pagination/test_paginator.rb +0 -120
- data/test/plucky/test_criteria_hash.rb +0 -359
- data/test/plucky/test_options_hash.rb +0 -302
- data/test/plucky/test_query.rb +0 -843
- data/test/test_plucky.rb +0 -48
- data/test/test_symbol.rb +0 -11
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Plucky::Normalizers::CriteriaHashKey do
|
4
|
+
subject {
|
5
|
+
described_class.new
|
6
|
+
}
|
7
|
+
|
8
|
+
context "with a string" do
|
9
|
+
it "returns symbol" do
|
10
|
+
subject.call('foo').should eq(:foo)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context "with a symbol" do
|
15
|
+
it "returns symbol" do
|
16
|
+
subject.call(:foo).should eq(:foo)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context "with :id" do
|
21
|
+
it "returns :_id" do
|
22
|
+
subject.call(:id).should eq(:_id)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it "returns key if something weird" do
|
27
|
+
subject.call(['crazytown']).should eq(['crazytown'])
|
28
|
+
end
|
29
|
+
|
30
|
+
SymbolOperators.each do |operator|
|
31
|
+
context "with #{operator} symbol operator" do
|
32
|
+
it "returns field" do
|
33
|
+
subject.call(:age.send(operator)).should eq(:age)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,193 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Plucky::Normalizers::CriteriaHashValue do
|
4
|
+
let(:criteria_hash) { Plucky::CriteriaHash.new }
|
5
|
+
|
6
|
+
subject {
|
7
|
+
described_class.new(criteria_hash)
|
8
|
+
}
|
9
|
+
|
10
|
+
context "with a string" do
|
11
|
+
it "leaves string values for string keys alone" do
|
12
|
+
subject.call(:foo, :foo, 'bar').should eq('bar')
|
13
|
+
end
|
14
|
+
|
15
|
+
context "that is actually an object id" do
|
16
|
+
it "converts string values to object ids for object id keys" do
|
17
|
+
criteria_hash.object_ids = [:_id]
|
18
|
+
id = BSON::ObjectId.new
|
19
|
+
subject.call(:_id, :_id, id.to_s).should eq(id)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "with a time" do
|
25
|
+
it "converts times to utc" do
|
26
|
+
time = Time.now
|
27
|
+
actual = time
|
28
|
+
expected = time.utc
|
29
|
+
result = subject.call(:foo, :foo, actual)
|
30
|
+
result.should be_utc
|
31
|
+
result.should eq(expected)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "leaves utc times alone" do
|
35
|
+
time = Time.now
|
36
|
+
actual = time.utc
|
37
|
+
expected = time.utc
|
38
|
+
result = subject.call(:foo, :foo, actual)
|
39
|
+
result.should be_utc
|
40
|
+
result.should eq(expected)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "with an array" do
|
45
|
+
it "defaults to $in" do
|
46
|
+
actual = [1,2,3]
|
47
|
+
expected = {:$in => [1,2,3]}
|
48
|
+
subject.call(:foo, :foo, actual).should eq(expected)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "does not double up $in" do
|
52
|
+
actual = [1, 2, 3]
|
53
|
+
expected = [1, 2, 3]
|
54
|
+
subject.call(:$in, :$in, actual).should eq(expected)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "uses existing modifier if present" do
|
58
|
+
actual = {'$all' => [1,2,3]}
|
59
|
+
expected = {'$all' => [1,2,3]}
|
60
|
+
subject.call(:foo, :foo, actual).should eq(expected)
|
61
|
+
|
62
|
+
actual = {'$any' => [1,2,3]}
|
63
|
+
expected = {'$any' => [1,2,3]}
|
64
|
+
subject.call(:foo, :foo, actual).should eq(expected)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "does not turn value to $in with $or key" do
|
68
|
+
actual = [{:numbers => 1}, {:numbers => 2}]
|
69
|
+
expected = [{:numbers => 1}, {:numbers => 2}]
|
70
|
+
subject.call(:$or, :$or, actual).should eq(expected)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "does not turn value to $in with $and key" do
|
74
|
+
actual = [{:numbers => 1}, {:numbers => 2}]
|
75
|
+
expected = [{:numbers => 1}, {:numbers => 2}]
|
76
|
+
subject.call(:$and, :$and, actual).should eq(expected)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "does not turn value to $in with $nor key" do
|
80
|
+
actual = [{:numbers => 1}, {:numbers => 2}]
|
81
|
+
expected = [{:numbers => 1}, {:numbers => 2}]
|
82
|
+
subject.call(:$nor, :$nor, actual).should eq(expected)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "defaults to $in even with ObjectId keys" do
|
86
|
+
actual = [1,2,3]
|
87
|
+
expected = {:$in => [1,2,3]}
|
88
|
+
criteria_hash.object_ids = [:mistake_id]
|
89
|
+
subject.call(:mistake_id, :mistake_id, actual).should eq(expected)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context "with a set" do
|
94
|
+
it "defaults to $in and convert to array" do
|
95
|
+
actual = [1,2,3].to_set
|
96
|
+
expected = {:$in => [1,2,3]}
|
97
|
+
subject.call(:numbers, :numbers, actual).should eq(expected)
|
98
|
+
end
|
99
|
+
|
100
|
+
it "uses existing modifier if present and convert to array" do
|
101
|
+
actual = {'$all' => [1,2,3].to_set}
|
102
|
+
expected = {'$all' => [1,2,3]}
|
103
|
+
subject.call(:foo, :foo, actual).should eq(expected)
|
104
|
+
|
105
|
+
actual = {'$any' => [1,2,3].to_set}
|
106
|
+
expected = {'$any' => [1,2,3]}
|
107
|
+
subject.call(:foo, :foo, actual).should eq(expected)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context "with string object ids for string keys" do
|
112
|
+
let(:object_id) { BSON::ObjectId.new }
|
113
|
+
|
114
|
+
it "leaves string ids as strings" do
|
115
|
+
subject.call(:_id, :_id, object_id.to_s).should eq(object_id.to_s)
|
116
|
+
subject.call(:room_id, :room_id, object_id.to_s).should eq(object_id.to_s)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context "with string object ids for object id keys" do
|
121
|
+
let(:object_id) { BSON::ObjectId.new }
|
122
|
+
|
123
|
+
before do
|
124
|
+
criteria_hash.object_ids = [:_id, :room_id]
|
125
|
+
end
|
126
|
+
|
127
|
+
it "converts strings to object ids" do
|
128
|
+
subject.call(:_id, :_id, object_id.to_s).should eq(object_id)
|
129
|
+
subject.call(:room_id, :room_id, object_id.to_s).should eq(object_id)
|
130
|
+
end
|
131
|
+
|
132
|
+
context "nested with modifier" do
|
133
|
+
let(:oid1) { BSON::ObjectId.new }
|
134
|
+
let(:oid2) { BSON::ObjectId.new }
|
135
|
+
let(:oids) { [oid1.to_s, oid2.to_s] }
|
136
|
+
|
137
|
+
it "converts strings to object ids" do
|
138
|
+
actual = {:$in => oids}
|
139
|
+
expected = {:$in => [oid1, oid2]}
|
140
|
+
subject.call(:_id, :_id, actual).should eq(expected)
|
141
|
+
end
|
142
|
+
|
143
|
+
it "does not modify original array of string ids" do
|
144
|
+
subject.call(:_id, :_id, {:$in => oids})
|
145
|
+
oids.should == [oid1.to_s, oid2.to_s]
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
context "nested clauses" do
|
151
|
+
it "knows constant array of operators that take nested queries" do
|
152
|
+
described_class::NestingOperators.should == [:$or, :$and, :$nor]
|
153
|
+
end
|
154
|
+
|
155
|
+
described_class::NestingOperators.each do |operator|
|
156
|
+
context "with #{operator}" do
|
157
|
+
it "works with symbol operators" do
|
158
|
+
nested1 = {:age.gt => 12, :age.lt => 20}
|
159
|
+
translated1 = {:age => {:$gt => 12, :$lt => 20 }}
|
160
|
+
nested2 = {:type.nin => ['friend', 'enemy']}
|
161
|
+
translated2 = {:type => {:$nin => ['friend', 'enemy']}}
|
162
|
+
value = [nested1, nested2]
|
163
|
+
expected = [translated1, translated2]
|
164
|
+
|
165
|
+
subject.call(operator, operator, value).should eq(expected)
|
166
|
+
end
|
167
|
+
|
168
|
+
it "honors criteria hash options" do
|
169
|
+
nested = [{:post_id => '4f5ead6378fca23a13000001'}]
|
170
|
+
translated = [{:post_id => BSON::ObjectId.from_string('4f5ead6378fca23a13000001')}]
|
171
|
+
given = {operator.to_s => [nested]}
|
172
|
+
|
173
|
+
criteria_hash.object_ids = [:post_id]
|
174
|
+
subject.call(operator, operator, nested).should eq(translated)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
context "doubly nested" do
|
180
|
+
it "works with symbol operators" do
|
181
|
+
nested1 = {:age.gt => 12, :age.lt => 20}
|
182
|
+
translated1 = {:age => {:$gt => 12, :$lt => 20}}
|
183
|
+
nested2 = {:type.nin => ['friend', 'enemy']}
|
184
|
+
translated2 = {:type => {:$nin => ['friend', 'enemy']}}
|
185
|
+
nested3 = {'$and' => [nested2]}
|
186
|
+
translated3 = {:$and => [translated2]}
|
187
|
+
expected = [translated1, translated3]
|
188
|
+
|
189
|
+
subject.call(:$or, :$or, [nested1, nested3]).should eq(expected)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'plucky/normalizers/fields_value'
|
3
|
+
|
4
|
+
describe Plucky::Normalizers::FieldsValue do
|
5
|
+
it "defaults to nil" do
|
6
|
+
subject.call(nil).should be_nil
|
7
|
+
end
|
8
|
+
|
9
|
+
it "returns nil if empty string" do
|
10
|
+
subject.call('').should be_nil
|
11
|
+
end
|
12
|
+
|
13
|
+
it "returns nil if empty array" do
|
14
|
+
subject.call([]).should be_nil
|
15
|
+
end
|
16
|
+
|
17
|
+
it "works with array" do
|
18
|
+
subject.call(['one', 'two']).should eq(['one', 'two'])
|
19
|
+
end
|
20
|
+
|
21
|
+
# Ruby 1.9.x was sending array [{:age => 20}], instead of hash.
|
22
|
+
it "works with array that has one hash" do
|
23
|
+
subject.call([{:age => 20}]).should eq({:age => 20})
|
24
|
+
end
|
25
|
+
|
26
|
+
it "flattens multi-dimensional array" do
|
27
|
+
subject.call([[:one, :two]]).should eq([:one, :two])
|
28
|
+
end
|
29
|
+
|
30
|
+
it "works with symbol" do
|
31
|
+
subject.call(:one).should eq([:one])
|
32
|
+
end
|
33
|
+
|
34
|
+
it "works with array of symbols" do
|
35
|
+
subject.call([:one, :two]).should eq([:one, :two])
|
36
|
+
end
|
37
|
+
|
38
|
+
it "works with hash" do
|
39
|
+
subject.call({:one => 1, :two => -1}).should eq({:one => 1, :two => -1})
|
40
|
+
end
|
41
|
+
|
42
|
+
it "converts comma separated list to array" do
|
43
|
+
subject.call('one, two').should eq(['one', 'two'])
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'plucky/normalizers/integer'
|
3
|
+
|
4
|
+
describe Plucky::Normalizers::Integer do
|
5
|
+
context "with nil" do
|
6
|
+
it "returns nil" do
|
7
|
+
subject.call(nil).should be_nil
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
context "with an integer" do
|
12
|
+
it "returns an integer" do
|
13
|
+
subject.call(1).should be(1)
|
14
|
+
subject.call(3232).should be(3232)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context "with a string" do
|
19
|
+
it "returns a string" do
|
20
|
+
subject.call('1').should be(1)
|
21
|
+
subject.call('3232').should be(3232)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Plucky::Normalizers::OptionsHashKey do
|
4
|
+
subject {
|
5
|
+
described_class.new
|
6
|
+
}
|
7
|
+
|
8
|
+
it "changes order to sort" do
|
9
|
+
subject.call(:order).should eq(:sort)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "changes select to fields" do
|
13
|
+
subject.call(:select).should eq(:fields)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "changes offset to skip" do
|
17
|
+
subject.call(:offset).should eq(:skip)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "changes id to _id" do
|
21
|
+
subject.call(:id).should eq(:_id)
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Plucky::Normalizers::OptionsHashValue do
|
4
|
+
let(:key_normalizer) {
|
5
|
+
lambda { |key|
|
6
|
+
if key == :id
|
7
|
+
:_id
|
8
|
+
else
|
9
|
+
key.to_sym
|
10
|
+
end
|
11
|
+
}
|
12
|
+
}
|
13
|
+
|
14
|
+
let(:upcasing_normalizer) {
|
15
|
+
lambda { |value| value.to_s.upcase }
|
16
|
+
}
|
17
|
+
|
18
|
+
let(:default_arguments) {
|
19
|
+
{
|
20
|
+
:key_normalizer => key_normalizer,
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
subject {
|
25
|
+
described_class.new(default_arguments)
|
26
|
+
}
|
27
|
+
|
28
|
+
it "raises exception if missing key normalizer" do
|
29
|
+
expect {
|
30
|
+
described_class.new
|
31
|
+
}.to raise_error(ArgumentError, "Missing required key :key_normalizer")
|
32
|
+
end
|
33
|
+
|
34
|
+
it "allows injecting a new value normalizer" do
|
35
|
+
instance = described_class.new(default_arguments.merge({
|
36
|
+
:value_normalizers => {
|
37
|
+
:some_field => upcasing_normalizer,
|
38
|
+
}
|
39
|
+
}))
|
40
|
+
|
41
|
+
instance.call(:some_field, 'upcase me').should eq('UPCASE ME')
|
42
|
+
end
|
43
|
+
|
44
|
+
context "with :fields key" do
|
45
|
+
subject {
|
46
|
+
described_class.new(default_arguments.merge({
|
47
|
+
:value_normalizers => {
|
48
|
+
:fields => upcasing_normalizer
|
49
|
+
},
|
50
|
+
}))
|
51
|
+
}
|
52
|
+
|
53
|
+
it "calls the fields value normalizer" do
|
54
|
+
subject.call(:fields, :foo).should eq('FOO')
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context "with :sort key" do
|
59
|
+
subject {
|
60
|
+
described_class.new(default_arguments.merge({
|
61
|
+
:value_normalizers => {
|
62
|
+
:sort => upcasing_normalizer
|
63
|
+
},
|
64
|
+
}))
|
65
|
+
}
|
66
|
+
|
67
|
+
it "calls the sort value normalizer" do
|
68
|
+
subject.call(:sort, :foo).should eq('FOO')
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "with :limit key" do
|
73
|
+
subject {
|
74
|
+
described_class.new(default_arguments.merge({
|
75
|
+
:value_normalizers => {
|
76
|
+
:limit => upcasing_normalizer
|
77
|
+
},
|
78
|
+
}))
|
79
|
+
}
|
80
|
+
|
81
|
+
it "calls the limit value normalizer" do
|
82
|
+
subject.call(:limit, :foo).should eq('FOO')
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context "with :skip key" do
|
87
|
+
subject {
|
88
|
+
described_class.new(default_arguments.merge({
|
89
|
+
:value_normalizers => {
|
90
|
+
:skip => upcasing_normalizer
|
91
|
+
},
|
92
|
+
}))
|
93
|
+
}
|
94
|
+
|
95
|
+
it "calls the skip value normalizer" do
|
96
|
+
subject.call(:skip, :foo).should eq('FOO')
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'plucky/normalizers/sort_value'
|
3
|
+
|
4
|
+
describe Plucky::Normalizers::SortValue do
|
5
|
+
let(:key_normalizer) {
|
6
|
+
lambda { |key| key == :id ? :_id : key.to_sym }
|
7
|
+
}
|
8
|
+
|
9
|
+
subject {
|
10
|
+
described_class.new({
|
11
|
+
:key_normalizer => key_normalizer,
|
12
|
+
})
|
13
|
+
}
|
14
|
+
|
15
|
+
it "raises exception if missing key normalizer" do
|
16
|
+
expect {
|
17
|
+
described_class.new
|
18
|
+
}.to raise_error(ArgumentError, "Missing required key :key_normalizer")
|
19
|
+
end
|
20
|
+
|
21
|
+
it "defaults to nil" do
|
22
|
+
subject.call(nil).should eq(nil)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "works with natural order ascending" do
|
26
|
+
subject.call('$natural' => 1).should eq('$natural' => 1)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "works with natural order descending" do
|
30
|
+
subject.call('$natural' => -1).should eq('$natural' => -1)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "converts single ascending field (string)" do
|
34
|
+
subject.call('foo asc').should eq([['foo', 1]])
|
35
|
+
subject.call('foo ASC').should eq([['foo', 1]])
|
36
|
+
end
|
37
|
+
|
38
|
+
it "converts single descending field (string)" do
|
39
|
+
subject.call('foo desc').should eq([['foo', -1]])
|
40
|
+
subject.call('foo DESC').should eq([['foo', -1]])
|
41
|
+
end
|
42
|
+
|
43
|
+
it "converts multiple fields (string)" do
|
44
|
+
subject.call('foo desc, bar asc').should eq([['foo', -1], ['bar', 1]])
|
45
|
+
end
|
46
|
+
|
47
|
+
it "converts multiple fields and default no direction to ascending (string)" do
|
48
|
+
subject.call('foo desc, bar, baz').should eq([['foo', -1], ['bar', 1], ['baz', 1]])
|
49
|
+
end
|
50
|
+
|
51
|
+
it "converts symbol" do
|
52
|
+
subject.call(:name).should eq([['name', 1]])
|
53
|
+
end
|
54
|
+
|
55
|
+
it "converts operator" do
|
56
|
+
subject.call(:foo.desc).should eq([['foo', -1]])
|
57
|
+
end
|
58
|
+
|
59
|
+
it "converts array of operators" do
|
60
|
+
subject.call([:foo.desc, :bar.asc]).should eq([['foo', -1], ['bar', 1]])
|
61
|
+
end
|
62
|
+
|
63
|
+
it "converts array of symbols" do
|
64
|
+
subject.call([:first_name, :last_name]).should eq([['first_name', 1], ['last_name', 1]])
|
65
|
+
end
|
66
|
+
|
67
|
+
it "works with array and one string element" do
|
68
|
+
subject.call(['foo, bar desc']).should eq([['foo', 1], ['bar', -1]])
|
69
|
+
end
|
70
|
+
|
71
|
+
it "works with array of single array" do
|
72
|
+
subject.call([['foo', -1]]).should eq([['foo', -1]])
|
73
|
+
end
|
74
|
+
|
75
|
+
it "works with array of multiple arrays" do
|
76
|
+
subject.call([['foo', -1], ['bar', 1]]).should eq([['foo', -1], ['bar', 1]])
|
77
|
+
end
|
78
|
+
|
79
|
+
it "compacts nil values in array" do
|
80
|
+
subject.call([nil, :foo.desc]).should eq([['foo', -1]])
|
81
|
+
end
|
82
|
+
|
83
|
+
it "converts array with mix of values" do
|
84
|
+
subject.call([:foo.desc, 'bar']).should eq([['foo', -1], ['bar', 1]])
|
85
|
+
end
|
86
|
+
|
87
|
+
it "converts keys based on key normalizer" do
|
88
|
+
subject.call([:id.asc]).should eq([['_id', 1]])
|
89
|
+
end
|
90
|
+
|
91
|
+
it "converts string with $natural correctly" do
|
92
|
+
subject.call('$natural desc').should eq([['$natural', -1]])
|
93
|
+
end
|
94
|
+
end
|