jmonteiro-mongo_mapper 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. data/.gitignore +10 -0
  2. data/LICENSE +20 -0
  3. data/README.rdoc +38 -0
  4. data/Rakefile +55 -0
  5. data/VERSION +1 -0
  6. data/bin/mmconsole +60 -0
  7. data/jmonteiro-mongo_mapper.gemspec +195 -0
  8. data/lib/mongo_mapper.rb +128 -0
  9. data/lib/mongo_mapper/descendant_appends.rb +44 -0
  10. data/lib/mongo_mapper/document.rb +402 -0
  11. data/lib/mongo_mapper/dynamic_finder.rb +74 -0
  12. data/lib/mongo_mapper/embedded_document.rb +61 -0
  13. data/lib/mongo_mapper/finder_options.rb +127 -0
  14. data/lib/mongo_mapper/plugins.rb +19 -0
  15. data/lib/mongo_mapper/plugins/associations.rb +104 -0
  16. data/lib/mongo_mapper/plugins/associations/base.rb +121 -0
  17. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +28 -0
  18. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +23 -0
  19. data/lib/mongo_mapper/plugins/associations/collection.rb +21 -0
  20. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +49 -0
  21. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +139 -0
  22. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
  23. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +117 -0
  24. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +31 -0
  25. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +23 -0
  26. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +13 -0
  27. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +66 -0
  28. data/lib/mongo_mapper/plugins/associations/proxy.rb +118 -0
  29. data/lib/mongo_mapper/plugins/callbacks.rb +65 -0
  30. data/lib/mongo_mapper/plugins/clone.rb +13 -0
  31. data/lib/mongo_mapper/plugins/descendants.rb +16 -0
  32. data/lib/mongo_mapper/plugins/dirty.rb +119 -0
  33. data/lib/mongo_mapper/plugins/equality.rb +11 -0
  34. data/lib/mongo_mapper/plugins/identity_map.rb +66 -0
  35. data/lib/mongo_mapper/plugins/inspect.rb +14 -0
  36. data/lib/mongo_mapper/plugins/keys.rb +295 -0
  37. data/lib/mongo_mapper/plugins/logger.rb +17 -0
  38. data/lib/mongo_mapper/plugins/pagination.rb +85 -0
  39. data/lib/mongo_mapper/plugins/protected.rb +31 -0
  40. data/lib/mongo_mapper/plugins/rails.rb +80 -0
  41. data/lib/mongo_mapper/plugins/serialization.rb +109 -0
  42. data/lib/mongo_mapper/plugins/validations.rb +48 -0
  43. data/lib/mongo_mapper/support.rb +213 -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 +93 -0
  49. data/test/functional/associations/test_in_array_proxy.rb +309 -0
  50. data/test/functional/associations/test_many_documents_as_proxy.rb +246 -0
  51. data/test/functional/associations/test_many_documents_proxy.rb +437 -0
  52. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +175 -0
  53. data/test/functional/associations/test_many_embedded_proxy.rb +216 -0
  54. data/test/functional/associations/test_many_polymorphic_proxy.rb +340 -0
  55. data/test/functional/associations/test_one_proxy.rb +149 -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 +156 -0
  60. data/test/functional/test_document.rb +1171 -0
  61. data/test/functional/test_embedded_document.rb +125 -0
  62. data/test/functional/test_identity_map.rb +233 -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 +41 -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 +103 -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 +203 -0
  78. data/test/unit/test_dynamic_finder.rb +125 -0
  79. data/test/unit/test_embedded_document.rb +628 -0
  80. data/test/unit/test_finder_options.rb +325 -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 +42 -0
  85. data/test/unit/test_rails.rb +139 -0
  86. data/test/unit/test_rails_compatibility.rb +42 -0
  87. data/test/unit/test_serialization.rb +51 -0
  88. data/test/unit/test_support.rb +350 -0
  89. data/test/unit/test_time_zones.rb +39 -0
  90. data/test/unit/test_validations.rb +492 -0
  91. metadata +260 -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,42 @@
