mongo_mapper 0.6.10 → 0.7.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.
Files changed (106) hide show
  1. data/README.rdoc +5 -14
  2. data/Rakefile +1 -1
  3. data/VERSION +1 -1
  4. data/lib/mongo_mapper.rb +48 -56
  5. data/lib/mongo_mapper/document.rb +136 -164
  6. data/lib/mongo_mapper/embedded_document.rb +29 -354
  7. data/lib/mongo_mapper/plugins.rb +31 -0
  8. data/lib/mongo_mapper/plugins/associations.rb +105 -0
  9. data/lib/mongo_mapper/plugins/associations/base.rb +123 -0
  10. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +30 -0
  11. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +25 -0
  12. data/lib/mongo_mapper/plugins/associations/collection.rb +21 -0
  13. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +50 -0
  14. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +139 -0
  15. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
  16. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +117 -0
  17. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +31 -0
  18. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +23 -0
  19. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +13 -0
  20. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +68 -0
  21. data/lib/mongo_mapper/plugins/associations/proxy.rb +118 -0
  22. data/lib/mongo_mapper/plugins/callbacks.rb +65 -0
  23. data/lib/mongo_mapper/plugins/clone.rb +13 -0
  24. data/lib/mongo_mapper/plugins/descendants.rb +16 -0
  25. data/lib/mongo_mapper/plugins/dirty.rb +119 -0
  26. data/lib/mongo_mapper/plugins/equality.rb +23 -0
  27. data/lib/mongo_mapper/plugins/identity_map.rb +122 -0
  28. data/lib/mongo_mapper/plugins/inspect.rb +14 -0
  29. data/lib/mongo_mapper/plugins/keys.rb +324 -0
  30. data/lib/mongo_mapper/plugins/logger.rb +17 -0
  31. data/lib/mongo_mapper/plugins/pagination.rb +24 -0
  32. data/lib/mongo_mapper/plugins/pagination/proxy.rb +68 -0
  33. data/lib/mongo_mapper/plugins/protected.rb +45 -0
  34. data/lib/mongo_mapper/plugins/rails.rb +45 -0
  35. data/lib/mongo_mapper/plugins/serialization.rb +105 -0
  36. data/lib/mongo_mapper/plugins/validations.rb +46 -0
  37. data/lib/mongo_mapper/query.rb +130 -0
  38. data/lib/mongo_mapper/support.rb +40 -17
  39. data/lib/mongo_mapper/support/descendant_appends.rb +46 -0
  40. data/lib/mongo_mapper/support/find.rb +77 -0
  41. data/mongo_mapper.gemspec +55 -38
  42. data/performance/read_write.rb +52 -0
  43. data/specs.watchr +23 -2
  44. data/test/functional/associations/test_belongs_to_proxy.rb +12 -10
  45. data/test/functional/associations/test_many_documents_as_proxy.rb +4 -21
  46. data/test/functional/associations/test_many_documents_proxy.rb +2 -8
  47. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +59 -39
  48. data/test/functional/associations/test_many_embedded_proxy.rb +145 -81
  49. data/test/functional/associations/test_many_polymorphic_proxy.rb +2 -40
  50. data/test/functional/associations/test_one_proxy.rb +25 -10
  51. data/test/functional/test_binary.rb +2 -8
  52. data/test/functional/test_callbacks.rb +1 -5
  53. data/test/functional/test_dirty.rb +27 -23
  54. data/test/functional/test_document.rb +224 -165
  55. data/test/functional/test_embedded_document.rb +72 -82
  56. data/test/functional/test_identity_map.rb +508 -0
  57. data/test/functional/test_modifiers.rb +15 -5
  58. data/test/functional/test_pagination.rb +1 -3
  59. data/test/functional/test_protected.rb +155 -0
  60. data/test/functional/test_string_id_compatibility.rb +7 -12
  61. data/test/functional/test_validations.rb +26 -58
  62. data/test/models.rb +0 -39
  63. data/test/test_helper.rb +37 -3
  64. data/test/unit/associations/test_base.rb +5 -5
  65. data/test/unit/associations/test_proxy.rb +8 -6
  66. data/test/unit/test_descendant_appends.rb +71 -0
  67. data/test/unit/test_document.rb +71 -76
  68. data/test/unit/test_dynamic_finder.rb +27 -29
  69. data/test/unit/test_embedded_document.rb +555 -601
  70. data/test/unit/{test_key.rb → test_keys.rb} +2 -5
  71. data/test/unit/test_mongo_mapper.rb +69 -9
  72. data/test/unit/test_pagination.rb +40 -32
  73. data/test/unit/test_plugins.rb +50 -0
  74. data/test/unit/{test_finder_options.rb → test_query.rb} +74 -65
  75. data/test/unit/test_rails.rb +123 -0
  76. data/test/unit/{test_serializations.rb → test_serialization.rb} +1 -2
  77. data/test/unit/test_support.rb +23 -7
  78. data/test/unit/test_time_zones.rb +3 -4
  79. data/test/unit/test_validations.rb +58 -17
  80. metadata +53 -36
  81. data/lib/mongo_mapper/associations.rb +0 -78
  82. data/lib/mongo_mapper/associations/base.rb +0 -119
  83. data/lib/mongo_mapper/associations/belongs_to_polymorphic_proxy.rb +0 -26
  84. data/lib/mongo_mapper/associations/belongs_to_proxy.rb +0 -21
  85. data/lib/mongo_mapper/associations/collection.rb +0 -19
  86. data/lib/mongo_mapper/associations/in_array_proxy.rb +0 -137
  87. data/lib/mongo_mapper/associations/many_documents_as_proxy.rb +0 -26
  88. data/lib/mongo_mapper/associations/many_documents_proxy.rb +0 -115
  89. data/lib/mongo_mapper/associations/many_embedded_polymorphic_proxy.rb +0 -31
  90. data/lib/mongo_mapper/associations/many_embedded_proxy.rb +0 -54
  91. data/lib/mongo_mapper/associations/many_polymorphic_proxy.rb +0 -11
  92. data/lib/mongo_mapper/associations/one_proxy.rb +0 -64
  93. data/lib/mongo_mapper/associations/proxy.rb +0 -116
  94. data/lib/mongo_mapper/callbacks.rb +0 -61
  95. data/lib/mongo_mapper/dirty.rb +0 -117
  96. data/lib/mongo_mapper/dynamic_finder.rb +0 -74
  97. data/lib/mongo_mapper/finder_options.rb +0 -145
  98. data/lib/mongo_mapper/key.rb +0 -36
  99. data/lib/mongo_mapper/mongo_mapper.rb +0 -125
  100. data/lib/mongo_mapper/pagination.rb +0 -66
  101. data/lib/mongo_mapper/rails_compatibility/document.rb +0 -15
  102. data/lib/mongo_mapper/rails_compatibility/embedded_document.rb +0 -28
  103. data/lib/mongo_mapper/serialization.rb +0 -54
  104. data/lib/mongo_mapper/serializers/json_serializer.rb +0 -48
  105. data/lib/mongo_mapper/validations.rb +0 -39
  106. data/test/functional/test_rails_compatibility.rb +0 -25
