mongomodel 0.4.9 → 0.5.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.
- data/.travis.yml +30 -0
- data/Gemfile +1 -1
- data/README.md +7 -1
- data/Rakefile +0 -2
- data/gemfiles/mongo_mapper.gemfile +6 -7
- data/gemfiles/mongoid.gemfile +6 -7
- data/gemfiles/rails-3.1.gemfile +5 -6
- data/gemfiles/rails-3.2.gemfile +5 -6
- data/gemfiles/rails-4-observers.gemfile +6 -8
- data/gemfiles/rails-4-protected-attributes.gemfile +6 -8
- data/gemfiles/rails-4.gemfile +5 -7
- data/lib/mongomodel.rb +1 -0
- data/lib/mongomodel/concerns/associations/has_many_by_ids.rb +6 -1
- data/lib/mongomodel/concerns/attribute_methods/forbidden.rb +17 -0
- data/lib/mongomodel/concerns/attribute_methods/multi_parameter_assignment.rb +1 -1
- data/lib/mongomodel/concerns/attributes.rb +5 -0
- data/lib/mongomodel/concerns/properties.rb +2 -2
- data/lib/mongomodel/concerns/serialization.rb +15 -6
- data/lib/mongomodel/embedded_document.rb +1 -0
- data/lib/mongomodel/railtie.rb +7 -5
- data/lib/mongomodel/support/scope.rb +2 -9
- data/lib/mongomodel/support/scope/array_methods.rb +21 -0
- data/lib/mongomodel/support/types/date_time.rb +18 -5
- data/lib/mongomodel/version.rb +1 -1
- data/spec/mongomodel/attributes/store_spec.rb +9 -5
- data/spec/mongomodel/concerns/activemodel_spec.rb +13 -13
- data/spec/mongomodel/concerns/associations/belongs_to_spec.rb +65 -65
- data/spec/mongomodel/concerns/associations/has_many_by_ids_spec.rb +128 -121
- data/spec/mongomodel/concerns/attributes_spec.rb +11 -2
- data/spec/mongomodel/concerns/logging_spec.rb +1 -1
- data/spec/mongomodel/concerns/observing_spec.rb +1 -1
- data/spec/mongomodel/concerns/serialization/json_serialization_spec.rb +26 -10
- data/spec/mongomodel/concerns/timestamps_spec.rb +5 -5
- data/spec/mongomodel/document/indexes_spec.rb +1 -1
- data/spec/mongomodel/document/validations/uniqueness_spec.rb +1 -1
- data/spec/mongomodel/document/validations_spec.rb +1 -1
- data/spec/mongomodel/document_spec.rb +1 -1
- data/spec/mongomodel/mongomodel_spec.rb +1 -1
- data/spec/mongomodel/support/mongo_order_spec.rb +2 -2
- data/spec/mongomodel/support/paginator_spec.rb +3 -3
- data/spec/mongomodel/support/property_spec.rb +12 -6
- data/spec/mongomodel/support/scope_spec.rb +24 -14
- data/spec/support/helpers/document_finder_stubs.rb +5 -5
- data/spec/support/matchers/find_with.rb +2 -2
- metadata +6 -4
- data/Appraisals +0 -46
@@ -11,9 +11,10 @@ module MongoModel
|
|
11
11
|
Array => [ 1, 2, 3, "hello", :world, [99, 100] ],
|
12
12
|
Hash => { :rabbit => 'hat', 'hello' => 12345 }.with_indifferent_access,
|
13
13
|
Date => Date.today,
|
14
|
+
CustomClass => CustomClass.new('hello'),
|
15
|
+
# Pre-cast Time and DateTime to remove microseconds
|
14
16
|
Time => Types::Time.new.cast(Time.now),
|
15
|
-
DateTime => Types::DateTime.new.cast(DateTime.now)
|
16
|
-
CustomClass => CustomClass.new('hello')
|
17
|
+
DateTime => Types::DateTime.new.cast(DateTime.now.in_time_zone)
|
17
18
|
}
|
18
19
|
|
19
20
|
specs_for(Document, EmbeddedDocument) do
|
@@ -117,6 +118,14 @@ module MongoModel
|
|
117
118
|
subject.attributes = { :non_property => 'property value' }
|
118
119
|
subject.read_attribute(:non_property).should == 'property value'
|
119
120
|
end
|
121
|
+
|
122
|
+
if defined?(ActiveModel::ForbiddenAttributesProtection)
|
123
|
+
it "raises ActiveModel::ForbiddenAttributesError when passed an unpermitted strong_params hash" do
|
124
|
+
expect {
|
125
|
+
subject.attributes = double(:permitted? => false)
|
126
|
+
}.to raise_error(ActiveModel::ForbiddenAttributesError)
|
127
|
+
end
|
128
|
+
end
|
120
129
|
end
|
121
130
|
|
122
131
|
describe "#new" do
|
@@ -5,7 +5,7 @@ module MongoModel
|
|
5
5
|
describe "logging" do
|
6
6
|
define_class(:TestDocument, described_class)
|
7
7
|
|
8
|
-
let(:logger) {
|
8
|
+
let(:logger) { double('logger').as_null_object }
|
9
9
|
before(:each) { MongoModel.logger = logger }
|
10
10
|
|
11
11
|
it "has a logger reader on the class" do
|
@@ -15,18 +15,21 @@ module MongoModel
|
|
15
15
|
end
|
16
16
|
|
17
17
|
let(:instance) do
|
18
|
-
TestModel.new(:name => 'Hello World', :age => 25, :paid => true, :prefs => { :foo => 'bar' }, :internal => 'hideme')
|
18
|
+
TestModel.new(:id => "abc-123", :name => 'Hello World', :age => 25, :paid => true, :prefs => { :foo => 'bar' }, :internal => 'hideme')
|
19
19
|
end
|
20
20
|
|
21
|
-
it "includes root in
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
21
|
+
it "includes root in the JSON response when include_root_in_json = true" do
|
22
|
+
TestModel.include_root_in_json = true
|
23
|
+
|
24
|
+
json = instance.to_json
|
25
|
+
json.should match(/^\{"test_model":\{/)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "does not include root in the JSON response when include_root_in_json = false" do
|
29
|
+
TestModel.include_root_in_json = false
|
30
|
+
|
31
|
+
json = instance.to_json
|
32
|
+
json.should_not match(/^\{"test_model":\{/)
|
30
33
|
end
|
31
34
|
|
32
35
|
it "encodes all public attributes" do
|
@@ -37,6 +40,13 @@ module MongoModel
|
|
37
40
|
json.should match(/"prefs":\{"foo":"bar"\}/)
|
38
41
|
end
|
39
42
|
|
43
|
+
if described_class == Document
|
44
|
+
it "encodes the id" do
|
45
|
+
json = instance.to_json
|
46
|
+
json.should match(/"id":"abc-123"/)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
40
50
|
it "does not encode internal attributes" do
|
41
51
|
json = instance.to_json
|
42
52
|
json.should_not match(/"internal":"hideme"/)
|
@@ -63,5 +73,11 @@ module MongoModel
|
|
63
73
|
json.should match(/"hello":"Hi friend!"/)
|
64
74
|
json.should match(/"type":"TestModel"/)
|
65
75
|
end
|
76
|
+
|
77
|
+
it "encodes keys in the serializable_hash as strings" do
|
78
|
+
hash = instance.serializable_hash(:methods => :hello)
|
79
|
+
hash.should have_key("name")
|
80
|
+
hash.should have_key("hello")
|
81
|
+
end
|
66
82
|
end
|
67
83
|
end
|
@@ -39,7 +39,7 @@ module MongoModel
|
|
39
39
|
|
40
40
|
before(:each) do
|
41
41
|
@now = Types::Time.new.cast(Time.now)
|
42
|
-
Time.stub
|
42
|
+
Time.stub(:now).and_return(@now)
|
43
43
|
end
|
44
44
|
|
45
45
|
it "sets the updated_at property to the current time when saved" do
|
@@ -92,7 +92,7 @@ module MongoModel
|
|
92
92
|
|
93
93
|
before(:each) do
|
94
94
|
@now = Types::Time.new.cast(Time.now)
|
95
|
-
Time.stub
|
95
|
+
Time.stub(:now).and_return(@now)
|
96
96
|
end
|
97
97
|
|
98
98
|
it "sets the created_at property to the current time when created" do
|
@@ -103,11 +103,11 @@ module MongoModel
|
|
103
103
|
it "does not change the created_at property when updated" do
|
104
104
|
@next = 1.day.from_now
|
105
105
|
|
106
|
-
Time.stub
|
106
|
+
Time.stub(:now).and_return(@now)
|
107
107
|
|
108
108
|
doc.save
|
109
109
|
|
110
|
-
Time.stub
|
110
|
+
Time.stub(:now).and_return(@next)
|
111
111
|
|
112
112
|
doc.save
|
113
113
|
subject.created_at.should == @now
|
@@ -152,7 +152,7 @@ module MongoModel
|
|
152
152
|
@today = Date.today
|
153
153
|
@tomorrow = 1.day.from_now
|
154
154
|
|
155
|
-
Time.stub
|
155
|
+
Time.stub(:now).and_return(@tomorrow)
|
156
156
|
|
157
157
|
doc.save
|
158
158
|
subject.created_on.should == @today
|
@@ -21,7 +21,7 @@ module MongoModel
|
|
21
21
|
|
22
22
|
describe "#save!" do
|
23
23
|
before(:each) do
|
24
|
-
subject.errors.stub
|
24
|
+
subject.errors.stub(:full_messages).and_return(["first error", "second error"])
|
25
25
|
end
|
26
26
|
|
27
27
|
it "raises a MongoModel::DocumentInvalid exception" do
|
@@ -10,7 +10,7 @@ module MongoModel
|
|
10
10
|
property = Document.properties[:id]
|
11
11
|
property.name.should == :id
|
12
12
|
property.as.should == '_id'
|
13
|
-
property.default(
|
13
|
+
property.default(double('instance', :generate_id => 'abc-123')).should == 'abc-123'
|
14
14
|
end
|
15
15
|
|
16
16
|
describe "equality" do
|
@@ -14,7 +14,7 @@ module MongoModel
|
|
14
14
|
|
15
15
|
describe "#to_sort" do
|
16
16
|
it "converts to mongo sort array" do
|
17
|
-
model =
|
17
|
+
model = double('model', :properties => double('properties', :[] => nil))
|
18
18
|
subject.to_sort(model).should == [['name', :ascending], ['age', :descending]]
|
19
19
|
end
|
20
20
|
end
|
@@ -94,7 +94,7 @@ module MongoModel
|
|
94
94
|
describe "#to_sort" do
|
95
95
|
context "given property" do
|
96
96
|
it "uses property as value to convert to mongo sort" do
|
97
|
-
property =
|
97
|
+
property = double('property', :as => '_name')
|
98
98
|
subject.to_sort(property).should == ['_name', :ascending]
|
99
99
|
end
|
100
100
|
end
|
@@ -2,8 +2,8 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module MongoModel
|
4
4
|
describe Paginator do
|
5
|
-
let(:entries) { [
|
6
|
-
let(:scope) {
|
5
|
+
let(:entries) { [double] * 10 }
|
6
|
+
let(:scope) { double(:count => 35, :limit => entries).as_null_object }
|
7
7
|
let(:page) { 2 }
|
8
8
|
let(:per_page) { 10 }
|
9
9
|
|
@@ -32,7 +32,7 @@ module MongoModel
|
|
32
32
|
end
|
33
33
|
|
34
34
|
context "last page" do
|
35
|
-
let(:entries) { [
|
35
|
+
let(:entries) { [double] * 5 }
|
36
36
|
before { scope.stub(:count => nil) }
|
37
37
|
|
38
38
|
let(:page) { 4 }
|
@@ -19,7 +19,7 @@ module MongoModel
|
|
19
19
|
end
|
20
20
|
|
21
21
|
it "defaults to nil" do
|
22
|
-
subject.default(
|
22
|
+
subject.default(double('document instance')).should be_nil
|
23
23
|
end
|
24
24
|
|
25
25
|
it "equals a property with the same name and type" do
|
@@ -47,7 +47,7 @@ module MongoModel
|
|
47
47
|
end
|
48
48
|
|
49
49
|
it "defaults to custom default" do
|
50
|
-
subject.default(
|
50
|
+
subject.default(double('document instance')).should == 21
|
51
51
|
end
|
52
52
|
|
53
53
|
it "equals a property with the same name, type and options" do
|
@@ -61,10 +61,16 @@ module MongoModel
|
|
61
61
|
end
|
62
62
|
|
63
63
|
context "with callable default" do
|
64
|
-
|
65
|
-
|
66
|
-
it "calls
|
67
|
-
|
64
|
+
let(:document) { double('document instance', :answer => 42) }
|
65
|
+
|
66
|
+
it "calls the proc yielding the instance" do
|
67
|
+
property = Property.new(:age, Integer, :default => lambda { |doc| doc.answer })
|
68
|
+
property.default(document).should == 42
|
69
|
+
end
|
70
|
+
|
71
|
+
it "calls the proc in the context of the instance" do
|
72
|
+
property = Property.new(:age, Integer, :default => proc { answer })
|
73
|
+
property.default(document).should == 42
|
68
74
|
end
|
69
75
|
end
|
70
76
|
|
@@ -278,23 +278,33 @@ module MongoModel
|
|
278
278
|
end
|
279
279
|
|
280
280
|
describe "#select" do
|
281
|
-
|
282
|
-
|
283
|
-
|
281
|
+
context "when no block is given" do
|
282
|
+
it "returns a new scope" do
|
283
|
+
subject.select(:author).should be_an_instance_of(Scope)
|
284
|
+
end
|
284
285
|
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
286
|
+
it "is not loaded" do
|
287
|
+
subject.to_a
|
288
|
+
subject.select(:author).should_not be_loaded
|
289
|
+
end
|
290
|
+
|
291
|
+
it "adds individual select values" do
|
292
|
+
select_scope = subject.select(:author)
|
293
|
+
select_scope.select_values.should == subject.select_values + [:author]
|
294
|
+
end
|
289
295
|
|
290
|
-
|
291
|
-
|
292
|
-
|
296
|
+
it "adds multiple select values" do
|
297
|
+
select_scope = subject.select(:author, :published)
|
298
|
+
select_scope.select_values.should == subject.select_values + [:author, :published]
|
299
|
+
end
|
293
300
|
end
|
294
301
|
|
295
|
-
|
296
|
-
|
297
|
-
|
302
|
+
context "when a block given" do
|
303
|
+
it "passed block to to_a#select" do
|
304
|
+
blk = lambda { |*args| true }
|
305
|
+
subject.to_a.should_receive(:select).with(&blk)
|
306
|
+
subject.select(&blk)
|
307
|
+
end
|
298
308
|
end
|
299
309
|
end
|
300
310
|
|
@@ -780,7 +790,7 @@ module MongoModel
|
|
780
790
|
it "loads total entries using count when auto-detection not possible" do
|
781
791
|
paginator = nil
|
782
792
|
|
783
|
-
subject.stub
|
793
|
+
subject.stub(:count).and_return(57)
|
784
794
|
model.should_find(finder_options.merge(:offset => 0, :limit => 5), posts) {
|
785
795
|
paginator = subject.paginate(:per_page => 5)
|
786
796
|
}
|
@@ -4,13 +4,13 @@ module DocumentFinderStubs
|
|
4
4
|
include RSpec::Mocks::ExampleMethods
|
5
5
|
|
6
6
|
def stub_find(result)
|
7
|
-
find_result =
|
8
|
-
collection.stub
|
7
|
+
find_result = double('find result', :to_a => result.map { |doc| doc.to_mongo }, :count => result.size).as_null_object
|
8
|
+
collection.stub(:find).and_return(find_result)
|
9
9
|
end
|
10
10
|
|
11
11
|
def should_find(expected={}, result=[])
|
12
12
|
selector, options = MongoModel::MongoOptions.new(self, expected).to_a
|
13
|
-
find_result =
|
13
|
+
find_result = double('find result', :to_a => result.map { |doc| doc.to_mongo }).as_null_object
|
14
14
|
collection.should_receive(:find).once.with(selector, options).and_return(find_result)
|
15
15
|
yield if block_given?
|
16
16
|
end
|
@@ -22,7 +22,7 @@ module DocumentFinderStubs
|
|
22
22
|
|
23
23
|
def should_count(expected={}, result=[])
|
24
24
|
selector, options = MongoModel::MongoOptions.new(self, expected).to_a
|
25
|
-
find_result =
|
25
|
+
find_result = double('find result', :count => result).as_null_object
|
26
26
|
collection.should_receive(:find).once.with(selector, options).and_return(find_result)
|
27
27
|
yield if block_given?
|
28
28
|
end
|
@@ -33,7 +33,7 @@ module DocumentFinderStubs
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def stub_delete
|
36
|
-
collection.stub
|
36
|
+
collection.stub(:remove)
|
37
37
|
end
|
38
38
|
|
39
39
|
def should_delete(conditions={})
|
@@ -4,7 +4,7 @@ RSpec::Matchers.define(:find_with) do |find_options|
|
|
4
4
|
match do |klass|
|
5
5
|
selector, options = MongoModel::MongoOptions.new(klass, find_options).to_a
|
6
6
|
|
7
|
-
result =
|
7
|
+
result = double('find result', :to_a => (@result || []).map { |d| d.to_mongo })
|
8
8
|
klass.collection.should_receive(:find).once.with(selector, options).and_return(result)
|
9
9
|
|
10
10
|
true
|
@@ -21,7 +21,7 @@ RSpec::Matchers.define(:count_with) do |find_options|
|
|
21
21
|
|
22
22
|
match do |klass|
|
23
23
|
selector, options = MongoModel::MongoOptions.new(klass, find_options).to_a
|
24
|
-
result =
|
24
|
+
result = double('find result')
|
25
25
|
|
26
26
|
klass.collection.should_receive(:find).once.with(selector, options).and_return(result)
|
27
27
|
result.should_receive(:count).once.and_return(@count || 5)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongomodel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-08-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -116,7 +116,7 @@ extensions: []
|
|
116
116
|
extra_rdoc_files: []
|
117
117
|
files:
|
118
118
|
- .gitignore
|
119
|
-
-
|
119
|
+
- .travis.yml
|
120
120
|
- Gemfile
|
121
121
|
- Guardfile
|
122
122
|
- LICENSE
|
@@ -148,6 +148,7 @@ files:
|
|
148
148
|
- lib/mongomodel/concerns/attribute_methods.rb
|
149
149
|
- lib/mongomodel/concerns/attribute_methods/before_type_cast.rb
|
150
150
|
- lib/mongomodel/concerns/attribute_methods/dirty.rb
|
151
|
+
- lib/mongomodel/concerns/attribute_methods/forbidden.rb
|
151
152
|
- lib/mongomodel/concerns/attribute_methods/multi_parameter_assignment.rb
|
152
153
|
- lib/mongomodel/concerns/attribute_methods/nested.rb
|
153
154
|
- lib/mongomodel/concerns/attribute_methods/protected.rb
|
@@ -196,6 +197,7 @@ files:
|
|
196
197
|
- lib/mongomodel/support/paginator.rb
|
197
198
|
- lib/mongomodel/support/reference.rb
|
198
199
|
- lib/mongomodel/support/scope.rb
|
200
|
+
- lib/mongomodel/support/scope/array_methods.rb
|
199
201
|
- lib/mongomodel/support/scope/batches.rb
|
200
202
|
- lib/mongomodel/support/scope/dynamic_finders.rb
|
201
203
|
- lib/mongomodel/support/scope/finder_methods.rb
|
@@ -300,7 +302,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
300
302
|
version: '0'
|
301
303
|
segments:
|
302
304
|
- 0
|
303
|
-
hash: -
|
305
|
+
hash: -3084382199068025224
|
304
306
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
305
307
|
none: false
|
306
308
|
requirements:
|
data/Appraisals
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
RAILS_3_1 = "3.1.10"
|
2
|
-
RAILS_3_2 = "3.2.11"
|
3
|
-
|
4
|
-
appraise "rails-3.1" do
|
5
|
-
gem "activesupport", RAILS_3_1
|
6
|
-
gem "activemodel", RAILS_3_1
|
7
|
-
end
|
8
|
-
|
9
|
-
appraise "rails-3.2" do
|
10
|
-
gem "activesupport", RAILS_3_2
|
11
|
-
gem "activemodel", RAILS_3_2
|
12
|
-
end
|
13
|
-
|
14
|
-
if RUBY_VERSION >= "1.9"
|
15
|
-
appraise "rails-4" do
|
16
|
-
gem "activesupport", :git => "https://github.com/rails/rails.git"
|
17
|
-
gem "activemodel", :git => "https://github.com/rails/rails.git"
|
18
|
-
gem "journey", :git => "https://github.com/rails/journey.git"
|
19
|
-
end
|
20
|
-
|
21
|
-
appraise "rails-4-protected-attributes" do
|
22
|
-
gem "activesupport", :git => "https://github.com/rails/rails.git"
|
23
|
-
gem "activemodel", :git => "https://github.com/rails/rails.git"
|
24
|
-
gem "protected_attributes", :git=>"https://github.com/rails/protected_attributes.git"
|
25
|
-
gem "journey", :git => "https://github.com/rails/journey.git"
|
26
|
-
end
|
27
|
-
|
28
|
-
appraise "rails-4-observers" do
|
29
|
-
gem "activesupport", :git => "https://github.com/rails/rails.git"
|
30
|
-
gem "activemodel", :git => "https://github.com/rails/rails.git"
|
31
|
-
gem "rails-observers", :git => "https://github.com/rails/rails-observers.git"
|
32
|
-
gem "journey", :git => "https://github.com/rails/journey.git"
|
33
|
-
end
|
34
|
-
|
35
|
-
appraise "mongoid" do
|
36
|
-
gem "mongoid"
|
37
|
-
gem "activesupport", RAILS_3_2
|
38
|
-
gem "activemodel", RAILS_3_2
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
appraise "mongo_mapper" do
|
43
|
-
gem "mongo_mapper"
|
44
|
-
gem "activesupport", RAILS_3_2
|
45
|
-
gem "activemodel", RAILS_3_2
|
46
|
-
end
|