plucky 0.5.2 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/spec/plucky_spec.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Plucky do
|
4
|
+
describe ".to_object_id" do
|
5
|
+
before do
|
6
|
+
@id = BSON::ObjectId.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it "converts nil to nil" do
|
10
|
+
Plucky.to_object_id(nil).should be_nil
|
11
|
+
end
|
12
|
+
|
13
|
+
it "converts blank to nil" do
|
14
|
+
Plucky.to_object_id('').should be_nil
|
15
|
+
end
|
16
|
+
|
17
|
+
it "leaves object id alone" do
|
18
|
+
Plucky.to_object_id(@id).should equal(@id)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "converts string to object id" do
|
22
|
+
Plucky.to_object_id(@id.to_s).should == @id
|
23
|
+
end
|
24
|
+
|
25
|
+
it "not convert string that is not legal object id" do
|
26
|
+
Plucky.to_object_id('foo').should == 'foo'
|
27
|
+
Plucky.to_object_id(1).should == 1
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe ".modifier?" do
|
32
|
+
context "with a string" do
|
33
|
+
it "returns true if modifier" do
|
34
|
+
Plucky.modifier?('$in').should be_true
|
35
|
+
end
|
36
|
+
|
37
|
+
it "returns false if not modifier" do
|
38
|
+
Plucky.modifier?('nope').should be_false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "with a symbol" do
|
43
|
+
it "returns true if modifier" do
|
44
|
+
Plucky.modifier?(:$in).should be_true
|
45
|
+
end
|
46
|
+
|
47
|
+
it "returns false if not modifier" do
|
48
|
+
Plucky.modifier?(:nope).should be_false
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "::Methods" do
|
54
|
+
it "returns array of methods" do
|
55
|
+
Plucky::Methods.should == [
|
56
|
+
:where, :filter,
|
57
|
+
:sort, :order, :reverse,
|
58
|
+
:paginate, :per_page, :limit, :skip, :offset,
|
59
|
+
:fields, :ignore, :only,
|
60
|
+
:each, :find_each, :find_one, :find,
|
61
|
+
:count, :size, :distinct,
|
62
|
+
:last, :first, :all, :to_a,
|
63
|
+
:exists?, :exist?, :empty?,
|
64
|
+
:remove,
|
65
|
+
].sort_by(&:to_s)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -1,55 +1,53 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
|
-
|
3
|
+
describe SymbolOperator do
|
4
4
|
context "SymbolOperator" do
|
5
|
-
|
5
|
+
before { @operator = SymbolOperator.new(:foo, 'in') }
|
6
6
|
subject { @operator }
|
7
7
|
|
8
|
-
|
8
|
+
it "has field" do
|
9
9
|
subject.field.should == :foo
|
10
10
|
end
|
11
11
|
|
12
|
-
|
12
|
+
it "has operator" do
|
13
13
|
subject.operator.should == 'in'
|
14
14
|
end
|
15
15
|
|
16
16
|
context "==" do
|
17
|
-
|
17
|
+
it "returns true if field and operator are equal" do
|
18
18
|
SymbolOperator.new(:foo, 'in').should == SymbolOperator.new(:foo, 'in')
|
19
19
|
end
|
20
20
|
|
21
|
-
|
21
|
+
it "returns false if fields are equal but operators are not" do
|
22
22
|
SymbolOperator.new(:foo, 'in').should_not == SymbolOperator.new(:foo, 'all')
|
23
23
|
end
|
24
24
|
|
25
|
-
|
25
|
+
it "returns false if operators are equal but fields are not" do
|
26
26
|
SymbolOperator.new(:foo, 'in').should_not == SymbolOperator.new(:bar, 'in')
|
27
27
|
end
|
28
28
|
|
29
|
-
|
29
|
+
it "returns false if neither are equal" do
|
30
30
|
SymbolOperator.new(:foo, 'in').should_not == SymbolOperator.new(:bar, 'all')
|
31
31
|
end
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
SymbolOperator.new(:foo, 'in').should_not == 'foo.in'
|
36
|
-
end
|
33
|
+
it "returns false if other isn't an symbol operator" do
|
34
|
+
SymbolOperator.new(:foo, 'in').should_not == 'foo.in'
|
37
35
|
end
|
38
36
|
end
|
39
37
|
|
40
38
|
context "<=>" do
|
41
|
-
|
39
|
+
it "returns string comparison of operator for same field, different operator" do
|
42
40
|
(SymbolOperator.new(:foo, 'in') <=> SymbolOperator.new(:foo, 'all')).should == 1
|
43
41
|
(SymbolOperator.new(:foo, 'all') <=> SymbolOperator.new(:foo, 'in')).should == -1
|
44
42
|
end
|
45
43
|
|
46
|
-
|
44
|
+
it "returns 0 for same field same operator" do
|
47
45
|
(SymbolOperator.new(:foo, 'in') <=> SymbolOperator.new(:foo, 'in')).should == 0
|
48
46
|
end
|
49
47
|
|
50
|
-
|
48
|
+
it "returns 1 for different field" do
|
51
49
|
(SymbolOperator.new(:foo, 'in') <=> SymbolOperator.new(:bar, 'in')).should == 1
|
52
50
|
end
|
53
51
|
end
|
54
52
|
end
|
55
|
-
end
|
53
|
+
end
|
data/spec/symbol_spec.rb
ADDED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: plucky
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-12-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: mongo
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,7 +21,12 @@ dependencies:
|
|
21
21
|
version: '1.5'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.5'
|
25
30
|
description:
|
26
31
|
email:
|
27
32
|
- nunemaker@gmail.com
|
@@ -29,9 +34,11 @@ executables: []
|
|
29
34
|
extensions: []
|
30
35
|
extra_rdoc_files: []
|
31
36
|
files:
|
37
|
+
- .bundle/config
|
32
38
|
- .gitignore
|
33
39
|
- .travis.yml
|
34
40
|
- Gemfile
|
41
|
+
- Guardfile
|
35
42
|
- LICENSE
|
36
43
|
- README.md
|
37
44
|
- Rakefile
|
@@ -43,6 +50,13 @@ files:
|
|
43
50
|
- lib/plucky/extensions/duplicable.rb
|
44
51
|
- lib/plucky/extensions/symbol.rb
|
45
52
|
- lib/plucky/new_relic.rb
|
53
|
+
- lib/plucky/normalizers/criteria_hash_key.rb
|
54
|
+
- lib/plucky/normalizers/criteria_hash_value.rb
|
55
|
+
- lib/plucky/normalizers/fields_value.rb
|
56
|
+
- lib/plucky/normalizers/integer.rb
|
57
|
+
- lib/plucky/normalizers/options_hash_key.rb
|
58
|
+
- lib/plucky/normalizers/options_hash_value.rb
|
59
|
+
- lib/plucky/normalizers/sort_value.rb
|
46
60
|
- lib/plucky/options_hash.rb
|
47
61
|
- lib/plucky/pagination.rb
|
48
62
|
- lib/plucky/pagination/decorator.rb
|
@@ -50,16 +64,24 @@ files:
|
|
50
64
|
- lib/plucky/query.rb
|
51
65
|
- lib/plucky/version.rb
|
52
66
|
- plucky.gemspec
|
67
|
+
- script/criteria_hash.rb
|
68
|
+
- spec/helper.rb
|
69
|
+
- spec/plucky/criteria_hash_spec.rb
|
70
|
+
- spec/plucky/normalizers/criteria_hash_key_spec.rb
|
71
|
+
- spec/plucky/normalizers/criteria_hash_value_spec.rb
|
72
|
+
- spec/plucky/normalizers/fields_value_spec.rb
|
73
|
+
- spec/plucky/normalizers/integer_spec.rb
|
74
|
+
- spec/plucky/normalizers/options_hash_key_spec.rb
|
75
|
+
- spec/plucky/normalizers/options_hash_value_spec.rb
|
76
|
+
- spec/plucky/normalizers/sort_value_spec.rb
|
77
|
+
- spec/plucky/options_hash_spec.rb
|
78
|
+
- spec/plucky/pagination/decorator_spec.rb
|
79
|
+
- spec/plucky/pagination/paginator_spec.rb
|
80
|
+
- spec/plucky/query_spec.rb
|
81
|
+
- spec/plucky_spec.rb
|
82
|
+
- spec/symbol_operator_spec.rb
|
83
|
+
- spec/symbol_spec.rb
|
53
84
|
- specs.watchr
|
54
|
-
- test/helper.rb
|
55
|
-
- test/plucky/pagination/test_decorator.rb
|
56
|
-
- test/plucky/pagination/test_paginator.rb
|
57
|
-
- test/plucky/test_criteria_hash.rb
|
58
|
-
- test/plucky/test_options_hash.rb
|
59
|
-
- test/plucky/test_query.rb
|
60
|
-
- test/test_plucky.rb
|
61
|
-
- test/test_symbol.rb
|
62
|
-
- test/test_symbol_operator.rb
|
63
85
|
homepage: http://jnunemaker.github.com/plucky/
|
64
86
|
licenses: []
|
65
87
|
post_install_message:
|
@@ -72,26 +94,39 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
72
94
|
- - ! '>='
|
73
95
|
- !ruby/object:Gem::Version
|
74
96
|
version: '0'
|
97
|
+
segments:
|
98
|
+
- 0
|
99
|
+
hash: 3663631979890408625
|
75
100
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
101
|
none: false
|
77
102
|
requirements:
|
78
103
|
- - ! '>='
|
79
104
|
- !ruby/object:Gem::Version
|
80
105
|
version: '0'
|
106
|
+
segments:
|
107
|
+
- 0
|
108
|
+
hash: 3663631979890408625
|
81
109
|
requirements: []
|
82
110
|
rubyforge_project:
|
83
|
-
rubygems_version: 1.8.
|
111
|
+
rubygems_version: 1.8.23
|
84
112
|
signing_key:
|
85
113
|
specification_version: 3
|
86
114
|
summary: Thin layer over the ruby driver that allows you to quickly grab hold of your
|
87
115
|
data (pluck it!).
|
88
116
|
test_files:
|
89
|
-
-
|
90
|
-
-
|
91
|
-
-
|
92
|
-
-
|
93
|
-
-
|
94
|
-
-
|
95
|
-
-
|
96
|
-
-
|
97
|
-
-
|
117
|
+
- spec/helper.rb
|
118
|
+
- spec/plucky/criteria_hash_spec.rb
|
119
|
+
- spec/plucky/normalizers/criteria_hash_key_spec.rb
|
120
|
+
- spec/plucky/normalizers/criteria_hash_value_spec.rb
|
121
|
+
- spec/plucky/normalizers/fields_value_spec.rb
|
122
|
+
- spec/plucky/normalizers/integer_spec.rb
|
123
|
+
- spec/plucky/normalizers/options_hash_key_spec.rb
|
124
|
+
- spec/plucky/normalizers/options_hash_value_spec.rb
|
125
|
+
- spec/plucky/normalizers/sort_value_spec.rb
|
126
|
+
- spec/plucky/options_hash_spec.rb
|
127
|
+
- spec/plucky/pagination/decorator_spec.rb
|
128
|
+
- spec/plucky/pagination/paginator_spec.rb
|
129
|
+
- spec/plucky/query_spec.rb
|
130
|
+
- spec/plucky_spec.rb
|
131
|
+
- spec/symbol_operator_spec.rb
|
132
|
+
- spec/symbol_spec.rb
|
@@ -1,120 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
class PaginatorTest < Test::Unit::TestCase
|
4
|
-
include Plucky::Pagination
|
5
|
-
|
6
|
-
context "#initialize" do
|
7
|
-
context "with total and page" do
|
8
|
-
setup { @paginator = Paginator.new(20, 2) }
|
9
|
-
subject { @paginator }
|
10
|
-
|
11
|
-
should "set total" do
|
12
|
-
subject.total_entries.should == 20
|
13
|
-
end
|
14
|
-
|
15
|
-
should "set page" do
|
16
|
-
subject.current_page.should == 2
|
17
|
-
end
|
18
|
-
|
19
|
-
should "default per_page to 25" do
|
20
|
-
subject.per_page.should == 25
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
context "with total, page and per_page" do
|
25
|
-
setup { @paginator = Paginator.new(20, 2, 10) }
|
26
|
-
subject { @paginator }
|
27
|
-
|
28
|
-
should "set total" do
|
29
|
-
subject.total_entries.should == 20
|
30
|
-
end
|
31
|
-
|
32
|
-
should "set page" do
|
33
|
-
subject.current_page.should == 2
|
34
|
-
end
|
35
|
-
|
36
|
-
should "set per_page" do
|
37
|
-
subject.per_page.should == 10
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
context "with string values for total, page and per_page" do
|
42
|
-
setup { @paginator = Paginator.new('20', '2', '10') }
|
43
|
-
subject { @paginator }
|
44
|
-
|
45
|
-
should "set total" do
|
46
|
-
subject.total_entries.should == 20
|
47
|
-
end
|
48
|
-
|
49
|
-
should "set page" do
|
50
|
-
subject.current_page.should == 2
|
51
|
-
end
|
52
|
-
|
53
|
-
should "set per_page" do
|
54
|
-
subject.per_page.should == 10
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
context "with page less than 1" do
|
59
|
-
setup { @paginator = Paginator.new(20, -2, 10) }
|
60
|
-
subject { @paginator }
|
61
|
-
|
62
|
-
should "set page to 1" do
|
63
|
-
subject.current_page.should == 1
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
should "alias limit to per_page" do
|
69
|
-
Paginator.new(30, 2, 30).limit.should == 30
|
70
|
-
end
|
71
|
-
|
72
|
-
should "be know total number of pages" do
|
73
|
-
Paginator.new(43, 2, 7).total_pages.should == 7
|
74
|
-
Paginator.new(40, 2, 10).total_pages.should == 4
|
75
|
-
end
|
76
|
-
|
77
|
-
context "#out_of_bounds?" do
|
78
|
-
should "be true if current_page is greater than total_pages" do
|
79
|
-
Paginator.new(2, 3, 1).should be_out_of_bounds
|
80
|
-
end
|
81
|
-
|
82
|
-
should "be false if current page is less than total_pages" do
|
83
|
-
Paginator.new(2, 1, 1).should_not be_out_of_bounds
|
84
|
-
end
|
85
|
-
|
86
|
-
should "be false if current page equals total_pages" do
|
87
|
-
Paginator.new(2, 2, 1).should_not be_out_of_bounds
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
context "#previous_page" do
|
92
|
-
should "be nil if there is no page less than current" do
|
93
|
-
Paginator.new(2, 1, 1).previous_page.should be_nil
|
94
|
-
end
|
95
|
-
|
96
|
-
should "be number less than current page if there is one" do
|
97
|
-
Paginator.new(2, 2, 1).previous_page.should == 1
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
context "#next_page" do
|
102
|
-
should "be nil if no page greater than current page" do
|
103
|
-
Paginator.new(2, 2, 1).next_page.should be_nil
|
104
|
-
end
|
105
|
-
|
106
|
-
should "be number greater than current page if there is one" do
|
107
|
-
Paginator.new(2, 1, 1).next_page.should == 2
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
context "#skip" do
|
112
|
-
should "work" do
|
113
|
-
Paginator.new(30, 3, 10).skip.should == 20
|
114
|
-
end
|
115
|
-
|
116
|
-
should "be aliased to offset for will paginate" do
|
117
|
-
Paginator.new(30, 3, 10).offset.should == 20
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
@@ -1,359 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
class CriteriaHashTest < Test::Unit::TestCase
|
4
|
-
include Plucky
|
5
|
-
|
6
|
-
context "Plucky::CriteriaHash" do
|
7
|
-
should "delegate missing methods to the source hash" do
|
8
|
-
hash = {:baz => 'wick', :foo => 'bar'}
|
9
|
-
criteria = CriteriaHash.new(hash)
|
10
|
-
criteria[:foo].should == 'bar'
|
11
|
-
criteria[:baz].should == 'wick'
|
12
|
-
criteria.keys.to_set.should == [:baz, :foo].to_set
|
13
|
-
end
|
14
|
-
|
15
|
-
SymbolOperators.each do |operator|
|
16
|
-
should "work with #{operator} symbol operator" do
|
17
|
-
CriteriaHash.new(:age.send(operator) => 21)[:age].should == {"$#{operator}" => 21}
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
should "handle multiple symbol operators on the same field" do
|
22
|
-
CriteriaHash.new(:age.gt => 12, :age.lt => 20)[:age].should == {
|
23
|
-
'$gt' => 12, '$lt' => 20
|
24
|
-
}
|
25
|
-
end
|
26
|
-
|
27
|
-
context "nested clauses" do
|
28
|
-
context "::NestingOperators" do
|
29
|
-
should "return array of operators that take nested queries" do
|
30
|
-
CriteriaHash::NestingOperators.should == [:$or, :$and, :$nor]
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
CriteriaHash::NestingOperators.each do |operator|
|
35
|
-
context "#{operator}" do
|
36
|
-
should "work with symbol operators" do
|
37
|
-
nested1 = {:age.gt => 12, :age.lt => 20}
|
38
|
-
translated1 = {:age => {'$gt' => 12, '$lt' => 20 }}
|
39
|
-
nested2 = {:type.nin => ['friend', 'enemy']}
|
40
|
-
translated2 = {:type => {'$nin' => ['friend', 'enemy']}}
|
41
|
-
|
42
|
-
given = {operator.to_s => [nested1, nested2]}
|
43
|
-
|
44
|
-
CriteriaHash.new(given)[operator].should == [translated1, translated2]
|
45
|
-
end
|
46
|
-
|
47
|
-
should "honor criteria hash options" do
|
48
|
-
nested = {:post_id => '4f5ead6378fca23a13000001'}
|
49
|
-
translated = {:post_id => BSON::ObjectId.from_string('4f5ead6378fca23a13000001')}
|
50
|
-
given = {operator.to_s => [nested]}
|
51
|
-
|
52
|
-
CriteriaHash.new(given, :object_ids => [:post_id])[operator].should == [translated]
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
context "doubly nested" do
|
58
|
-
should "work with symbol operators" do
|
59
|
-
nested1 = {:age.gt => 12, :age.lt => 20}
|
60
|
-
translated1 = {:age => {'$gt' => 12, '$lt' => 20}}
|
61
|
-
nested2 = {:type.nin => ['friend', 'enemy']}
|
62
|
-
translated2 = {:type => {'$nin' => ['friend', 'enemy']}}
|
63
|
-
nested3 = {'$and' => [nested2]}
|
64
|
-
translated3 = {:$and => [translated2]}
|
65
|
-
|
66
|
-
given = {'$or' => [nested1, nested3]}
|
67
|
-
|
68
|
-
CriteriaHash.new(given)[:$or].should == [translated1, translated3]
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
context "#initialize_copy" do
|
74
|
-
setup do
|
75
|
-
@original = CriteriaHash.new({
|
76
|
-
:comments => {:_id => 1}, :tags => ['mongo', 'ruby'],
|
77
|
-
}, :object_ids => [:_id])
|
78
|
-
@cloned = @original.clone
|
79
|
-
end
|
80
|
-
|
81
|
-
should "duplicate source hash" do
|
82
|
-
@cloned.source.should_not equal(@original.source)
|
83
|
-
end
|
84
|
-
|
85
|
-
should "duplicate options hash" do
|
86
|
-
@cloned.options.should_not equal(@original.options)
|
87
|
-
end
|
88
|
-
|
89
|
-
should "clone duplicable? values" do
|
90
|
-
@cloned[:comments].should_not equal(@original[:comments])
|
91
|
-
@cloned[:tags].should_not equal(@original[:tags])
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
context "#object_ids=" do
|
96
|
-
should "work with array" do
|
97
|
-
criteria = CriteriaHash.new
|
98
|
-
criteria.object_ids = [:_id]
|
99
|
-
criteria.object_ids.should == [:_id]
|
100
|
-
end
|
101
|
-
|
102
|
-
should "flatten multi-dimensional array" do
|
103
|
-
criteria = CriteriaHash.new
|
104
|
-
criteria.object_ids = [[:_id]]
|
105
|
-
criteria.object_ids.should == [:_id]
|
106
|
-
end
|
107
|
-
|
108
|
-
should "raise argument error if not array" do
|
109
|
-
assert_raises(ArgumentError) { CriteriaHash.new.object_ids = {} }
|
110
|
-
assert_raises(ArgumentError) { CriteriaHash.new.object_ids = nil }
|
111
|
-
assert_raises(ArgumentError) { CriteriaHash.new.object_ids = 'foo' }
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
context "#[]=" do
|
116
|
-
should "leave string values for string keys alone" do
|
117
|
-
criteria = CriteriaHash.new
|
118
|
-
criteria[:foo] = 'bar'
|
119
|
-
criteria[:foo].should == 'bar'
|
120
|
-
end
|
121
|
-
|
122
|
-
should "convert string values to object ids for object id keys" do
|
123
|
-
id = BSON::ObjectId.new
|
124
|
-
criteria = CriteriaHash.new({}, :object_ids => [:_id])
|
125
|
-
criteria[:_id] = id.to_s
|
126
|
-
criteria[:_id].should == id
|
127
|
-
end
|
128
|
-
|
129
|
-
should "convert sets to arrays" do
|
130
|
-
criteria = CriteriaHash.new
|
131
|
-
criteria[:foo] = [1, 2].to_set
|
132
|
-
criteria[:foo].should == {'$in' => [1, 2]}
|
133
|
-
end
|
134
|
-
|
135
|
-
should "convert times to utc" do
|
136
|
-
time = Time.now
|
137
|
-
criteria = CriteriaHash.new
|
138
|
-
criteria[:foo] = time
|
139
|
-
criteria[:foo].should be_utc
|
140
|
-
criteria[:foo].should == time.utc
|
141
|
-
end
|
142
|
-
|
143
|
-
should "convert :id to :_id" do
|
144
|
-
criteria = CriteriaHash.new
|
145
|
-
criteria[:id] = 1
|
146
|
-
criteria[:_id].should == 1
|
147
|
-
criteria[:id].should be_nil
|
148
|
-
end
|
149
|
-
|
150
|
-
should "work with symbol operators" do
|
151
|
-
criteria = CriteriaHash.new
|
152
|
-
criteria[:_id.in] = ['foo']
|
153
|
-
criteria[:_id].should == {'$in' => ['foo']}
|
154
|
-
end
|
155
|
-
|
156
|
-
should "set each of the conditions pairs" do
|
157
|
-
criteria = CriteriaHash.new
|
158
|
-
criteria[:conditions] = {:_id => 'john', :foo => 'bar'}
|
159
|
-
criteria[:_id].should == 'john'
|
160
|
-
criteria[:foo].should == 'bar'
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
context "with id key" do
|
165
|
-
should "convert to _id" do
|
166
|
-
id = BSON::ObjectId.new
|
167
|
-
criteria = CriteriaHash.new(:id => id)
|
168
|
-
criteria[:_id].should == id
|
169
|
-
criteria[:id].should be_nil
|
170
|
-
end
|
171
|
-
|
172
|
-
should "convert id with symbol operator to _id with modifier" do
|
173
|
-
id = BSON::ObjectId.new
|
174
|
-
criteria = CriteriaHash.new(:id.ne => id)
|
175
|
-
criteria[:_id].should == {'$ne' => id}
|
176
|
-
criteria[:id].should be_nil
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
context "with time value" do
|
181
|
-
should "convert to utc if not utc" do
|
182
|
-
CriteriaHash.new(:created_at => Time.now)[:created_at].utc?.should be(true)
|
183
|
-
end
|
184
|
-
|
185
|
-
should "leave utc alone" do
|
186
|
-
CriteriaHash.new(:created_at => Time.now.utc)[:created_at].utc?.should be(true)
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
context "with array value" do
|
191
|
-
should "default to $in" do
|
192
|
-
CriteriaHash.new(:numbers => [1,2,3])[:numbers].should == {'$in' => [1,2,3]}
|
193
|
-
end
|
194
|
-
|
195
|
-
should "use existing modifier if present" do
|
196
|
-
CriteriaHash.new(:numbers => {'$all' => [1,2,3]})[:numbers].should == {'$all' => [1,2,3]}
|
197
|
-
CriteriaHash.new(:numbers => {'$any' => [1,2,3]})[:numbers].should == {'$any' => [1,2,3]}
|
198
|
-
end
|
199
|
-
|
200
|
-
should "not turn value to $in with $or key" do
|
201
|
-
CriteriaHash.new(:$or => [{:numbers => 1}, {:numbers => 2}] )[:$or].should == [{:numbers=>1}, {:numbers=>2}]
|
202
|
-
end
|
203
|
-
|
204
|
-
should "not turn value to $in with $and key" do
|
205
|
-
CriteriaHash.new(:$and => [{:numbers => 1}, {:numbers => 2}] )[:$and].should == [{:numbers=>1}, {:numbers=>2}]
|
206
|
-
end
|
207
|
-
|
208
|
-
should "not turn value to $in with $nor key" do
|
209
|
-
CriteriaHash.new(:$nor => [{:numbers => 1}, {:numbers => 2}] )[:$nor].should == [{:numbers=>1}, {:numbers=>2}]
|
210
|
-
end
|
211
|
-
|
212
|
-
should "default to $in even with ObjectId keys" do
|
213
|
-
CriteriaHash.new({:mistake_id => [1,2,3]}, :object_ids => [:mistake_id])[:mistake_id].should == {'$in' => [1,2,3]}
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
|
-
context "with set value" do
|
218
|
-
should "default to $in and convert to array" do
|
219
|
-
CriteriaHash.new(:numbers => [1,2,3].to_set)[:numbers].should == {'$in' => [1,2,3]}
|
220
|
-
end
|
221
|
-
|
222
|
-
should "use existing modifier if present and convert to array" do
|
223
|
-
CriteriaHash.new(:numbers => {'$all' => [1,2,3].to_set})[:numbers].should == {'$all' => [1,2,3]}
|
224
|
-
CriteriaHash.new(:numbers => {'$any' => [1,2,3].to_set})[:numbers].should == {'$any' => [1,2,3]}
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
context "with string ids for string keys" do
|
229
|
-
setup do
|
230
|
-
@id = BSON::ObjectId.new
|
231
|
-
@room_id = BSON::ObjectId.new
|
232
|
-
@criteria = CriteriaHash.new(:_id => @id.to_s, :room_id => @room_id.to_s)
|
233
|
-
end
|
234
|
-
|
235
|
-
should "leave string ids as strings" do
|
236
|
-
@criteria[:_id].should == @id.to_s
|
237
|
-
@criteria[:room_id].should == @room_id.to_s
|
238
|
-
@criteria[:_id].should be_instance_of(String)
|
239
|
-
@criteria[:room_id].should be_instance_of(String)
|
240
|
-
end
|
241
|
-
end
|
242
|
-
|
243
|
-
context "with string ids for object id keys" do
|
244
|
-
setup do
|
245
|
-
@id = BSON::ObjectId.new
|
246
|
-
@room_id = BSON::ObjectId.new
|
247
|
-
end
|
248
|
-
|
249
|
-
should "convert strings to object ids" do
|
250
|
-
criteria = CriteriaHash.new({:_id => @id.to_s, :room_id => @room_id.to_s}, :object_ids => [:_id, :room_id])
|
251
|
-
criteria[:_id].should == @id
|
252
|
-
criteria[:room_id].should == @room_id
|
253
|
-
criteria[:_id].should be_instance_of(BSON::ObjectId)
|
254
|
-
criteria[:room_id].should be_instance_of(BSON::ObjectId)
|
255
|
-
end
|
256
|
-
|
257
|
-
should "convert :id with string value to object id value" do
|
258
|
-
criteria = CriteriaHash.new({:id => @id.to_s}, :object_ids => [:_id])
|
259
|
-
criteria[:_id].should == @id
|
260
|
-
end
|
261
|
-
end
|
262
|
-
|
263
|
-
context "with string ids for object id keys (nested)" do
|
264
|
-
setup do
|
265
|
-
@id1 = BSON::ObjectId.new
|
266
|
-
@id2 = BSON::ObjectId.new
|
267
|
-
@ids = [@id1.to_s, @id2.to_s]
|
268
|
-
@criteria = CriteriaHash.new({:_id => {'$in' => @ids}}, :object_ids => [:_id])
|
269
|
-
end
|
270
|
-
|
271
|
-
should "convert strings to object ids" do
|
272
|
-
@criteria[:_id].should == {'$in' => [@id1, @id2]}
|
273
|
-
end
|
274
|
-
|
275
|
-
should "not modify original array of string ids" do
|
276
|
-
@ids.should == [@id1.to_s, @id2.to_s]
|
277
|
-
end
|
278
|
-
end
|
279
|
-
|
280
|
-
context "#merge" do
|
281
|
-
should "work when no keys match" do
|
282
|
-
c1 = CriteriaHash.new(:foo => 'bar')
|
283
|
-
c2 = CriteriaHash.new(:baz => 'wick')
|
284
|
-
c1.merge(c2).should == CriteriaHash.new(:foo => 'bar', :baz => 'wick')
|
285
|
-
end
|
286
|
-
|
287
|
-
should "turn matching keys with simple values into array" do
|
288
|
-
c1 = CriteriaHash.new(:foo => 'bar')
|
289
|
-
c2 = CriteriaHash.new(:foo => 'baz')
|
290
|
-
c1.merge(c2).should == CriteriaHash.new(:foo => {'$in' => %w[bar baz]})
|
291
|
-
end
|
292
|
-
|
293
|
-
should "unique matching key values" do
|
294
|
-
c1 = CriteriaHash.new(:foo => 'bar')
|
295
|
-
c2 = CriteriaHash.new(:foo => 'bar')
|
296
|
-
c1.merge(c2).should == CriteriaHash.new(:foo => {'$in' => %w[bar]})
|
297
|
-
end
|
298
|
-
|
299
|
-
should "correctly merge arrays and non-arrays" do
|
300
|
-
c1 = CriteriaHash.new(:foo => 'bar')
|
301
|
-
c2 = CriteriaHash.new(:foo => %w[bar baz])
|
302
|
-
c1.merge(c2).should == CriteriaHash.new(:foo => {'$in' => %w[bar baz]})
|
303
|
-
c2.merge(c1).should == CriteriaHash.new(:foo => {'$in' => %w[bar baz]})
|
304
|
-
end
|
305
|
-
|
306
|
-
should "be able to merge two modifier hashes" do
|
307
|
-
c1 = CriteriaHash.new('$in' => [1, 2])
|
308
|
-
c2 = CriteriaHash.new('$in' => [2, 3])
|
309
|
-
c1.merge(c2).should == CriteriaHash.new('$in' => [1, 2, 3])
|
310
|
-
end
|
311
|
-
|
312
|
-
should "merge matching keys with a single modifier" do
|
313
|
-
c1 = CriteriaHash.new(:foo => {'$in' => [1, 2, 3]})
|
314
|
-
c2 = CriteriaHash.new(:foo => {'$in' => [1, 4, 5]})
|
315
|
-
c1.merge(c2).should == CriteriaHash.new(:foo => {'$in' => [1, 2, 3, 4, 5]})
|
316
|
-
end
|
317
|
-
|
318
|
-
should "merge matching keys with multiple modifiers" do
|
319
|
-
c1 = CriteriaHash.new(:foo => {'$in' => [1, 2, 3]})
|
320
|
-
c2 = CriteriaHash.new(:foo => {'$all' => [1, 4, 5]})
|
321
|
-
c1.merge(c2).should == CriteriaHash.new(:foo => {'$in' => [1, 2, 3], '$all' => [1, 4, 5]})
|
322
|
-
end
|
323
|
-
|
324
|
-
should "not update mergee" do
|
325
|
-
c1 = CriteriaHash.new(:foo => 'bar')
|
326
|
-
c2 = CriteriaHash.new(:foo => 'baz')
|
327
|
-
c1.merge(c2).should_not equal(c1)
|
328
|
-
c1[:foo].should == 'bar'
|
329
|
-
end
|
330
|
-
end
|
331
|
-
|
332
|
-
context "#merge!" do
|
333
|
-
should "merge and replace" do
|
334
|
-
c1 = CriteriaHash.new(:foo => 'bar')
|
335
|
-
c2 = CriteriaHash.new(:foo => 'baz')
|
336
|
-
c1.merge!(c2)
|
337
|
-
c1[:foo].should == {'$in' => ['bar', 'baz']}
|
338
|
-
end
|
339
|
-
end
|
340
|
-
|
341
|
-
context "#simple?" do
|
342
|
-
should "be true if only filtering by _id" do
|
343
|
-
CriteriaHash.new(:_id => 'id').should be_simple
|
344
|
-
end
|
345
|
-
|
346
|
-
should "be true if only filtering by Sci" do
|
347
|
-
CriteriaHash.new(:_id => 'id', :_type => 'Foo').should be_simple
|
348
|
-
end
|
349
|
-
|
350
|
-
should "be false if querying by anthing other than _id/Sci" do
|
351
|
-
CriteriaHash.new(:foo => 'bar').should_not be_simple
|
352
|
-
end
|
353
|
-
|
354
|
-
should "be false if querying only by _type" do
|
355
|
-
CriteriaHash.new(:_type => 'Foo').should_not be_simple
|
356
|
-
end
|
357
|
-
end
|
358
|
-
end
|
359
|
-
end
|