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.
- data/.gitignore +10 -0
- data/LICENSE +20 -0
- data/README.rdoc +29 -0
- data/Rakefile +55 -0
- data/VERSION +1 -0
- data/bin/mmconsole +60 -0
- data/lib/mongo_mapper.rb +131 -0
- data/lib/mongo_mapper/document.rb +417 -0
- data/lib/mongo_mapper/embedded_document.rb +55 -0
- data/lib/mongo_mapper/finder_options.rb +127 -0
- data/lib/mongo_mapper/plugins.rb +30 -0
- data/lib/mongo_mapper/plugins/associations.rb +104 -0
- data/lib/mongo_mapper/plugins/associations/base.rb +121 -0
- data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +30 -0
- data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +25 -0
- data/lib/mongo_mapper/plugins/associations/collection.rb +21 -0
- data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +50 -0
- data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +139 -0
- data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
- data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +117 -0
- data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +31 -0
- data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +23 -0
- data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +13 -0
- data/lib/mongo_mapper/plugins/associations/one_proxy.rb +68 -0
- data/lib/mongo_mapper/plugins/associations/proxy.rb +118 -0
- data/lib/mongo_mapper/plugins/callbacks.rb +134 -0
- data/lib/mongo_mapper/plugins/clone.rb +13 -0
- data/lib/mongo_mapper/plugins/descendants.rb +16 -0
- data/lib/mongo_mapper/plugins/dirty.rb +119 -0
- data/lib/mongo_mapper/plugins/equality.rb +23 -0
- data/lib/mongo_mapper/plugins/identity_map.rb +122 -0
- data/lib/mongo_mapper/plugins/inspect.rb +14 -0
- data/lib/mongo_mapper/plugins/keys.rb +324 -0
- data/lib/mongo_mapper/plugins/logger.rb +17 -0
- data/lib/mongo_mapper/plugins/pagination.rb +85 -0
- data/lib/mongo_mapper/plugins/protected.rb +45 -0
- data/lib/mongo_mapper/plugins/rails.rb +45 -0
- data/lib/mongo_mapper/plugins/serialization.rb +105 -0
- data/lib/mongo_mapper/plugins/validations.rb +57 -0
- data/lib/mongo_mapper/support.rb +217 -0
- data/lib/mongo_mapper/support/descendant_appends.rb +46 -0
- data/lib/mongo_mapper/support/find.rb +77 -0
- data/mongo_mapper.gemspec +195 -0
- data/performance/read_write.rb +52 -0
- data/specs.watchr +51 -0
- data/test/NOTE_ON_TESTING +1 -0
- data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +63 -0
- data/test/functional/associations/test_belongs_to_proxy.rb +101 -0
- data/test/functional/associations/test_in_array_proxy.rb +309 -0
- data/test/functional/associations/test_many_documents_as_proxy.rb +229 -0
- data/test/functional/associations/test_many_documents_proxy.rb +431 -0
- data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +176 -0
- data/test/functional/associations/test_many_embedded_proxy.rb +256 -0
- data/test/functional/associations/test_many_polymorphic_proxy.rb +302 -0
- data/test/functional/associations/test_one_proxy.rb +161 -0
- data/test/functional/test_associations.rb +44 -0
- data/test/functional/test_binary.rb +27 -0
- data/test/functional/test_callbacks.rb +81 -0
- data/test/functional/test_dirty.rb +163 -0
- data/test/functional/test_document.rb +1264 -0
- data/test/functional/test_embedded_document.rb +125 -0
- data/test/functional/test_identity_map.rb +508 -0
- data/test/functional/test_logger.rb +20 -0
- data/test/functional/test_modifiers.rb +252 -0
- data/test/functional/test_pagination.rb +93 -0
- data/test/functional/test_protected.rb +155 -0
- data/test/functional/test_string_id_compatibility.rb +67 -0
- data/test/functional/test_validations.rb +329 -0
- data/test/models.rb +232 -0
- data/test/support/custom_matchers.rb +55 -0
- data/test/support/timing.rb +16 -0
- data/test/test_helper.rb +60 -0
- data/test/unit/associations/test_base.rb +207 -0
- data/test/unit/associations/test_proxy.rb +105 -0
- data/test/unit/serializers/test_json_serializer.rb +189 -0
- data/test/unit/test_descendant_appends.rb +71 -0
- data/test/unit/test_document.rb +231 -0
- data/test/unit/test_dynamic_finder.rb +123 -0
- data/test/unit/test_embedded_document.rb +663 -0
- data/test/unit/test_finder_options.rb +329 -0
- data/test/unit/test_keys.rb +169 -0
- data/test/unit/test_mongo_mapper.rb +65 -0
- data/test/unit/test_pagination.rb +127 -0
- data/test/unit/test_plugins.rb +50 -0
- data/test/unit/test_rails.rb +123 -0
- data/test/unit/test_rails_compatibility.rb +52 -0
- data/test/unit/test_serialization.rb +51 -0
- data/test/unit/test_support.rb +354 -0
- data/test/unit/test_time_zones.rb +39 -0
- data/test/unit/test_validations.rb +544 -0
- metadata +290 -0
@@ -0,0 +1,55 @@
|
|
1
|
+
module CustomMatchers
|
2
|
+
custom_matcher :be_nil do |receiver, matcher, args|
|
3
|
+
matcher.positive_failure_message = "Expected #{receiver} to be nil but it wasn't"
|
4
|
+
matcher.negative_failure_message = "Expected #{receiver} not to be nil but it was"
|
5
|
+
receiver.nil?
|
6
|
+
end
|
7
|
+
|
8
|
+
custom_matcher :be_blank do |receiver, matcher, args|
|
9
|
+
matcher.positive_failure_message = "Expected #{receiver} to be blank but it wasn't"
|
10
|
+
matcher.negative_failure_message = "Expected #{receiver} not to be blank but it was"
|
11
|
+
receiver.blank?
|
12
|
+
end
|
13
|
+
|
14
|
+
custom_matcher :be_true do |receiver, matcher, args|
|
15
|
+
matcher.positive_failure_message = "Expected #{receiver} to be true but it wasn't"
|
16
|
+
matcher.negative_failure_message = "Expected #{receiver} not to be true but it was"
|
17
|
+
receiver.eql?(true)
|
18
|
+
end
|
19
|
+
|
20
|
+
custom_matcher :be_false do |receiver, matcher, args|
|
21
|
+
matcher.positive_failure_message = "Expected #{receiver} to be false but it wasn't"
|
22
|
+
matcher.negative_failure_message = "Expected #{receiver} not to be false but it was"
|
23
|
+
receiver.eql?(false)
|
24
|
+
end
|
25
|
+
|
26
|
+
custom_matcher :be_valid do |receiver, matcher, args|
|
27
|
+
matcher.positive_failure_message = "Expected to be valid but it was invalid #{receiver.errors.inspect}"
|
28
|
+
matcher.negative_failure_message = "Expected to be invalid but it was valid #{receiver.errors.inspect}"
|
29
|
+
receiver.valid?
|
30
|
+
end
|
31
|
+
|
32
|
+
custom_matcher :have_error_on do |receiver, matcher, args|
|
33
|
+
receiver.valid?
|
34
|
+
attribute = args[0]
|
35
|
+
expected_message = args[1]
|
36
|
+
|
37
|
+
if expected_message.nil?
|
38
|
+
matcher.positive_failure_message = "#{receiver} had no errors on #{attribute}"
|
39
|
+
matcher.negative_failure_message = "#{receiver} had errors on #{attribute} #{receiver.errors.inspect}"
|
40
|
+
!receiver.errors.on(attribute).blank?
|
41
|
+
else
|
42
|
+
actual = receiver.errors.on(attribute)
|
43
|
+
matcher.positive_failure_message = %Q(Expected error on #{attribute} to be "#{expected_message}" but was "#{actual}")
|
44
|
+
matcher.negative_failure_message = %Q(Expected error on #{attribute} not to be "#{expected_message}" but was "#{actual}")
|
45
|
+
actual == expected_message
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
custom_matcher :have_index do |receiver, matcher, args|
|
50
|
+
index_name = args[0]
|
51
|
+
matcher.positive_failure_message = "#{receiver} does not have index named #{index_name}, but should"
|
52
|
+
matcher.negative_failure_message = "#{receiver} does have index named #{index_name}, but should not"
|
53
|
+
!receiver.collection.index_information.detect { |index| index[0] == index_name }.nil?
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class Test::Unit::TestCase
|
2
|
+
def run_with_test_timing(*args, &block)
|
3
|
+
begin_time = Time.now
|
4
|
+
run_without_test_timing(*args, &block)
|
5
|
+
end_time = Time.now
|
6
|
+
|
7
|
+
duration = end_time - begin_time
|
8
|
+
threshold = 1.0
|
9
|
+
|
10
|
+
if duration > threshold
|
11
|
+
puts "\nSLOW TEST: #{duration} - #{self.name}"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
alias_method_chain :run, :test_timing unless method_defined?(:run_without_test_timing)
|
16
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
if ENV["RAILS3"]
|
2
|
+
gem "activemodel", ">= 3.0.0.beta"
|
3
|
+
require 'active_model'
|
4
|
+
end
|
5
|
+
|
6
|
+
require File.expand_path(File.dirname(__FILE__) + '/../lib/mongo_mapper')
|
7
|
+
|
8
|
+
gem 'jnunemaker-matchy', '0.4.0'
|
9
|
+
gem 'shoulda', '2.10.2'
|
10
|
+
gem 'timecop', '0.3.1'
|
11
|
+
gem 'mocha', '0.9.8'
|
12
|
+
|
13
|
+
require 'matchy'
|
14
|
+
require 'shoulda'
|
15
|
+
require 'timecop'
|
16
|
+
require 'mocha'
|
17
|
+
require 'pp'
|
18
|
+
|
19
|
+
require 'support/custom_matchers'
|
20
|
+
require 'support/timing'
|
21
|
+
|
22
|
+
class Test::Unit::TestCase
|
23
|
+
include CustomMatchers
|
24
|
+
|
25
|
+
def Doc(name=nil, &block)
|
26
|
+
klass = Class.new do
|
27
|
+
include MongoMapper::Document
|
28
|
+
set_collection_name "test#{rand(20)}"
|
29
|
+
|
30
|
+
if name
|
31
|
+
class_eval "def self.name; '#{name}' end"
|
32
|
+
class_eval "def self.to_s; '#{name}' end"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
klass.class_eval(&block) if block_given?
|
37
|
+
klass.collection.remove
|
38
|
+
klass
|
39
|
+
end
|
40
|
+
|
41
|
+
def EDoc(name=nil, &block)
|
42
|
+
klass = Class.new do
|
43
|
+
include MongoMapper::EmbeddedDocument
|
44
|
+
|
45
|
+
if name
|
46
|
+
class_eval "def self.name; '#{name}' end"
|
47
|
+
class_eval "def self.to_s; '#{name}' end"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
klass.class_eval(&block) if block_given?
|
52
|
+
klass
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
test_dir = File.expand_path(File.dirname(__FILE__) + '/../tmp')
|
57
|
+
FileUtils.mkdir_p(test_dir) unless File.exist?(test_dir)
|
58
|
+
|
59
|
+
MongoMapper.connection = Mongo::Connection.new('127.0.0.1', 27017, {:logger => Logger.new(test_dir + '/test.log')})
|
60
|
+
MongoMapper.database = 'test'
|
@@ -0,0 +1,207 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'models'
|
3
|
+
|
4
|
+
class FooMonster; end
|
5
|
+
|
6
|
+
class AssociationBaseTest < Test::Unit::TestCase
|
7
|
+
include MongoMapper::Plugins::Associations
|
8
|
+
|
9
|
+
should "initialize with type and name" do
|
10
|
+
base = Base.new(:many, :foos)
|
11
|
+
base.type.should == :many
|
12
|
+
base.name.should == :foos
|
13
|
+
end
|
14
|
+
|
15
|
+
should "also allow options when initializing" do
|
16
|
+
base = Base.new(:many, :foos, :polymorphic => true)
|
17
|
+
base.options[:polymorphic].should be_true
|
18
|
+
end
|
19
|
+
|
20
|
+
context "class_name" do
|
21
|
+
should "work for belongs_to" do
|
22
|
+
Base.new(:belongs_to, :user).class_name.should == 'User'
|
23
|
+
end
|
24
|
+
|
25
|
+
should "work for many" do
|
26
|
+
Base.new(:many, :smart_people).class_name.should == 'SmartPerson'
|
27
|
+
end
|
28
|
+
|
29
|
+
should "be changeable using class_name option" do
|
30
|
+
base = Base.new(:many, :smart_people, :class_name => 'IntelligentPerson')
|
31
|
+
base.class_name.should == 'IntelligentPerson'
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "klass" do
|
36
|
+
should "default to class_name constantized" do
|
37
|
+
Base.new(:belongs_to, :foo_monster).klass.should == FooMonster
|
38
|
+
end
|
39
|
+
|
40
|
+
should "be the specified class" do
|
41
|
+
anonnymous_class = Class.new
|
42
|
+
Base.new(:belongs_to, :foo_monster, :class => anonnymous_class).klass.should == anonnymous_class
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "many?" do
|
47
|
+
should "be true if many" do
|
48
|
+
Base.new(:many, :foos).many?.should be_true
|
49
|
+
end
|
50
|
+
|
51
|
+
should "be false if not many" do
|
52
|
+
Base.new(:belongs_to, :foo).many?.should be_false
|
53
|
+
Base.new(:one, :foo).many?.should be_false
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "one?" do
|
58
|
+
should "be true if one" do
|
59
|
+
Base.new(:one, :foo).one?.should be_true
|
60
|
+
end
|
61
|
+
|
62
|
+
should "be false if not one" do
|
63
|
+
Base.new(:many, :foo).one?.should be_false
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context "belongs_to?" do
|
68
|
+
should "be true if belongs_to" do
|
69
|
+
Base.new(:belongs_to, :foo).belongs_to?.should be_true
|
70
|
+
end
|
71
|
+
|
72
|
+
should "be false if not belongs_to" do
|
73
|
+
Base.new(:many, :foos).belongs_to?.should be_false
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "polymorphic?" do
|
78
|
+
should "be true if polymorphic" do
|
79
|
+
Base.new(:many, :foos, :polymorphic => true).polymorphic?.should be_true
|
80
|
+
end
|
81
|
+
|
82
|
+
should "be false if not polymorphic" do
|
83
|
+
Base.new(:many, :bars).polymorphic?.should be_false
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context "as?" do
|
88
|
+
should "be true if one" do
|
89
|
+
Base.new(:one, :foo, :as => :commentable).as?.should be_true
|
90
|
+
end
|
91
|
+
|
92
|
+
should "be false if not one" do
|
93
|
+
Base.new(:many, :foo).as?.should be_false
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context "in_array?" do
|
98
|
+
should "be true if one" do
|
99
|
+
Base.new(:one, :foo, :in => :list_ids).in_array?.should be_true
|
100
|
+
end
|
101
|
+
|
102
|
+
should "be false if not one" do
|
103
|
+
Base.new(:many, :foo).in_array?.should be_false
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context "finder_options" do
|
108
|
+
should "default to empty hash" do
|
109
|
+
base = Base.new(:many, :foos)
|
110
|
+
base.finder_options.should == {}
|
111
|
+
end
|
112
|
+
|
113
|
+
should "work with order" do
|
114
|
+
base = Base.new(:many, :foos, :order => 'position')
|
115
|
+
base.finder_options.should == {:order => 'position'}
|
116
|
+
end
|
117
|
+
|
118
|
+
should "correctly parse from options" do
|
119
|
+
base = Base.new(:many, :foos, :order => 'position', :somekey => 'somevalue')
|
120
|
+
base.finder_options.should == {:order => 'position', :somekey => 'somevalue'}
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context "type_key_name" do
|
125
|
+
should "be _type for many" do
|
126
|
+
Base.new(:many, :foos).type_key_name.should == '_type'
|
127
|
+
end
|
128
|
+
|
129
|
+
should "be association name _ type for belongs_to" do
|
130
|
+
Base.new(:belongs_to, :foo).type_key_name.should == 'foo_type'
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
context "foreign_key" do
|
135
|
+
should "default to assocation name _id for belongs to" do
|
136
|
+
base = Base.new(:belongs_to, :foo)
|
137
|
+
base.foreign_key.should == 'foo_id'
|
138
|
+
end
|
139
|
+
|
140
|
+
should "be overridable with :foreign_key option" do
|
141
|
+
base = Base.new(:belongs_to, :foo, :foreign_key => 'foobar_id')
|
142
|
+
base.foreign_key.should == 'foobar_id'
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
should "have ivar that is association name" do
|
147
|
+
Base.new(:belongs_to, :foo).ivar.should == '@_foo'
|
148
|
+
end
|
149
|
+
|
150
|
+
context "embeddable?" do
|
151
|
+
should "be true if class is embeddable" do
|
152
|
+
base = Base.new(:many, :medias)
|
153
|
+
base.embeddable?.should be_true
|
154
|
+
end
|
155
|
+
|
156
|
+
should "be false if class is not embeddable" do
|
157
|
+
base = Base.new(:many, :statuses)
|
158
|
+
base.embeddable?.should be_false
|
159
|
+
|
160
|
+
base = Base.new(:belongs_to, :project)
|
161
|
+
base.embeddable?.should be_false
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
context "proxy_class" do
|
166
|
+
should "be ManyDocumentsProxy for many" do
|
167
|
+
base = Base.new(:many, :statuses)
|
168
|
+
base.proxy_class.should == ManyDocumentsProxy
|
169
|
+
end
|
170
|
+
|
171
|
+
should "be ManyPolymorphicProxy for polymorphic many" do
|
172
|
+
base = Base.new(:many, :messages, :polymorphic => true)
|
173
|
+
base.proxy_class.should == ManyPolymorphicProxy
|
174
|
+
end
|
175
|
+
|
176
|
+
should "be ManyEmbeddedProxy for many embedded" do
|
177
|
+
base = Base.new(:many, :medias)
|
178
|
+
base.proxy_class.should == ManyEmbeddedProxy
|
179
|
+
end
|
180
|
+
|
181
|
+
should "be ManyEmbeddedPolymorphicProxy for polymorphic many embedded" do
|
182
|
+
base = Base.new(:many, :medias, :polymorphic => true)
|
183
|
+
base.proxy_class.should == ManyEmbeddedPolymorphicProxy
|
184
|
+
end
|
185
|
+
|
186
|
+
should "be BelongsToProxy for belongs_to" do
|
187
|
+
base = Base.new(:belongs_to, :project)
|
188
|
+
base.proxy_class.should == BelongsToProxy
|
189
|
+
end
|
190
|
+
|
191
|
+
should "be BelongsToPolymorphicProxy for polymorphic belongs_to" do
|
192
|
+
base = Base.new(:belongs_to, :target, :polymorphic => true)
|
193
|
+
base.proxy_class.should == BelongsToPolymorphicProxy
|
194
|
+
end
|
195
|
+
|
196
|
+
should "be OneProxy for one" do
|
197
|
+
base = Base.new(:one, :target, :polymorphic => true)
|
198
|
+
base.proxy_class.should == OneProxy
|
199
|
+
end
|
200
|
+
|
201
|
+
should "be InArrayProxy for many with :in option" do
|
202
|
+
base = Base.new(:many, :messages, :in => :message_ids)
|
203
|
+
base.proxy_class.should == InArrayProxy
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class FakeNilProxy < MongoMapper::Plugins::Associations::Proxy
|
4
|
+
def find_target; nil end
|
5
|
+
end
|
6
|
+
|
7
|
+
class FakeBlankProxy < MongoMapper::Plugins::Associations::Proxy
|
8
|
+
def find_target; '' end
|
9
|
+
end
|
10
|
+
|
11
|
+
class FakeNumberProxy < MongoMapper::Plugins::Associations::Proxy
|
12
|
+
def find_target; 17 end
|
13
|
+
end
|
14
|
+
|
15
|
+
class FakeProxy < MongoMapper::Plugins::Associations::Proxy
|
16
|
+
def find_target; [1, 2] end
|
17
|
+
end
|
18
|
+
|
19
|
+
class ProxyTest < Test::Unit::TestCase
|
20
|
+
def setup
|
21
|
+
@owner = mock('owner')
|
22
|
+
@owner.stubs(:new?).returns(false)
|
23
|
+
@association = mock('association')
|
24
|
+
@association.stubs(:options).returns({:extend => []})
|
25
|
+
|
26
|
+
@proxy = FakeProxy.new(@owner, @association)
|
27
|
+
@nil_proxy = FakeNilProxy.new(@owner, @association)
|
28
|
+
@blank_proxy = FakeBlankProxy.new(@owner, @association)
|
29
|
+
end
|
30
|
+
|
31
|
+
should 'return true for === target' do
|
32
|
+
@proxy = FakeProxy.new(@owner, @association)
|
33
|
+
@proxy.should === Array
|
34
|
+
end
|
35
|
+
|
36
|
+
should "set target to nil when reset is called" do
|
37
|
+
@proxy.reset
|
38
|
+
@proxy.target.should be_nil
|
39
|
+
end
|
40
|
+
|
41
|
+
should "be able to inspect the proxy" do
|
42
|
+
@proxy.inspect.should == '[1, 2]'
|
43
|
+
end
|
44
|
+
|
45
|
+
context "nil?" do
|
46
|
+
should "be true if nil" do
|
47
|
+
@nil_proxy.nil?.should be_true
|
48
|
+
end
|
49
|
+
|
50
|
+
should "be false if not nil" do
|
51
|
+
@proxy.nil?.should be_false
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "blank?" do
|
56
|
+
should "be true if blank" do
|
57
|
+
@blank_proxy.blank?.should be_true
|
58
|
+
@nil_proxy.blank?.should be_true
|
59
|
+
end
|
60
|
+
|
61
|
+
should "be false if not blank" do
|
62
|
+
@proxy.blank?.should be_false
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "present?" do
|
67
|
+
should "be true if present" do
|
68
|
+
@proxy.present?.should be_true
|
69
|
+
end
|
70
|
+
|
71
|
+
should "be false if not present" do
|
72
|
+
@blank_proxy.present?.should be_false
|
73
|
+
@nil_proxy.present?.should be_false
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
should "delegate respond_to? to target" do
|
78
|
+
@proxy.respond_to?(:each).should be_true
|
79
|
+
@proxy.respond_to?(:size).should be_true
|
80
|
+
@proxy.respond_to?(:gsub).should be_false
|
81
|
+
end
|
82
|
+
|
83
|
+
should "alias proxy owner to owner" do
|
84
|
+
@proxy.proxy_owner.should == @owner
|
85
|
+
end
|
86
|
+
|
87
|
+
should "alias proxy target to target" do
|
88
|
+
@proxy.proxy_target.should == @target
|
89
|
+
end
|
90
|
+
|
91
|
+
context "send" do
|
92
|
+
should "work if proxy responds to method" do
|
93
|
+
@proxy.send(:reset)
|
94
|
+
@proxy.target.should be_nil
|
95
|
+
end
|
96
|
+
|
97
|
+
should "work if the target responds to the method" do
|
98
|
+
@proxy.send(:size).should == 2
|
99
|
+
end
|
100
|
+
|
101
|
+
should "not work if neither the proxy or target respond to method" do
|
102
|
+
lambda { @proxy.send(:gsub) }.should raise_error
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,189 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class JsonSerializationTest < Test::Unit::TestCase
|
4
|
+
class Tag
|
5
|
+
include MongoMapper::EmbeddedDocument
|
6
|
+
key :name, String
|
7
|
+
end
|
8
|
+
|
9
|
+
class Contact
|
10
|
+
include MongoMapper::Document
|
11
|
+
key :name, String
|
12
|
+
key :age, Integer
|
13
|
+
key :created_at, Time
|
14
|
+
key :awesome, Boolean
|
15
|
+
key :preferences, Hash
|
16
|
+
|
17
|
+
many :tags, :class_name => 'JsonSerializationTest::Tag'
|
18
|
+
end
|
19
|
+
|
20
|
+
def setup
|
21
|
+
Contact.include_root_in_json = false
|
22
|
+
@contact = Contact.new(
|
23
|
+
:name => 'Konata Izumi',
|
24
|
+
:age => 16,
|
25
|
+
:created_at => Time.utc(2006, 8, 1),
|
26
|
+
:awesome => true,
|
27
|
+
:preferences => { :shows => 'anime' }
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
should "include demodulized root" do
|
32
|
+
Contact.include_root_in_json = true
|
33
|
+
assert_match %r{^\{"contact": \{}, @contact.to_json
|
34
|
+
end
|
35
|
+
|
36
|
+
should "encode all encodable attributes" do
|
37
|
+
json = @contact.to_json
|
38
|
+
|
39
|
+
assert_no_match %r{"_id"}, json
|
40
|
+
assert_match %r{"name":"Konata Izumi"}, json
|
41
|
+
assert_match %r{"age":16}, json
|
42
|
+
assert json.include?(%("created_at":#{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}))
|
43
|
+
assert_match %r{"awesome":true}, json
|
44
|
+
assert_match %r{"preferences":\{"shows":"anime"\}}, json
|
45
|
+
end
|
46
|
+
|
47
|
+
should "allow attribute filtering with only" do
|
48
|
+
json = @contact.to_json(:only => [:name, :age])
|
49
|
+
|
50
|
+
assert_no_match %r{"_id"}, json
|
51
|
+
assert_match %r{"name":"Konata Izumi"}, json
|
52
|
+
assert_match %r{"age":16}, json
|
53
|
+
assert_no_match %r{"awesome"}, json
|
54
|
+
assert_no_match %r{"created_at"}, json
|
55
|
+
assert_no_match %r{"preferences"}, json
|
56
|
+
end
|
57
|
+
|
58
|
+
should "allow attribute filtering with except" do
|
59
|
+
json = @contact.to_json(:except => [:name, :age])
|
60
|
+
|
61
|
+
assert_no_match %r{"_id"}, json
|
62
|
+
assert_no_match %r{"name"}, json
|
63
|
+
assert_no_match %r{"age"}, json
|
64
|
+
assert_match %r{"awesome"}, json
|
65
|
+
assert_match %r{"created_at"}, json
|
66
|
+
assert_match %r{"preferences"}, json
|
67
|
+
end
|
68
|
+
|
69
|
+
context "_id key" do
|
70
|
+
should "not be included by default" do
|
71
|
+
json = @contact.to_json
|
72
|
+
assert_no_match %r{"_id":}, json
|
73
|
+
end
|
74
|
+
|
75
|
+
should "not be included even if :except is used" do
|
76
|
+
json = @contact.to_json(:except => :name)
|
77
|
+
assert_no_match %r{"_id":}, json
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context "id method" do
|
82
|
+
setup do
|
83
|
+
def @contact.label; "Has cheezburger"; end
|
84
|
+
def @contact.favorite_quote; "Constraints are liberating"; end
|
85
|
+
end
|
86
|
+
|
87
|
+
should "be included by default" do
|
88
|
+
json = @contact.to_json
|
89
|
+
assert_match %r{"id"}, json
|
90
|
+
end
|
91
|
+
|
92
|
+
should "be included when single method included" do
|
93
|
+
json = @contact.to_json(:methods => :label)
|
94
|
+
assert_match %r{"id"}, json
|
95
|
+
assert_match %r{"label":"Has cheezburger"}, json
|
96
|
+
assert_match %r{"name":"Konata Izumi"}, json
|
97
|
+
assert_no_match %r{"favorite_quote":"Constraints are liberating"}, json
|
98
|
+
end
|
99
|
+
|
100
|
+
should "be included when multiple methods included" do
|
101
|
+
json = @contact.to_json(:methods => [:label, :favorite_quote])
|
102
|
+
assert_match %r{"id"}, json
|
103
|
+
assert_match %r{"label":"Has cheezburger"}, json
|
104
|
+
assert_match %r{"favorite_quote":"Constraints are liberating"}, json
|
105
|
+
assert_match %r{"name":"Konata Izumi"}, json
|
106
|
+
end
|
107
|
+
|
108
|
+
should "not be included if :only is present" do
|
109
|
+
json = @contact.to_json(:only => :name)
|
110
|
+
assert_no_match %r{"id":}, json
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context "including methods" do
|
115
|
+
setup do
|
116
|
+
def @contact.label; "Has cheezburger"; end
|
117
|
+
def @contact.favorite_quote; "Constraints are liberating"; end
|
118
|
+
end
|
119
|
+
|
120
|
+
should "include single method" do
|
121
|
+
json = @contact.to_json(:methods => :label)
|
122
|
+
assert_match %r{"label":"Has cheezburger"}, json
|
123
|
+
end
|
124
|
+
|
125
|
+
should "include multiple methods" do
|
126
|
+
json = @contact.to_json(:only => :name, :methods => [:label, :favorite_quote])
|
127
|
+
assert_match %r{"label":"Has cheezburger"}, json
|
128
|
+
assert_match %r{"favorite_quote":"Constraints are liberating"}, json
|
129
|
+
assert_match %r{"name":"Konata Izumi"}, json
|
130
|
+
assert_no_match %r{"age":16}, json
|
131
|
+
assert_no_match %r{"awesome"}, json
|
132
|
+
assert_no_match %r{"created_at"}, json
|
133
|
+
assert_no_match %r{"preferences"}, json
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
context "array of records" do
|
138
|
+
setup do
|
139
|
+
@contacts = [
|
140
|
+
Contact.new(:name => 'David', :age => 39),
|
141
|
+
Contact.new(:name => 'Mary', :age => 14)
|
142
|
+
]
|
143
|
+
end
|
144
|
+
|
145
|
+
should "allow attribute filtering with only" do
|
146
|
+
json = @contacts.to_json(:only => :name)
|
147
|
+
assert_match %r{\{"name":"David"\}}, json
|
148
|
+
assert_match %r{\{"name":"Mary"\}}, json
|
149
|
+
end
|
150
|
+
|
151
|
+
should "allow attribute filtering with except" do
|
152
|
+
json = @contacts.to_json(:except => [:name, :preferences, :awesome, :created_at, :updated_at])
|
153
|
+
assert_match %r{"age":39}, json
|
154
|
+
assert_match %r{"age":14}, json
|
155
|
+
assert_no_match %r{"name":}, json
|
156
|
+
assert_no_match %r{"preferences":}, json
|
157
|
+
assert_no_match %r{"awesome":}, json
|
158
|
+
assert_no_match %r{"created_at":}, json
|
159
|
+
assert_no_match %r{"updated_at":}, json
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
should "allow options for hash of records" do
|
164
|
+
contacts = {
|
165
|
+
1 => Contact.new(:name => 'David', :age => 39),
|
166
|
+
2 => Contact.new(:name => 'Mary', :age => 14)
|
167
|
+
}
|
168
|
+
json = contacts.to_json(:only => [1, :name])
|
169
|
+
assert_match %r{"1":}, json
|
170
|
+
assert_match %r{\{"name":"David"\}}, json
|
171
|
+
assert_no_match %r{"2":}, json
|
172
|
+
end
|
173
|
+
|
174
|
+
should "include embedded attributes" do
|
175
|
+
contact = Contact.new(:name => 'John', :age => 27)
|
176
|
+
contact.tags = [Tag.new(:name => 'awesome'), Tag.new(:name => 'ruby')]
|
177
|
+
json = contact.to_json
|
178
|
+
assert_match %r{"tags":}, json
|
179
|
+
assert_match %r{"name":"awesome"}, json
|
180
|
+
assert_match %r{"name":"ruby"}, json
|
181
|
+
end
|
182
|
+
|
183
|
+
should "include dynamic attributes" do
|
184
|
+
contact = Contact.new(:name => 'John', :age => 27, :foo => 'bar')
|
185
|
+
contact['smell'] = 'stinky'
|
186
|
+
json = contact.to_json
|
187
|
+
assert_match %r{"smell":"stinky"}, json
|
188
|
+
end
|
189
|
+
end
|