1
+ require 'test_helper'
2
+
3
+ module MyPlugin
4
+ module ClassMethods
5
+ def class_foo
6
+ 'class_foo'
7
+ end
8
+ end
9
+
10
+ module InstanceMethods
11
+ def instance_foo
12
+ 'instance_foo'
13
+ end
14
+ end
15
+ end
16
+
17
+ class PluginsTest < Test::Unit::TestCase
18
+ context "plugin" do
19
+ setup do
20
+ @document = Class.new do
21
+ extend MongoMapper::Plugins
22
+ plugin MyPlugin
23
+ end
24
+ end
25
+
26
+ should "include instance methods" do
27
+ @document.new.instance_foo.should == 'instance_foo'
28
+ end
29
+
30
+ should "extend class methods" do
31
+ @document.class_foo.should == 'class_foo'
32
+ end
33
+
34
+ should "default plugins to empty array" do
35
+ Class.new { extend MongoMapper::Plugins }.plugins.should == []
36
+ end
37
+
38
+ should "add plugin to plugins" do
39
+ @document.plugins.should include(MyPlugin)
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,139 @@
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 self_and_descendants" do
25
+ @klass.self_and_descendants.should == [@klass]
26
+ end
27
+
28
+ should "implement human_name" do
29
+ @klass.human_name.should == 'Post'
30
+ end
31
+
32
+ should "implement human_attribute_name" do
33
+ @klass.human_attribute_name(:foo).should == 'Foo'
34
+ end
35
+ end
36
+
37
+ context "Instance methods" do
38
+ setup do
39
+ @klass.class_eval do
40
+ def bar=(value)
41
+ write_attribute(:foo, value)
42
+ end
43
+
44
+ def bar_before_typecast
45
+ read_attribute_before_typecast(:foo)
46
+ end
47
+
48
+ def bar
49
+ read_attribute(:foo)
50
+ end
51
+ end
52
+ end
53
+
54
+ should "alias new_record? to new?" do
55
+ @klass.new.should be_new_record
56
+ end
57
+
58
+ should "be able to read key with read_attribute" do
59
+ @klass.new(:foo => 'Bar').bar.should == 'Bar'
60
+ end
61
+
62
+ should "be able to read key before typecast with read_attribute_before_typecast" do
63
+ @klass.new(:foo => 21).bar_before_typecast.should == 21
64
+ @klass.new(:foo => 21).bar.should == '21'
65
+ end
66
+
67
+ should "be able to write key with write_attribute" do
68
+ @klass.new(:bar => 'Setting Foo').foo.should == 'Setting Foo'
69
+ end
70
+ end
71
+ end
72
+
73
+ context "EmbeddedDocument" do
74
+ setup do
75
+ @klass = EDoc('Post') { key :foo, String }
76
+ end
77
+
78
+ context "Class methods" do
79
+ should "alias has_many to many" do
80
+ @klass.should respond_to(:has_many)
81
+ end
82
+
83
+ should "alias has_one to one" do
84
+ @klass.should respond_to(:has_one)
85
+ end
86
+
87
+ should "have column names" do
88
+ @klass.column_names.sort.should == ['_id', 'foo']
89
+ end
90
+
91
+ should "implement self_and_descendants" do
92
+ @klass.self_and_descendants.should == [@klass]
93
+ end
94
+
95
+ should "implement human_name" do
96
+ @klass.human_name.should == 'Post'
97
+ end
98
+
99
+ should "implement human_attribute_name" do
100
+ @klass.human_attribute_name(:foo).should == 'Foo'
101
+ end
102
+ end
103
+
104
+ context "Instance methods" do
105
+ setup do
106
+ @klass.class_eval do
107
+ def bar=(value)
108
+ write_attribute(:foo, value)
109
+ end
110
+
111
+ def bar_before_typecast
112
+ read_attribute_before_typecast(:foo)
113
+ end
114
+
115
+ def bar
116
+ read_attribute(:foo)
117
+ end
118
+ end
119
+ end
120
+
121
+ should "alias new_record? to new?" do
122
+ @klass.new.should be_new_record
123
+ end
124
+
125
+ should "be able to read key with read_attribute" do
126
+ @klass.new(:foo => 'Bar').bar.should == 'Bar'
127
+ end
128
+
129
+ should "be able to read key before typecast with read_attribute_before_typecast" do
130
+ @klass.new(:foo => 21).bar_before_typecast.should == 21
131
+ @klass.new(:foo => 21).bar.should == '21'
132
+ end
133
+
134
+ should "be able to write key with write_attribute" do
135
+ @klass.new(:bar => 'Setting Foo').foo.should == 'Setting Foo'
136
+ end
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,42 @@
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
+ end
42
+ 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