@@ -20,7 +20,7 @@ class FooType < Struct.new(:bar)
20
20
  end
21
21
 
22
22
  class KeyTest < Test::Unit::TestCase
23
- include MongoMapper
23
+ include MongoMapper::Plugins::Keys
24
24
 
25
25
  context "Initializing a new key" do
26
26
  should "allow setting the name" do
@@ -82,10 +82,7 @@ class KeyTest < Test::Unit::TestCase
82
82
  end
83
83
 
84
84
  should "know if it is a embedded_document" do
85
- klass = Class.new do
86
- include MongoMapper::EmbeddedDocument
87
- end
88
- Key.new(:name, klass).embeddable?.should be_true
85
+ Key.new(:name, EDoc()).embeddable?.should be_true
89
86
  end
90
87
 
91
88
  should "know if it is not a embedded_document" do
@@ -8,58 +8,118 @@ class MongoMapperTest < Test::Unit::TestCase
8
8
  MongoMapper.connection = conn
9
9
  MongoMapper.connection.should == conn
10
10
  end
11
-
11
+
12
12
  should "default connection to new mongo ruby driver" do
13
13
  MongoMapper.connection = nil
14
14
  MongoMapper.connection.should be_instance_of(Mongo::Connection)
15
15
  end
16
-
16
+
17
17
  should "be able to write and read default database" do
18
18
  MongoMapper.database = 'test'
19
19
  MongoMapper.database.should be_instance_of(Mongo::DB)
20
20
  MongoMapper.database.name.should == 'test'
21
21
  end
22
-
22
+
23
23
  should "have document not found error" do
24
24
  lambda {
25
25
  MongoMapper::DocumentNotFound
26
26
  }.should_not raise_error
27
27
  end
28
+
29
+ should "be able to read/write config" do
30
+ config = {
31
+ 'development' => {'host' => '127.0.0.1', 'port' => 27017, 'database' => 'test'},
32
+ 'production' => {'host' => '127.0.0.1', 'port' => 27017, 'database' => 'test-prod'}
33
+ }
34
+
35
+ MongoMapper.config = config
36
+ MongoMapper.config.should == config
37
+ end
38
+
39
+ context "connecting to environment from config" do
40
+ should "work without authentication" do
41
+ MongoMapper.config = {
42
+ 'development' => {'host' => '127.0.0.1', 'port' => 27017, 'database' => 'test'}
43
+ }
44
+
45
+ Mongo::Connection.expects(:new).with('127.0.0.1', 27017, {})
46
+ MongoMapper.expects(:database=).with('test')
47
+ Mongo::DB.any_instance.expects(:authenticate).never
48
+ MongoMapper.connect('development')
49
+ end
50
+
51
+ should "work with options" do
52
+ MongoMapper.config = {
53
+ 'development' => {'host' => '127.0.0.1', 'port' => 27017, 'database' => 'test'}
54
+ }
55
+
56
+ connection, logger = mock('connection'), mock('logger')
57
+ Mongo::Connection.expects(:new).with('127.0.0.1', 27017, :logger => logger)
58
+ MongoMapper.connect('development', :logger => logger)
59
+ end
60
+
61
+ should "work with authentication" do
62
+ MongoMapper.config = {
63
+ 'development' => {'host' => '127.0.0.1', 'port' => 27017, 'database' => 'test', 'username' => 'john', 'password' => 'secret'}
64
+ }
65
+
66
+ Mongo::DB.any_instance.expects(:authenticate).with('john', 'secret')
67
+ MongoMapper.connect('development')
68
+ end
69
+ end
70
+
71
+ context "setup" do
72
+ should "work as shortcut for setting config, environment and options" do
73
+ config, logger = mock('config'), mock('logger')
74
+ MongoMapper.expects(:config=).with(config)
75
+ MongoMapper.expects(:connect).with('development', :logger => logger)
76
+ MongoMapper.expects(:handle_passenger_forking).never
77
+ MongoMapper.setup(config, 'development', :logger => logger)
78
+ end
79
+
80
+ should "handle passenger if option present" do
81
+ config, logger = mock('config'), mock('logger')
82
+ MongoMapper.expects(:config=).with(config)
83
+ MongoMapper.expects(:connect).with('development', :logger => logger)
84
+ MongoMapper.expects(:handle_passenger_forking)
85
+ MongoMapper.setup(config, 'development', :logger => logger, :passenger => true)
86
+ end
87
+ end
28
88
 
