drogus-mongo_mapper 0.6.10

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 (91) hide show
  1. data/.gitignore +10 -0
  2. data/LICENSE +20 -0
  3. data/README.rdoc +29 -0
  4. data/Rakefile +55 -0
  5. data/VERSION +1 -0
  6. data/bin/mmconsole +60 -0
  7. data/lib/mongo_mapper.rb +131 -0
  8. data/lib/mongo_mapper/document.rb +417 -0
  9. data/lib/mongo_mapper/embedded_document.rb +55 -0
  10. data/lib/mongo_mapper/finder_options.rb +127 -0
  11. data/lib/mongo_mapper/plugins.rb +30 -0
  12. data/lib/mongo_mapper/plugins/associations.rb +104 -0
  13. data/lib/mongo_mapper/plugins/associations/base.rb +121 -0
  14. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +30 -0
  15. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +25 -0
  16. data/lib/mongo_mapper/plugins/associations/collection.rb +21 -0
  17. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +50 -0
  18. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +139 -0
  19. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
  20. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +117 -0
  21. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +31 -0
  22. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +23 -0
  23. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +13 -0
  24. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +68 -0
  25. data/lib/mongo_mapper/plugins/associations/proxy.rb +118 -0
  26. data/lib/mongo_mapper/plugins/callbacks.rb +134 -0
  27. data/lib/mongo_mapper/plugins/clone.rb +13 -0
  28. data/lib/mongo_mapper/plugins/descendants.rb +16 -0
  29. data/lib/mongo_mapper/plugins/dirty.rb +119 -0
  30. data/lib/mongo_mapper/plugins/equality.rb +23 -0
  31. data/lib/mongo_mapper/plugins/identity_map.rb +122 -0
  32. data/lib/mongo_mapper/plugins/inspect.rb +14 -0
  33. data/lib/mongo_mapper/plugins/keys.rb +324 -0
  34. data/lib/mongo_mapper/plugins/logger.rb +17 -0
  35. data/lib/mongo_mapper/plugins/pagination.rb +85 -0
  36. data/lib/mongo_mapper/plugins/protected.rb +45 -0
  37. data/lib/mongo_mapper/plugins/rails.rb +45 -0
  38. data/lib/mongo_mapper/plugins/serialization.rb +105 -0
  39. data/lib/mongo_mapper/plugins/validations.rb +57 -0
  40. data/lib/mongo_mapper/support.rb +217 -0
  41. data/lib/mongo_mapper/support/descendant_appends.rb +46 -0
  42. data/lib/mongo_mapper/support/find.rb +77 -0
  43. data/mongo_mapper.gemspec +195 -0
  44. data/performance/read_write.rb +52 -0
  45. data/specs.watchr +51 -0
  46. data/test/NOTE_ON_TESTING +1 -0
  47. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +63 -0
  48. data/test/functional/associations/test_belongs_to_proxy.rb +101 -0
  49. data/test/functional/associations/test_in_array_proxy.rb +309 -0
  50. data/test/functional/associations/test_many_documents_as_proxy.rb +229 -0
  51. data/test/functional/associations/test_many_documents_proxy.rb +431 -0
  52. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +176 -0
  53. data/test/functional/associations/test_many_embedded_proxy.rb +256 -0
  54. data/test/functional/associations/test_many_polymorphic_proxy.rb +302 -0
  55. data/test/functional/associations/test_one_proxy.rb +161 -0
  56. data/test/functional/test_associations.rb +44 -0
  57. data/test/functional/test_binary.rb +27 -0
  58. data/test/functional/test_callbacks.rb +81 -0
  59. data/test/functional/test_dirty.rb +163 -0
  60. data/test/functional/test_document.rb +1264 -0
  61. data/test/functional/test_embedded_document.rb +125 -0
  62. data/test/functional/test_identity_map.rb +508 -0
  63. data/test/functional/test_logger.rb +20 -0
  64. data/test/functional/test_modifiers.rb +252 -0
  65. data/test/functional/test_pagination.rb +93 -0
  66. data/test/functional/test_protected.rb +155 -0
  67. data/test/functional/test_string_id_compatibility.rb +67 -0
  68. data/test/functional/test_validations.rb +329 -0
  69. data/test/models.rb +232 -0
  70. data/test/support/custom_matchers.rb +55 -0
  71. data/test/support/timing.rb +16 -0
  72. data/test/test_helper.rb +60 -0
  73. data/test/unit/associations/test_base.rb +207 -0
  74. data/test/unit/associations/test_proxy.rb +105 -0
  75. data/test/unit/serializers/test_json_serializer.rb +189 -0
  76. data/test/unit/test_descendant_appends.rb +71 -0
  77. data/test/unit/test_document.rb +231 -0
  78. data/test/unit/test_dynamic_finder.rb +123 -0
  79. data/test/unit/test_embedded_document.rb +663 -0
  80. data/test/unit/test_finder_options.rb +329 -0
  81. data/test/unit/test_keys.rb +169 -0
  82. data/test/unit/test_mongo_mapper.rb +65 -0
  83. data/test/unit/test_pagination.rb +127 -0
  84. data/test/unit/test_plugins.rb +50 -0
  85. data/test/unit/test_rails.rb +123 -0
  86. data/test/unit/test_rails_compatibility.rb +52 -0
  87. data/test/unit/test_serialization.rb +51 -0
  88. data/test/unit/test_support.rb +354 -0
  89. data/test/unit/test_time_zones.rb +39 -0
  90. data/test/unit/test_validations.rb +544 -0
  91. metadata +290 -0