89
+
29
90
  context "use_time_zone?" do
30
91
  should "be true if Time.zone set" do
31
92
  Time.zone = 'Hawaii'
32
93
  MongoMapper.use_time_zone?.should be_true
33
94
  Time.zone = nil
34
95
  end
35
-
96
+
36
97
  should "be false if Time.zone not set" do
37
98
  MongoMapper.use_time_zone?.should be_false
38
99
  end
39
100
  end
40
-
101
+
41
102
  context "time_class" do
42
103
  should "be Time.zone if using time zones" do
43
104
  Time.zone = 'Hawaii'
44
105
  MongoMapper.time_class.should == Time.zone
45
106
  Time.zone = nil
46
107
  end
47
-
108
+
48
109
  should "be Time if not using time zones" do
49
110
  MongoMapper.time_class.should == Time
50
111
  end
51
112
  end
52
-
113
+
53
114
  context "normalize_object_id" do
54
115
  should "turn string into object id" do
55
116
  id = Mongo::ObjectID.new
56
117
  MongoMapper.normalize_object_id(id.to_s).should == id
57
118
  end
58
-
119
+
59
120
  should "leave object id alone" do
60
121
  id = Mongo::ObjectID.new
61
122
  MongoMapper.normalize_object_id(id).should == id
62
123
  end
63
124
  end
64
-
65
125
  end
@@ -1,19 +1,27 @@
1
1
  require 'test_helper'
2
2
 
3
- class PaginationTest < Test::Unit::TestCase
3
+ class PaginationTest < Test::Unit::TestCase
4
+ should "default per_page to 25" do
5
+ Doc().per_page.should == 25
6
+ end
7
+
8
+ should "allow overriding per_page" do
9
+ Doc() { def self.per_page; 1 end }.per_page.should == 1
10
+ end
11
+
4
12
  context "Pagination proxy" do
5
- include MongoMapper::Pagination
13
+ include MongoMapper::Plugins::Pagination
6
14
 
7
15
  should "should have accessors for subject" do
8
16
  subject = [1,2,3,4,5]
9
- collection = PaginationProxy.new(25, 2)
17
+ collection = Proxy.new(25, 2)
10
18
  collection.subject = subject
11
19
  collection.subject.should == subject
12
20
  end
13
21
 
14
22
  should "delegate any methods not defined to the subject" do
15
23
  subject = [1,2,3,4,5]
16
- collection = PaginationProxy.new(25, 2, 10)
24
+ collection = Proxy.new(25, 2, 10)
17
25
  collection.subject = subject
18
26
  collection.size.should == 5
19
27
  collection.each_with_index do |value, i|
@@ -24,96 +32,96 @@ class PaginationTest < Test::Unit::TestCase
24
32
  end
25
33
 
26
34
  should "return correct value for total_entries" do
27
- PaginationProxy.new(25, 2, 10).total_entries.should == 25
28
- PaginationProxy.new('25', 2, 10).total_entries.should == 25
35
+ Proxy.new(25, 2, 10).total_entries.should == 25
36
+ Proxy.new('25', 2, 10).total_entries.should == 25
29
37
  end
30
38
 
31
39
  should "return correct value for per_page" do
32
- PaginationProxy.new(25, 2, 10).per_page.should == 10
33
- PaginationProxy.new(25, 2, '10').per_page.should == 10
40
+ Proxy.new(25, 2, 10).per_page.should == 10
41
+ Proxy.new(25, 2, '10').per_page.should == 10
34
42
  end
35
43
 
36
44
  should "alias limit to per_page" do
37
- PaginationProxy.new(100, 1, 300).limit.should == 300
45
+ Proxy.new(100, 1, 300).limit.should == 300
38
46
  end
39
47
 
40
48
  should "set per_page to 25 if nil or blank" do
41
- PaginationProxy.new(25, 2).per_page.should == 25
42
- PaginationProxy.new(25, 2, '').per_page.should == 25
49
+ Proxy.new(25, 2).per_page.should == 25
50
+ Proxy.new(25, 2, '').per_page.should == 25
43
51
  end
44
52
 
45
53
  should "return correct value for current_page" do
46
- PaginationProxy.new(25, 2, 10).current_page.should == 2
47
- PaginationProxy.new(25, '2', 10).current_page.should == 2
54
+ Proxy.new(25, 2, 10).current_page.should == 2
55
+ Proxy.new(25, '2', 10).current_page.should == 2
48
56
  end
49
57
 
50
58
  should "not allow value less than 1 for current page" do
51
- PaginationProxy.new(25, -1).current_page.should == 1
59
+ Proxy.new(25, -1).current_page.should == 1
52
60
  end
53
61
 
54
62
  should "automatically calculate total_pages from total_entries and per page" do
55
- PaginationProxy.new(25, 2, 10).total_pages.should == 3
63
+ Proxy.new(25, 2, 10).total_pages.should == 3
56
64
  end
57
65
 
58
66
  should "know how many records to skip" do
59
- PaginationProxy.new(25, 2, 10).skip.should == 10
67
+ Proxy.new(25, 2, 10).skip.should == 10
60
68
  end
61
69
 
62
70
  should "alias offset to skip" do
63
- PaginationProxy.new(25, 2, 10).offset.should == 10
71
+ Proxy.new(25, 2, 10).offset.should == 10
64
72
  end
65
73
 
66
74
  should "return true for === Array" do
67
- collection = PaginationProxy.new(25, 2, 10)
75
+ collection = Proxy.new(25, 2, 10)
68
76
  collection.subject = [1, 2]
69
77
  collection.should === Array
70
78
  end
71
79
 
72
80
  context "previous_page" do
73
81
  should "be nil if current page 1" do
74
- PaginationProxy.new(25, 1, 10).previous_page.should be_nil
82
+ Proxy.new(25, 1, 10).previous_page.should be_nil
75
83
  end
76
84
 
77
85
  should "be one less than current page if current is > 1" do
78
- PaginationProxy.new(25, 2, 10).previous_page.should == 1
86
+ Proxy.new(25, 2, 10).previous_page.should == 1
79
87
  end
80
88
  end
81
89
 
82
90
  context "next_page" do
83
91
  should "be nil if current page is last page" do
84
- PaginationProxy.new(25, 3, 10).next_page.should be_nil
92
+ Proxy.new(25, 3, 10).next_page.should be_nil
85
93
  end
86
94
 
87
95
  should "work for any page that is not last" do
88
- PaginationProxy.new(25, 1, 10).next_page.should == 2
89
- PaginationProxy.new(25, 2, 10).next_page.should == 3
96
+ Proxy.new(25, 1, 10).next_page.should == 2
97
+ Proxy.new(25, 2, 10).next_page.should == 3
90
98
  end
91
99
  end
92
100
 
93
101
  context "previous_page" do
94
102
  should "be nil if current page is first page" do
95
- PaginationProxy.new(25, 1, 10).previous_page.should be_nil
103
+ Proxy.new(25, 1, 10).previous_page.should be_nil
96
104
  end
97
105
 
98
106
  should "work for any page other than first" do
99
- PaginationProxy.new(25, 2, 10).previous_page.should == 1
100
- PaginationProxy.new(25, 3, 10).previous_page.should == 2
107
+ Proxy.new(25, 2, 10).previous_page.should == 1
108
+ Proxy.new(25, 3, 10).previous_page.should == 2
101
109
  end
102
110
  end
103
111
 
104
112
  context "out_of_bounds?" do
105
113
  should "be true if current_page is greater than total_pages" do
106
- PaginationProxy.new(25, 10, 4).out_of_bounds?.should be_true
114
+ Proxy.new(25, 10, 4).out_of_bounds?.should be_true
107
115
  end
108
116
 
109
117
  should "be false if current_page is less than total_pages" do
110
- PaginationProxy.new(25, 10, 1).out_of_bounds?.should be_false
111
- PaginationProxy.new(25, 2, 10).out_of_bounds?.should be_false
118
+ Proxy.new(25, 10, 1).out_of_bounds?.should be_false
119
+ Proxy.new(25, 2, 10).out_of_bounds?.should be_false
112
120
  end
113
121
 
114
122
  should "be false if current_page is equal to total_pages" do
115
- PaginationProxy.new(25, 3, 10).out_of_bounds?.should be_false
123
+ Proxy.new(25, 3, 10).out_of_bounds?.should be_false
116
124
  end
117
125
  end