@@ -0,0 +1,65 @@
1
+ require 'test_helper'
2
+
3
+ class Address; end
4
+
5
+ class MongoMapperTest < Test::Unit::TestCase
6
+ should "be able to write and read connection" do
7
+ conn = Mongo::Connection.new
8
+ MongoMapper.connection = conn
9
+ MongoMapper.connection.should == conn
10
+ end
11
+
12
+ should "default connection to new mongo ruby driver" do
13
+ MongoMapper.connection = nil
14
+ MongoMapper.connection.should be_instance_of(Mongo::Connection)
15
+ end
16
+
17
+ should "be able to write and read default database" do
18
+ MongoMapper.database = 'test'
19
+ MongoMapper.database.should be_instance_of(Mongo::DB)
20
+ MongoMapper.database.name.should == 'test'
21
+ end
22
+
23
+ should "have document not found error" do
24
+ lambda {
25
+ MongoMapper::DocumentNotFound
26
+ }.should_not raise_error
27
+ end
28
+
29
+ context "use_time_zone?" do
30
+ should "be true if Time.zone set" do
31
+ Time.zone = 'Hawaii'
32
+ MongoMapper.use_time_zone?.should be_true
33
+ Time.zone = nil
34
+ end
35
+
36
+ should "be false if Time.zone not set" do
37
+ MongoMapper.use_time_zone?.should be_false
38
+ end
39
+ end
40
+
41
+ context "time_class" do
42
+ should "be Time.zone if using time zones" do
43
+ Time.zone = 'Hawaii'
44
+ MongoMapper.time_class.should == Time.zone
45
+ Time.zone = nil
46
+ end
47
+
48
+ should "be Time if not using time zones" do
49
+ MongoMapper.time_class.should == Time
50
+ end
51
+ end
52
+
53
+ context "normalize_object_id" do
54
+ should "turn string into object id" do
55
+ id = Mongo::ObjectID.new
56
+ MongoMapper.normalize_object_id(id.to_s).should == id
57
+ end
58
+
59
+ should "leave object id alone" do
60
+ id = Mongo::ObjectID.new
61
+ MongoMapper.normalize_object_id(id).should == id
62
+ end
63
+ end
64
+
65
+ end
@@ -0,0 +1,127 @@
1
+ require 'test_helper'
2
+
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
+
12
+ context "Pagination proxy" do
13
+ include MongoMapper::Plugins::Pagination
14
+
15
+ should "should have accessors for subject" do
16
+ subject = [1,2,3,4,5]
17
+ collection = PaginationProxy.new(25, 2)
18
+ collection.subject = subject
19
+ collection.subject.should == subject
20
+ end
21
+
22
+ should "delegate any methods not defined to the subject" do
23
+ subject = [1,2,3,4,5]
24
+ collection = PaginationProxy.new(25, 2, 10)
25
+ collection.subject = subject
26
+ collection.size.should == 5
27
+ collection.each_with_index do |value, i|
28
+ value.should == subject[i]
29
+ end
30
+ collection[0..2].should == [1,2,3]
31
+ collection.class.should == Array
32
+ end
33
+
34
+ should "return correct value for total_entries" do
35
+ PaginationProxy.new(25, 2, 10).total_entries.should == 25
36
+ PaginationProxy.new('25', 2, 10).total_entries.should == 25
37
+ end
38
+
39
+ should "return correct value for per_page" do
40
+ PaginationProxy.new(25, 2, 10).per_page.should == 10
41
+ PaginationProxy.new(25, 2, '10').per_page.should == 10
42
+ end
43
+
44
+ should "alias limit to per_page" do
45
+ PaginationProxy.new(100, 1, 300).limit.should == 300
46
+ end
47
+
48
+ should "set per_page to 25 if nil or blank" do
49
+ PaginationProxy.new(25, 2).per_page.should == 25
50
+ PaginationProxy.new(25, 2, '').per_page.should == 25
51
+ end
52
+
53
+ should "return correct value for current_page" do
54
+ PaginationProxy.new(25, 2, 10).current_page.should == 2
55
+ PaginationProxy.new(25, '2', 10).current_page.should == 2
56
+ end
57
+
58
+ should "not allow value less than 1 for current page" do
59
+ PaginationProxy.new(25, -1).current_page.should == 1
60
+ end
61
+
62
+ should "automatically calculate total_pages from total_entries and per page" do
63
+ PaginationProxy.new(25, 2, 10).total_pages.should == 3
64
+ end
65
+
66
+ should "know how many records to skip" do
67
+ PaginationProxy.new(25, 2, 10).skip.should == 10
68
+ end
69
+
70
+ should "alias offset to skip" do
71
+ PaginationProxy.new(25, 2, 10).offset.should == 10
72
+ end
73
+
74
+ should "return true for === Array" do
75
+ collection = PaginationProxy.new(25, 2, 10)
76
+ collection.subject = [1, 2]
77
+ collection.should === Array
78
+ end
79
+
80
+ context "previous_page" do
81
+ should "be nil if current page 1" do
82
+ PaginationProxy.new(25, 1, 10).previous_page.should be_nil
83
+ end
84
+
85
+ should "be one less than current page if current is > 1" do
86
+ PaginationProxy.new(25, 2, 10).previous_page.should == 1
87
+ end
88
+ end
89
+
90
+ context "next_page" do
91
+ should "be nil if current page is last page" do
92
+ PaginationProxy.new(25, 3, 10).next_page.should be_nil
93
+ end
94
+
95
+ should "work for any page that is not last" do
96
+ PaginationProxy.new(25, 1, 10).next_page.should == 2
97
+ PaginationProxy.new(25, 2, 10).next_page.should == 3
98
+ end
99
+ end
100
+
101
+ context "previous_page" do
102
+ should "be nil if current page is first page" do
103
+ PaginationProxy.new(25, 1, 10).previous_page.should be_nil
104
+ end
105
+
106
+ should "work for any page other than first" do
107
+ PaginationProxy.new(25, 2, 10).previous_page.should == 1
108
+ PaginationProxy.new(25, 3, 10).previous_page.should == 2
109
+ end
110
+ end
111
+
112
+ context "out_of_bounds?" do
113
+ should "be true if current_page is greater than total_pages" do
114
+ PaginationProxy.new(25, 10, 4).out_of_bounds?.should be_true
115
+ end
116
+
117
+ should "be false if current_page is less than total_pages" do
118
+ PaginationProxy.new(25, 10, 1).out_of_bounds?.should be_false
119
+ PaginationProxy.new(25, 2, 10).out_of_bounds?.should be_false
120
+ end
121
+
122
+ should "be false if current_page is equal to total_pages" do
123
+ PaginationProxy.new(25, 3, 10).out_of_bounds?.should be_false
124
+ end
125
+ end
126
+ end # end of pagination proxy
127
+ end # end of test case
@@ -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
@@ -0,0 +1,123 @@
1
+ require 'test_helper'
2
+
3
+ class TestRails < Test::Unit::TestCase
4
+ context "Document" do
5
+ setup do
6
+ @klass = Doc('Post') do
7
+ key :foo, String
8
+ end
9
+ end
10
+
11
+ context "Class methods" do
12
+ should "alias has_many to many" do
13
+ @klass.should respond_to(:has_many)
14
+ end
15
+
16
+ should "alias has_one to one" do
17
+ @klass.should respond_to(:has_one)
18
+ end
19
+
20
+ should "have column names" do
21
+ @klass.column_names.sort.should == ['_id', 'foo']
22
+ end
23
+
24
+ should "implement human_name" do
25
+ @klass.human_name.should == 'Post'
26
+ end
27
+ end
28
+
29
+ context "Instance methods" do
30
+ setup do
31
+ @klass.class_eval do
32
+ def bar=(value)
33
+ write_attribute(:foo, value)
34
+ end
35
+
36
+ def bar_before_typecast
37
+ read_attribute_before_typecast(:foo)
38
+ end
39
+
40
+ def bar
41
+ read_attribute(:foo)
42
+ end
43
+ end
44
+ end
45
+
46
+ should "alias new_record? to new?" do
47
+ @klass.new.should be_new_record
48
+ end
49
+
50
+ should "be able to read key with read_attribute" do
51
+ @klass.new(:foo => 'Bar').bar.should == 'Bar'
52
+ end
53
+
54
+ should "be able to read key before typecast with read_attribute_before_typecast" do
55
+ @klass.new(:foo => 21).bar_before_typecast.should == 21
56
+ @klass.new(:foo => 21).bar.should == '21'
57
+ end
58
+
59
+ should "be able to write key with write_attribute" do
60
+ @klass.new(:bar => 'Setting Foo').foo.should == 'Setting Foo'
61
+ end
62
+ end
63
+ end
64
+
65
+ context "EmbeddedDocument" do
66
+ setup do
67
+ @klass = EDoc('Post') { key :foo, String }
68
+ end
69
+
70
+ context "Class methods" do
71
+ should "alias has_many to many" do
72
+ @klass.should respond_to(:has_many)
73
+ end
74
+
75
+ should "alias has_one to one" do
76
+ @klass.should respond_to(:has_one)
77
+ end
78
+
79
+ should "have column names" do
80
+ @klass.column_names.sort.should == ['_id', 'foo']
81
+ end
82
+
83
+ should "implement human_name" do
84
+ @klass.human_name.should == 'Post'
85
+ end
86
+ end
87
+
88
+ context "Instance methods" do
89
+ setup do
90
+ @klass.class_eval do
91
+ def bar=(value)
92
+ write_attribute(:foo, value)
93
+ end
94
+
95
+ def bar_before_typecast
96
+ read_attribute_before_typecast(:foo)
97
+ end
98
+
99
+ def bar
100
+ read_attribute(:foo)
101
+ end
102
+ end
103
+ end
104
+
105
+ should "alias new_record? to new?" do
106
+ @klass.new.should be_new_record
107
+ end
108
+
109
+ should "be able to read key with read_attribute" do
110
+ @klass.new(:foo => 'Bar').bar.should == 'Bar'
111
+ end
112
+
113
+ should "be able to read key before typecast with read_attribute_before_typecast" do
114
+ @klass.new(:foo => 21).bar_before_typecast.should == 21
115
+ @klass.new(:foo => 21).bar.should == '21'
116
+ end
117
+
118
+ should "be able to write key with write_attribute" do
119
+ @klass.new(:bar => 'Setting Foo').foo.should == 'Setting Foo'
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,52 @@
1
+ require 'test_helper'
2
+
3
+ class TestRailsCompatibility < Test::Unit::TestCase
4
+ class BigStuff
5
+ include MongoMapper::Document
6
+ end
7
+
8
+ class Item
9
+ include MongoMapper::EmbeddedDocument
10
+ key :for_all, String
11
+ end
12
+
13
+ class FirstItem < Item
14
+ key :first_only, String
15
+ many :second_items
16
+ end
17
+
18
+ class SecondItem < Item
19
+ key :second_only, String
20
+ end
21
+
22
+ context "EmbeddedDocument" do
23
+ should "alias many to has_many" do
24
+ FirstItem.should respond_to(:has_many)
25
+ end
26
+
27
+ should "alias one to has_one" do
28
+ FirstItem.should respond_to(:has_one)
29
+ end
30
+
31
+ should "have column names" do
32
+ Item.column_names.sort.should == ['_id', 'for_all']
33
+ FirstItem.column_names.sort.should == ['_id', 'first_only', 'for_all']
34
+ SecondItem.column_names.sort.should == ['_id', 'for_all', 'second_only']
35
+ end
36
+
37
+ should "alias new to new_record?" do
38
+ instance = Item.new
39
+ instance.new_record?.should == instance.new?
40
+ end
41
+
42
+ should "implement human_name" do
43
+ Item.human_name.should == 'Item'
44
+ end
45
+ end
46
+
47
+ context "Document" do
48
+ should "implement human_name" do
49
+ BigStuff.human_name.should == 'Big Stuff'
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,51 @@
1
+ require 'test_helper'
2
+
3
+ class SerializationTest < Test::Unit::TestCase
4
+ def setup
5
+ @document = EDoc do
6
+ key :name, String
7
+ key :age, Integer
8
+ key :awesome, Boolean
9
+ key :preferences, Hash
10
+ key :created_at, Time
11
+ end
12
+
13
+ @instance = @document.new(
14
+ :name => 'John Doe',
15
+ :age => 25,
16
+ :awesome => true,
17
+ :preferences => {:language => 'Ruby'},
18
+ :created_at => Time.now.change(:usec => 0)
19
+ )
20
+ end
21
+
22
+ [:json].each do |format|
23
+ context format do
24
+ should "be reversable" do
25
+ serialized = @instance.send("to_#{format}")
26
+ unserialized = @document.new.send("from_#{format}", serialized)
27
+
28
+ assert_equal @instance, unserialized
29
+ end
30
+
31
+ should "allow attribute only filtering" do
32
+ serialized = @instance.send("to_#{format}", :only => [ :age, :name ])
33
+ unserialized = @document.new.send("from_#{format}", serialized)
34
+
35
+ assert_equal @instance.name, unserialized.name
36
+ assert_equal @instance.age, unserialized.age
37
+ assert ! unserialized.awesome
38
+ assert_nil unserialized.created_at
39
+ end
40
+
41
+ should "allow attribute except filtering" do
42
+ serialized = @instance.send("to_#{format}", :except => [ :age, :name ])
43
+ unserialized = @document.new.send("from_#{format}", serialized)
44
+
45
+ assert_nil unserialized.name
46
+ assert_nil unserialized.age
47
+ assert_equal @instance.awesome, unserialized.awesome
48
+ end
49
+ end
50
+ end
51
+ end