118
- end # end of pagination proxy
119
- end # end of test case
126
+ end
127
+ end
@@ -0,0 +1,50 @@
1
+ require 'test_helper'
2
+
3
+ module MyPlugin
4
+ def self.configure(model)
5
+ model.class_eval { attr_accessor :from_configure }
6
+ end
7
+
8
+ module ClassMethods
9
+ def class_foo
10
+ 'class_foo'
11
+ end
12
+ end
13
+
14
+ module InstanceMethods
15
+ def instance_foo
16
+ 'instance_foo'
17
+ end
18
+ end
19
+ end
20
+
21
+ class PluginsTest < Test::Unit::TestCase
22
+ context "plugin" do
23
+ setup do
24
+ @document = Class.new do
25
+ extend MongoMapper::Plugins
26
+ plugin MyPlugin
27
+ end
28
+ end
29
+
30
+ should "include instance methods" do
31
+ @document.new.instance_foo.should == 'instance_foo'
32
+ end
33
+
34
+ should "extend class methods" do
35
+ @document.class_foo.should == 'class_foo'
36
+ end
37
+
38
+ should "pass model to configure" do
39
+ @document.new.should respond_to(:from_configure)
40
+ end
41
+
42
+ should "default plugins to empty array" do
43
+ Class.new { extend MongoMapper::Plugins }.plugins.should == []
44
+ end
45
+
46
+ should "add plugin to plugins" do
47
+ @document.plugins.should include(MyPlugin)
48
+ end
49
+ end
50
+ end
@@ -1,29 +1,29 @@
1
1
  require 'test_helper'
2
2
  require 'models'
3
3
 
4
- class FinderOptionsTest < Test::Unit::TestCase
4
+ class QueryTest < Test::Unit::TestCase
5
5
  include MongoMapper
6
6
 
7
7
  should "raise error if provided something other than a hash" do
8
- lambda { FinderOptions.new(Room) }.should raise_error(ArgumentError)
9
- lambda { FinderOptions.new(Room, 1) }.should raise_error(ArgumentError)
8
+ lambda { Query.new(Room) }.should raise_error(ArgumentError)
9
+ lambda { Query.new(Room, 1) }.should raise_error(ArgumentError)
10
10
  end
11
11
 
12
12
  should "symbolize the keys of the hash provided" do
13
- FinderOptions.new(Room, 'offset' => 1).options.keys.map do |key|
13
+ Query.new(Room, 'offset' => 1).options.keys.map do |key|
14
14
  key.should be_instance_of(Symbol)
15
15
  end
16
16
  end
17
17
 
18
18
  context "Converting conditions to criteria" do
19
19
  should "not add _type to query if model does not have superclass that is single collection inherited" do
20
- FinderOptions.new(Message, :foo => 'bar').criteria.should == {
20
+ Query.new(Message, :foo => 'bar').criteria.should == {
21
21
  :foo => 'bar'
22
22
  }
23
23
  end
24
24
 
25
25
  should "not add _type to nested conditions" do
26
- FinderOptions.new(Enter, :foo => 'bar', :age => {'$gt' => 21}).criteria.should == {
26
+ Query.new(Enter, :foo => 'bar', :age => {'$gt' => 21}).criteria.should == {
27
27
  :foo => 'bar',
28
28
  :age => {'$gt' => 21},
29
29
  :_type => 'Enter'
@@ -31,26 +31,32 @@ class FinderOptionsTest < Test::Unit::TestCase
31
31
  end
32
32
 
33
33
  should "automatically add _type to query if model is single collection inherited" do
34
- FinderOptions.new(Enter, :foo => 'bar').criteria.should == {
34
+ Query.new(Enter, :foo => 'bar').criteria.should == {
35
35
  :foo => 'bar',
36
36
  :_type => 'Enter'
37
37
  }
38
38
  end
39
39
 
40
- %w{gt lt gte lte ne in nin mod size where exists}.each do |operator|
40
+ %w{gt lt gte lte ne in nin mod all size where exists}.each do |operator|
41
41
  should "convert #{operator} conditions" do
42
- FinderOptions.new(Room, :age.send(operator) => 21).criteria.should == {
42
+ Query.new(Room, :age.send(operator) => 21).criteria.should == {
43
43
  :age => {"$#{operator}" => 21}
44
44
  }
45
45
  end
46
46
  end
47
47
 
48
+ should "normalize value when using symbol operators" do
49
+ time = Time.now.in_time_zone('Indiana (East)')
50
+ criteria = Query.new(Room, :created_at.gt => time).criteria
51
+ criteria[:created_at]['$gt'].should be_utc
52
+ end
53
+
48
54
  should "work with simple criteria" do
49
- FinderOptions.new(Room, :foo => 'bar').criteria.should == {
55
+ Query.new(Room, :foo => 'bar').criteria.should == {
50
56
  :foo => 'bar'
51
57
  }
52
58
 
53
- FinderOptions.new(Room, :foo => 'bar', :baz => 'wick').criteria.should == {
59
+ Query.new(Room, :foo => 'bar', :baz => 'wick').criteria.should == {
54
60
  :foo => 'bar',
55
61
  :baz => 'wick'
56
62
  }
@@ -58,71 +64,71 @@ class FinderOptionsTest < Test::Unit::TestCase
58
64
 
59
65
  should "convert id to _id" do
60
66
  id = Mongo::ObjectID.new
61
- FinderOptions.new(Room, :id => id).criteria.should == {:_id => id}
67
+ Query.new(Room, :id => id).criteria.should == {:_id => id}
62
68
  end
63
69
 
64
70
  should "convert id with symbol operator to _id with modifier" do
65
71
  id = Mongo::ObjectID.new
66
- FinderOptions.new(Room, :id.ne => id).criteria.should == {
72
+ Query.new(Room, :id.ne => id).criteria.should == {
67
73
  :_id => {'$ne' => id}
68
74
  }
69
75
  end
70
76
 
71
77
  should "make sure that _id's are object ids" do
72
78
  id = Mongo::ObjectID.new
73
- FinderOptions.new(Room, :_id => id.to_s).criteria.should == {:_id => id}
79
+ Query.new(Room, :_id => id.to_s).criteria.should == {:_id => id}
74
80
  end
75
81
 
76
82
  should "work fine with _id's that are object ids" do
77
83
  id = Mongo::ObjectID.new
78
- FinderOptions.new(Room, :_id => id).criteria.should == {:_id => id}
84
+ Query.new(Room, :_id => id).criteria.should == {:_id => id}
79
85
  end
80
86
 
81
87
  should "make sure other object id typed keys get converted" do
82
88
  id = Mongo::ObjectID.new
83
- FinderOptions.new(Message, :room_id => id.to_s).criteria.should == {:room_id => id}
89
+ Query.new(Message, :room_id => id.to_s).criteria.should == {:room_id => id}
84
90
  end
85
91
 
86
92
  should "work fine with object ids for object id typed keys" do
87
93
  id = Mongo::ObjectID.new
88
- FinderOptions.new(Message, :room_id => id).criteria.should == {:room_id => id}
94
+ Query.new(Message, :room_id => id).criteria.should == {:room_id => id}
89
95
  end
90
96
 
91
97
  should "convert times to utc if they aren't already" do
92
98
  time = Time.now.in_time_zone('Indiana (East)')
93
- criteria = FinderOptions.new(Room, :created_at => time).criteria
99
+ criteria = Query.new(Room, :created_at => time).criteria
94
100
  criteria[:created_at].utc?.should be_true
95
101
  end
96
102
 
97
103
  should "not funk with times already in utc" do
98
104
  time = Time.now.utc
99
- criteria = FinderOptions.new(Room, :created_at => time).criteria
105
+ criteria = Query.new(Room, :created_at => time).criteria
100
106
  criteria[:created_at].utc?.should be_true
101
107
  criteria[:created_at].should == time
102
108
  end
103
109
 
104
110
  should "use $in for arrays" do
105
- FinderOptions.new(Room, :foo => [1,2,3]).criteria.should == {
111
+ Query.new(Room, :foo => [1,2,3]).criteria.should == {
106
112
  :foo => {'$in' => [1,2,3]}
107
113
  }
108
114
  end
109
115
 
110
116
  should "not use $in for arrays if already using array operator" do
111
- FinderOptions.new(Room, :foo => {'$all' => [1,2,3]}).criteria.should == {
117
+ Query.new(Room, :foo => {'$all' => [1,2,3]}).criteria.should == {
112
118
  :foo => {'$all' => [1,2,3]}
113
119
  }
114
120
 
115
- FinderOptions.new(Room, :foo => {'$any' => [1,2,3]}).criteria.should == {
121
+ Query.new(Room, :foo => {'$any' => [1,2,3]}).criteria.should == {
116
122
  :foo => {'$any' => [1,2,3]}
117
123
  }
118
124
  end
119
125
 
120
126
  should "work arbitrarily deep" do
121
- FinderOptions.new(Room, :foo => {:bar => [1,2,3]}).criteria.should == {
127
+ Query.new(Room, :foo => {:bar => [1,2,3]}).criteria.should == {
122
128
  :foo => {:bar => {'$in' => [1,2,3]}}
123
129
  }
124
130
 
125
- FinderOptions.new(Room, :foo => {:bar => {'$any' => [1,2,3]}}).criteria.should == {
131
+ Query.new(Room, :foo => {:bar => {'$any' => [1,2,3]}}).criteria.should == {
126
132
  :foo => {:bar => {'$any' => [1,2,3]}}
127
133
  }
128
134
  end
@@ -131,175 +137,179 @@ class FinderOptionsTest < Test::Unit::TestCase
131
137
  context "ordering" do
132
138
  should "single field with ascending direction" do
133
139
  sort = [['foo', 1]]
134
- FinderOptions.new(Room, :order => 'foo asc').options[:sort].should == sort
135
- FinderOptions.new(Room, :order => 'foo ASC').options[:sort].should == sort
140
+ Query.new(Room, :order => 'foo asc').options[:sort].should == sort
141
+ Query.new(Room, :order => 'foo ASC').options[:sort].should == sort
136
142
  end
137
143
 
138
144
  should "single field with descending direction" do
139
145
  sort = [['foo', -1]]
140
- FinderOptions.new(Room, :order => 'foo desc').options[:sort].should == sort
141
- FinderOptions.new(Room, :order => 'foo DESC').options[:sort].should == sort
146
+ Query.new(Room, :order => 'foo desc').options[:sort].should == sort
147
+ Query.new(Room, :order => 'foo DESC').options[:sort].should == sort
142
148
  end
143
149
 
144
150
  should "convert order operators to mongo sort" do
145
- FinderOptions.new(Room, :order => :foo.asc).options[:sort].should == [['foo', 1]]
146
- FinderOptions.new(Room, :order => :foo.desc).options[:sort].should == [['foo', -1]]
151
+ Query.new(Room, :order => :foo.asc).options[:sort].should == [['foo', 1]]
152
+ Query.new(Room, :order => :foo.desc).options[:sort].should == [['foo', -1]]
147
153
  end
148
154
 
149
155
  should "convert array of order operators to mongo sort" do
150
- FinderOptions.new(Room, :order => [:foo.asc, :bar.desc]).options[:sort].should == [['foo', 1], ['bar', -1]]
156
+ Query.new(Room, :order => [:foo.asc, :bar.desc]).options[:sort].should == [['foo', 1], ['bar', -1]]
151
157
  end
152
158
 
153
159
  should "convert field without direction to ascending" do
154
160
  sort = [['foo', 1]]
155
- FinderOptions.new(Room, :order => 'foo').options[:sort].should == sort
161
+ Query.new(Room, :order => 'foo').options[:sort].should == sort
156
162
  end
157
163
 
158
164
  should "convert multiple fields with directions" do
159
165
  sort = [['foo', -1], ['bar', 1], ['baz', -1]]
160
- FinderOptions.new(Room, :order => 'foo desc, bar asc, baz desc').options[:sort].should == sort
166
+ Query.new(Room, :order => 'foo desc, bar asc, baz desc').options[:sort].should == sort
161
167
  end
162
168
 
163
169
  should "convert multiple fields with some missing directions" do
164
170
  sort = [['foo', -1], ['bar', 1], ['baz', 1]]
165
- FinderOptions.new(Room, :order => 'foo desc, bar, baz').options[:sort].should == sort
171
+ Query.new(Room, :order => 'foo desc, bar, baz').options[:sort].should == sort
166
172
  end
167
173
 
168
174
  should "just use sort if sort and order are present" do
169
175
  sort = [['$natural', 1]]
170
- FinderOptions.new(Room, :sort => sort, :order => 'foo asc').options[:sort].should == sort
176
+ Query.new(Room, :sort => sort, :order => 'foo asc').options[:sort].should == sort
171
177
  end
172
178
 
173
179
  should "convert natural in order to proper" do
174
180
  sort = [['$natural', 1]]
175
- FinderOptions.new(Room, :order => '$natural asc').options[:sort].should == sort
181
+ Query.new(Room, :order => '$natural asc').options[:sort].should == sort
176
182
  sort = [['$natural', -1]]
177
- FinderOptions.new(Room, :order => '$natural desc').options[:sort].should == sort
183
+ Query.new(Room, :order => '$natural desc').options[:sort].should == sort
178
184
  end
179
185
 
180
186
  should "work for natural order ascending" do
181
- FinderOptions.new(Room, :sort => {'$natural' => 1}).options[:sort]['$natural'].should == 1
187
+ Query.new(Room, :sort => {'$natural' => 1}).options[:sort]['$natural'].should == 1
182
188
  end
183
189
 
184
190
  should "work for natural order descending" do
185
- FinderOptions.new(Room, :sort => {'$natural' => -1}).options[:sort]['$natural'].should == -1
191
+ Query.new(Room, :sort => {'$natural' => -1}).options[:sort]['$natural'].should == -1
186
192
  end
187
193
  end
188
194
 
189
195
  context "skip" do
190
196
  should "default to 0" do
191
- FinderOptions.new(Room, {}).options[:skip].should == 0
197
+ Query.new(Room, {}).options[:skip].should == 0
192
198
  end
193
199
 
194
200
  should "use skip provided" do
195
- FinderOptions.new(Room, :skip => 2).options[:skip].should == 2
201
+ Query.new(Room, :skip => 2).options[:skip].should == 2
196
202
  end
197
203
 
198
204
  should "covert string to integer" do
199
- FinderOptions.new(Room, :skip => '2').options[:skip].should == 2
205
+ Query.new(Room, :skip => '2').options[:skip].should == 2
200
206
  end
201
207
 
202
208
  should "convert offset to skip" do
203
- FinderOptions.new(Room, :offset => 1).options[:skip].should == 1
209
+ Query.new(Room, :offset => 1).options[:skip].should == 1
204
210
  end
205
211
  end
206
212
 
207
213
  context "limit" do
208
214
  should "default to 0" do
209
- FinderOptions.new(Room, {}).options[:limit].should == 0
215
+ Query.new(Room, {}).options[:limit].should == 0
210
216
  end
211
217
 
212
218
  should "use limit provided" do
213
- FinderOptions.new(Room, :limit => 2).options[:limit].should == 2
219
+ Query.new(Room, :limit => 2).options[:limit].should == 2
214
220
  end
215
221
 
216
222
  should "covert string to integer" do
217
- FinderOptions.new(Room, :limit => '2').options[:limit].should == 2
223
+ Query.new(Room, :limit => '2').options[:limit].should == 2
218
224
  end
219
225
  end
220
226
 
221
227
  context "fields" do
222
228
  should "default to nil" do
223
- FinderOptions.new(Room, {}).options[:fields].should be(nil)
229
+ Query.new(Room, {}).options[:fields].should be(nil)
224
230
  end
225
231
 
226
232
  should "be converted to nil if empty string" do
227
- FinderOptions.new(Room, :fields => '').options[:fields].should be(nil)
233
+ Query.new(Room, :fields => '').options[:fields].should be(nil)
228
234
  end
229
235
 
230
236
  should "be converted to nil if []" do
231
- FinderOptions.new(Room, :fields => []).options[:fields].should be(nil)
237
+ Query.new(Room, :fields => []).options[:fields].should be(nil)
232
238
  end
233
239
 
234
240
  should "should work with array" do
235
- FinderOptions.new(Room, {:fields => %w(a b)}).options[:fields].should == %w(a b)
241
+ Query.new(Room, {:fields => %w(a b)}).options[:fields].should == %w(a b)
236
242
  end
237
243
 
238
244
  should "convert comma separated list to array" do
239
- FinderOptions.new(Room, {:fields => 'a, b'}).options[:fields].should == %w(a b)
245
+ Query.new(Room, {:fields => 'a, b'}).options[:fields].should == %w(a b)
240
246
  end
241
247
 
242
248
  should "also work as select" do
243
- FinderOptions.new(Room, :select => %w(a b)).options[:fields].should == %w(a b)
249
+ Query.new(Room, :select => %w(a b)).options[:fields].should == %w(a b)
250
+ end
251
+
252
+ should "also work with select as array of symbols" do
253
+ Query.new(Room, :select => [:a, :b]).options[:fields].should == [:a, :b]
244
254
  end
245
255
  end
246
256
 
247
257
  context "Condition auto-detection" do
248
258
  should "know :conditions are criteria" do
249
- finder = FinderOptions.new(Room, :conditions => {:foo => 'bar'})
259
+ finder = Query.new(Room, :conditions => {:foo => 'bar'})
250
260
  finder.criteria.should == {:foo => 'bar'}
251
261
  finder.options.keys.should_not include(:conditions)
252
262
  end
253
263
 
254
264
  should "know fields is an option" do
255
- finder = FinderOptions.new(Room, :fields => ['foo'])
265
+ finder = Query.new(Room, :fields => ['foo'])
256
266
  finder.options[:fields].should == ['foo']
257
267
  finder.criteria.keys.should_not include(:fields)
258
268
  end
259
269
 
260
270
  # select gets converted to fields so just checking keys
261
271
  should "know select is an option" do
262
- finder = FinderOptions.new(Room, :select => 'foo')
272
+ finder = Query.new(Room, :select => 'foo')
263
273
  finder.options.keys.should include(:sort)
264
274
  finder.criteria.keys.should_not include(:select)
265
275
  finder.criteria.keys.should_not include(:fields)
266
276
  end
267
277
 
268
278
  should "know skip is an option" do
269
- finder = FinderOptions.new(Room, :skip => 10)
279
+ finder = Query.new(Room, :skip => 10)
270
280
  finder.options[:skip].should == 10
271
281
  finder.criteria.keys.should_not include(:skip)
272
282
  end
273
283
 
274
284
  # offset gets converted to skip so just checking keys
275
285
  should "know offset is an option" do
276
- finder = FinderOptions.new(Room, :offset => 10)
286
+ finder = Query.new(Room, :offset => 10)
277
287
  finder.options.keys.should include(:skip)
278
288
  finder.criteria.keys.should_not include(:skip)
279
289
  finder.criteria.keys.should_not include(:offset)
280
290
  end
281
291
 
282
292
  should "know limit is an option" do
283
- finder = FinderOptions.new(Room, :limit => 10)
293
+ finder = Query.new(Room, :limit => 10)
284
294
  finder.options[:limit].should == 10
285
295
  finder.criteria.keys.should_not include(:limit)
286
296
  end
287
297
 
288
298
  should "know sort is an option" do
289
- finder = FinderOptions.new(Room, :sort => [['foo', 1]])
299
+ finder = Query.new(Room, :sort => [['foo', 1]])
290
300
  finder.options[:sort].should == [['foo', 1]]
291
301
  finder.criteria.keys.should_not include(:sort)
292
302
  end
293
303
 
294
304
  # order gets converted to sort so just checking keys
295
305
  should "know order is an option" do
296
- finder = FinderOptions.new(Room, :order => 'foo')
306
+ finder = Query.new(Room, :order => 'foo')
297
307
  finder.options.keys.should include(:sort)
298
308
  finder.criteria.keys.should_not include(:sort)
299
309
  end
300
310
 
301
311
  should "work with full range of things" do
302
- finder_options = FinderOptions.new(Room, {
312
+ query_options = Query.new(Room, {
303
313
  :foo => 'bar',
304
314
  :baz => true,
305
315
  :sort => [['foo', 1]],
@@ -308,12 +318,12 @@ class FinderOptionsTest < Test::Unit::TestCase
308
318
  :skip => 10,
309
319
  })
310
320
 
311
- finder_options.criteria.should == {
321
+ query_options.criteria.should == {
312
322
  :foo => 'bar',
313
323
  :baz => true,
314
324
  }
315
325
 
316
- finder_options.options.should == {
326
+ query_options.options.should == {
317
327
  :sort => [['foo', 1]],
318
328
  :fields => ['foo', 'baz'],
319
329
  :limit => 10,
@@ -321,5 +331,4 @@ class FinderOptionsTest < Test::Unit::TestCase
321
331
  }
322
332
  end
323
333
  end
324
-
325
- end # FinderOptionsTest
334
+ end