mongoid-rspec-mongoid-rc 1.3.2
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/.bundle/config +3 -0
- data/.document +5 -0
- data/.rvmrc +1 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +43 -0
- data/LICENSE +20 -0
- data/README.markdown +66 -0
- data/Rakefile +47 -0
- data/VERSION +1 -0
- data/lib/matchers/associations.rb +151 -0
- data/lib/matchers/document.rb +95 -0
- data/lib/matchers/validations.rb +41 -0
- data/lib/matchers/validations/associated.rb +19 -0
- data/lib/matchers/validations/format_of.rb +71 -0
- data/lib/matchers/validations/inclusion_of.rb +42 -0
- data/lib/matchers/validations/length_of.rb +9 -0
- data/lib/matchers/validations/numericality_of.rb +9 -0
- data/lib/matchers/validations/presence_of.rb +9 -0
- data/lib/matchers/validations/uniqueness_of.rb +99 -0
- data/lib/mongoid-rspec.rb +21 -0
- data/mongoid-rspec.gemspec +83 -0
- data/spec/models/article.rb +15 -0
- data/spec/models/comment.rb +6 -0
- data/spec/models/profile.rb +11 -0
- data/spec/models/site.rb +10 -0
- data/spec/models/user.rb +23 -0
- data/spec/spec_helper.rb +32 -0
- data/spec/unit/associations_spec.rb +28 -0
- data/spec/unit/document_spec.rb +11 -0
- data/spec/unit/validations_spec.rb +25 -0
- metadata +129 -0
data/.bundle/config
ADDED
data/.document
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm 1.9.2
|
data/Gemfile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
gemspec
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
mongoid-rspec (1.3.2)
|
5
|
+
mongoid (~> 2.0.0)
|
6
|
+
rspec (~> 2)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
specs:
|
10
|
+
activemodel (3.0.3)
|
11
|
+
activesupport (= 3.0.3)
|
12
|
+
builder (~> 2.1.2)
|
13
|
+
i18n (~> 0.4)
|
14
|
+
activesupport (3.0.3)
|
15
|
+
bson (1.1.5)
|
16
|
+
builder (2.1.2)
|
17
|
+
diff-lcs (1.1.2)
|
18
|
+
i18n (0.5.0)
|
19
|
+
mongo (1.1.5)
|
20
|
+
bson (>= 1.1.5)
|
21
|
+
mongoid (2.0.0.rc.1)
|
22
|
+
activemodel (~> 3.0)
|
23
|
+
mongo (~> 1.1)
|
24
|
+
tzinfo (~> 0.3.22)
|
25
|
+
will_paginate (~> 3.0.pre)
|
26
|
+
rspec (2.4.0)
|
27
|
+
rspec-core (~> 2.4.0)
|
28
|
+
rspec-expectations (~> 2.4.0)
|
29
|
+
rspec-mocks (~> 2.4.0)
|
30
|
+
rspec-core (2.4.0)
|
31
|
+
rspec-expectations (2.4.0)
|
32
|
+
diff-lcs (~> 1.1.2)
|
33
|
+
rspec-mocks (2.4.0)
|
34
|
+
tzinfo (0.3.23)
|
35
|
+
will_paginate (3.0.pre2)
|
36
|
+
|
37
|
+
PLATFORMS
|
38
|
+
ruby
|
39
|
+
|
40
|
+
DEPENDENCIES
|
41
|
+
mongoid (~> 2.0.0)
|
42
|
+
mongoid-rspec!
|
43
|
+
rspec (~> 2)
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Evan Sagge
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
mongoid-rspec
|
2
|
+
=
|
3
|
+
|
4
|
+
RSpec matchers for Mongoid.
|
5
|
+
|
6
|
+
|
7
|
+
Association Matchers
|
8
|
+
-
|
9
|
+
describe User do
|
10
|
+
it { should reference_many :articles }
|
11
|
+
it { should reference_many :comments }
|
12
|
+
it { should embed_one :profile }
|
13
|
+
it { should reference_many(:children).stored_as(:array) }
|
14
|
+
end
|
15
|
+
|
16
|
+
describe Profile do
|
17
|
+
it { should be_embedded_in(:user).as_inverse_of(:profile) }
|
18
|
+
end
|
19
|
+
|
20
|
+
describe Article do
|
21
|
+
it { should be_referenced_in(:user).as_inverse_of(:articles) }
|
22
|
+
it { should embed_many(:comments) }
|
23
|
+
end
|
24
|
+
|
25
|
+
describe Comment do
|
26
|
+
it { should be_embedded_in(:article).as_inverse_of(:comments) }
|
27
|
+
it { should be_referenced_in(:user).as_inverse_of(:comments) }
|
28
|
+
end
|
29
|
+
|
30
|
+
Validation Matchers
|
31
|
+
-
|
32
|
+
describe User do
|
33
|
+
it { should validate_presence_of(:login) }
|
34
|
+
it { should validate_uniqueness_of(:login) }
|
35
|
+
it { should validate_format_of(:login).to_allow("valid_login").not_to_allow("invalid login") }
|
36
|
+
it { should validate_associated(:profile) }
|
37
|
+
it { should validate_inclusion_of(:role).to_allow("admin", "member") }
|
38
|
+
it { should validate_numericality_of(:age) }
|
39
|
+
end
|
40
|
+
|
41
|
+
describe Article do
|
42
|
+
it { should validate_length_of(:title) }
|
43
|
+
end
|
44
|
+
|
45
|
+
Others
|
46
|
+
-
|
47
|
+
describe User do
|
48
|
+
it { should have_fields(:email, :login) }
|
49
|
+
it { should have_field(:active).of_type(Boolean).with_default_value_of(false) }
|
50
|
+
it { should have_fields(:birthdate, :registered_at).of_type(DateTime) }
|
51
|
+
|
52
|
+
# useful if you use factory_girl and have Factory(:user) defined for User
|
53
|
+
it { should save }
|
54
|
+
end
|
55
|
+
|
56
|
+
Use
|
57
|
+
-
|
58
|
+
add in Gemfile
|
59
|
+
|
60
|
+
gem 'mongoid-rspec'
|
61
|
+
|
62
|
+
drop in existing or dedicated support file in spec/support (spec/support/mongoid.rb)
|
63
|
+
|
64
|
+
RSpec.configure do |configuration|
|
65
|
+
configuration.include Mongoid::Matchers
|
66
|
+
end
|
data/Rakefile
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "mongoid-rspec"
|
8
|
+
gem.summary = %Q{RSpec matchers for Mongoid}
|
9
|
+
gem.description = %Q{RSpec matches for Mongoid models, including association and validation matchers}
|
10
|
+
gem.email = "evansagge@gmail.com"
|
11
|
+
gem.homepage = "http://github.com/evansagge/mongoid-rspec"
|
12
|
+
gem.authors = ["Evan Sagge"]
|
13
|
+
gem.add_dependency "mongoid", "~> 2.0.0"
|
14
|
+
gem.add_dependency "rspec", "~> 2"
|
15
|
+
end
|
16
|
+
Jeweler::GemcutterTasks.new
|
17
|
+
rescue LoadError
|
18
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'rspec/core'
|
22
|
+
require 'rspec/core/rake_task'
|
23
|
+
|
24
|
+
task :default => :spec
|
25
|
+
|
26
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
27
|
+
spec.pattern = "./spec/**/*_spec.rb"
|
28
|
+
end
|
29
|
+
|
30
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
31
|
+
spec.pattern = "./spec/**/*_spec.rb"
|
32
|
+
spec.rcov = true
|
33
|
+
end
|
34
|
+
|
35
|
+
# task :spec => :check_dependencies
|
36
|
+
|
37
|
+
require 'rake/rdoctask'
|
38
|
+
Rake::RDocTask.new do |rdoc|
|
39
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
40
|
+
|
41
|
+
rdoc.rdoc_dir = 'rdoc'
|
42
|
+
rdoc.title = "mongoid-rspec #{version}"
|
43
|
+
rdoc.rdoc_files.include('README*')
|
44
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
45
|
+
end
|
46
|
+
|
47
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.3.2
|
@@ -0,0 +1,151 @@
|
|
1
|
+
require 'mongoid/relations'
|
2
|
+
|
3
|
+
module Mongoid
|
4
|
+
module Matchers
|
5
|
+
module Associations
|
6
|
+
|
7
|
+
HAS_MANY = Mongoid::Relations::Referenced::Many
|
8
|
+
HAS_AND_BELONGS_TO_MANY = Mongoid::Relations::Referenced::ManyToMany
|
9
|
+
HAS_ONE = Mongoid::Relations::Referenced::One
|
10
|
+
BELONGS_TO = Mongoid::Relations::Referenced::In
|
11
|
+
EMBEDS_MANY = Mongoid::Relations::Embedded::Many
|
12
|
+
EMBEDS_ONE = Mongoid::Relations::Embedded::One
|
13
|
+
EMBEDDED_IN = Mongoid::Relations::Embedded::In
|
14
|
+
|
15
|
+
|
16
|
+
class HaveAssociationMatcher
|
17
|
+
def initialize(name, association_type)
|
18
|
+
@association = {}
|
19
|
+
@association[:name] = name.to_s
|
20
|
+
@association[:type] = association_type
|
21
|
+
# begin
|
22
|
+
# @association[:class] = name.to_s.classify.constantize
|
23
|
+
# rescue
|
24
|
+
# end
|
25
|
+
@expectation_message = "#{type_description} #{@association[:name].inspect}"
|
26
|
+
@expectation_message << " of type #{@association[:class].inspect}" unless @association[:class].nil?
|
27
|
+
end
|
28
|
+
|
29
|
+
def of_type(klass)
|
30
|
+
@association[:class] = klass
|
31
|
+
@expectation_message << " of type #{@association[:class].inspect}"
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def as_inverse_of(association_inverse_name)
|
36
|
+
raise "#{@association[:type].inspect} does not respond to :inverse_of" unless [BELONGS_TO, EMBEDDED_IN].include?(@association[:type])
|
37
|
+
@association[:inverse_of] = association_inverse_name.to_s
|
38
|
+
@expectation_message << " which is an inverse of #{@association[:inverse_of].inspect}"
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
42
|
+
def matches?(actual)
|
43
|
+
@actual = actual.is_a?(Class) ? actual : actual.class
|
44
|
+
metadata = @actual.relations[@association[:name]]
|
45
|
+
|
46
|
+
if metadata.nil?
|
47
|
+
@negative_result_message = "no association named #{@association[:name]}"
|
48
|
+
return false
|
49
|
+
else
|
50
|
+
@positive_result_message = "association named #{@association[:name]}"
|
51
|
+
end
|
52
|
+
|
53
|
+
relation = metadata.relation
|
54
|
+
if relation != @association[:type]
|
55
|
+
@negative_result_message = "#{@actual.inspect} #{type_description(relation, false)} #{@association[:name]}"
|
56
|
+
return false
|
57
|
+
else
|
58
|
+
@positive_result_message = "#{@actual.inspect} #{type_description(relation, false)} #{@association[:name]}"
|
59
|
+
end
|
60
|
+
|
61
|
+
if !@association[:class].nil? and @association[:class] != metadata.klass
|
62
|
+
@negative_result_message = "#{@positive_result_message} of type #{metadata.klass.inspect}"
|
63
|
+
return false
|
64
|
+
else
|
65
|
+
@positive_result_message = "#{@positive_result_message} of type #{metadata.klass.inspect}"
|
66
|
+
end
|
67
|
+
|
68
|
+
if @association[:inverse_of]
|
69
|
+
if @association[:inverse_of].to_s != metadata.inverse_of.to_s
|
70
|
+
@negative_result_message = "#{@positive_result_message} which is an inverse of #{metadata.inverse_of}"
|
71
|
+
return false
|
72
|
+
else
|
73
|
+
@positive_result_message = "#{@positive_result_message} which is an inverse of #{metadata.inverse_of}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
true
|
78
|
+
end
|
79
|
+
|
80
|
+
def failure_message_for_should
|
81
|
+
"Expected #{@actual.inspect} to #{@expectation_message}, got #{@negative_result_message}"
|
82
|
+
end
|
83
|
+
|
84
|
+
def failure_message_for_should_not
|
85
|
+
"Expected #{@actual.inspect} to not #{@expectation_message}, got #{@positive_result_message}"
|
86
|
+
end
|
87
|
+
|
88
|
+
def description
|
89
|
+
@expectation_message
|
90
|
+
end
|
91
|
+
|
92
|
+
def type_description(type = nil, passive = true)
|
93
|
+
type ||= @association[:type]
|
94
|
+
case type.name
|
95
|
+
when EMBEDS_ONE.name
|
96
|
+
(passive ? 'embed' : 'embeds') << ' one'
|
97
|
+
when EMBEDS_MANY.name
|
98
|
+
(passive ? 'embed' : 'embeds') << ' many'
|
99
|
+
when EMBEDDED_IN.name
|
100
|
+
(passive ? 'be' : 'is') << ' embedded in'
|
101
|
+
when HAS_ONE.name
|
102
|
+
(passive ? 'reference' : 'references') << ' one'
|
103
|
+
when HAS_MANY.name
|
104
|
+
(passive ? 'reference' : 'references') << ' many'
|
105
|
+
when HAS_AND_BELONGS_TO_MANY.name
|
106
|
+
(passive ? 'reference' : 'references') << ' and referenced in many'
|
107
|
+
when BELONGS_TO.name
|
108
|
+
(passive ? 'be referenced in' : 'referenced in')
|
109
|
+
else
|
110
|
+
raise "Unknown association type '%s'" % type
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def embed_one(association_name)
|
116
|
+
HaveAssociationMatcher.new(association_name, EMBEDS_ONE)
|
117
|
+
end
|
118
|
+
|
119
|
+
def embed_many(association_name)
|
120
|
+
HaveAssociationMatcher.new(association_name, EMBEDS_MANY)
|
121
|
+
end
|
122
|
+
|
123
|
+
def be_embedded_in(association_name)
|
124
|
+
HaveAssociationMatcher.new(association_name, EMBEDDED_IN)
|
125
|
+
end
|
126
|
+
|
127
|
+
def have_one_related(association_name)
|
128
|
+
HaveAssociationMatcher.new(association_name, HAS_ONE)
|
129
|
+
end
|
130
|
+
alias :reference_one :have_one_related
|
131
|
+
alias :have_one :have_one_related
|
132
|
+
|
133
|
+
def have_many_related(association_name)
|
134
|
+
HaveAssociationMatcher.new(association_name, HAS_MANY)
|
135
|
+
end
|
136
|
+
alias :reference_many :have_many_related
|
137
|
+
alias :have_many :have_many_related
|
138
|
+
|
139
|
+
def have_and_belong_to_many(association_name)
|
140
|
+
HaveAssociationMatcher.new(association_name, HAS_AND_BELONGS_TO_MANY)
|
141
|
+
end
|
142
|
+
alias :reference_and_be_referenced_in_many :have_and_belong_to_many
|
143
|
+
|
144
|
+
def belong_to_related(association_name)
|
145
|
+
HaveAssociationMatcher.new(association_name, BELONGS_TO)
|
146
|
+
end
|
147
|
+
alias :be_referenced_in :belong_to_related
|
148
|
+
alias :belong_to :belong_to_related
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module Matchers
|
3
|
+
class HaveFieldMatcher # :nodoc:
|
4
|
+
def initialize(*attrs)
|
5
|
+
@attributes = attrs.collect(&:to_s)
|
6
|
+
end
|
7
|
+
|
8
|
+
def of_type(type)
|
9
|
+
@type = type
|
10
|
+
self
|
11
|
+
end
|
12
|
+
|
13
|
+
def with_default_value_of(default)
|
14
|
+
@default = default
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
def matches?(klass)
|
19
|
+
@klass = klass.is_a?(Class) ? klass : klass.class
|
20
|
+
@errors = []
|
21
|
+
@attributes.each do |attr|
|
22
|
+
if @klass.fields.include?(attr)
|
23
|
+
error = ""
|
24
|
+
if @type and @klass.fields[attr].type != @type
|
25
|
+
error << " of type #{@klass.fields[attr].type}"
|
26
|
+
end
|
27
|
+
|
28
|
+
if @default and @klass.fields[attr].default != @default
|
29
|
+
error << " with default value of #{@klass.fields[attr].default}"
|
30
|
+
end
|
31
|
+
|
32
|
+
@errors.push("field #{attr.inspect}" << error) unless error.blank?
|
33
|
+
else
|
34
|
+
@errors.push "no field named #{attr.inspect}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
@errors.empty?
|
38
|
+
end
|
39
|
+
|
40
|
+
def failure_message_for_should
|
41
|
+
"Expected #{@klass.inspect} to #{description}, got #{@errors.to_sentence}"
|
42
|
+
end
|
43
|
+
|
44
|
+
def failure_message_for_should_not
|
45
|
+
"Expected #{@klass.inspect} to not #{description}, got #{@klass.inspect} to #{description}"
|
46
|
+
end
|
47
|
+
|
48
|
+
def description
|
49
|
+
desc = "have #{@attributes.size > 1 ? 'fields' : 'field'} named #{@attributes.collect(&:inspect).to_sentence}"
|
50
|
+
desc << " of type #{@type.inspect}" if @type
|
51
|
+
desc << " with default value of #{@default.inspect}" if @default
|
52
|
+
desc
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def have_field(*args)
|
57
|
+
HaveFieldMatcher.new(*args)
|
58
|
+
end
|
59
|
+
alias_method :have_fields, :have_field
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
RSpec::Matchers.define :have_instance_method do |name|
|
64
|
+
match do |klass|
|
65
|
+
klass.instance_methods.include?(name.to_sym)
|
66
|
+
end
|
67
|
+
|
68
|
+
description do
|
69
|
+
"have instance method #{name.to_s}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
RSpec::Matchers.define :be_mongoid_document do
|
74
|
+
match do |doc|
|
75
|
+
doc.class.included_modules.should include(Mongoid::Document)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
RSpec::Matchers.define :be_versioned_document do
|
80
|
+
match do |doc|
|
81
|
+
doc.class.included_modules.should include(Mongoid::Versioning)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
RSpec::Matchers.define :be_timestamped_document do
|
86
|
+
match do |doc|
|
87
|
+
doc.class.included_modules.should include(Mongoid::Timestamps)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
RSpec::Matchers.define :be_paranoid_document do
|
92
|
+
match do |doc|
|
93
|
+
doc.class.included_modules.should include(Mongoid::Paranoia)
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module Matchers
|
3
|
+
module Validations
|
4
|
+
|
5
|
+
class HaveValidationMatcher
|
6
|
+
|
7
|
+
def initialize(field, validation_type)
|
8
|
+
@field = field.to_s
|
9
|
+
@type = validation_type.to_s
|
10
|
+
end
|
11
|
+
|
12
|
+
def matches?(actual)
|
13
|
+
@klass = actual.is_a?(Class) ? actual : actual.class
|
14
|
+
|
15
|
+
@validator = @klass.validators_on(@field).detect{|v| v.kind.to_s == @type }
|
16
|
+
|
17
|
+
if @validator
|
18
|
+
@negative_result_message = @positive_result_message = "#{@type.inspect} validator on #{@field.inspect}"
|
19
|
+
else
|
20
|
+
@negative_result_message = "no #{@type.inspect} validator on #{@field.inspect}"
|
21
|
+
return false
|
22
|
+
end
|
23
|
+
|
24
|
+
true
|
25
|
+
end
|
26
|
+
|
27
|
+
def failure_message_for_should
|
28
|
+
"Expected #{@klass.inspect} to #{description}, got #{@negative_result_message}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def failure_message_for_should_not
|
32
|
+
"Expected #{@klass.inspect} to not #{description}, got #{@positive_result_message}"
|
33
|
+
end
|
34
|
+
|
35
|
+
def description
|
36
|
+
"validate #{@type} of #{@field.inspect}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module Matchers
|
3
|
+
module Validations
|
4
|
+
class ValidateAssociatedMatcher < HaveValidationMatcher
|
5
|
+
def initialize(name)
|
6
|
+
super(name, :associated)
|
7
|
+
end
|
8
|
+
|
9
|
+
def description
|
10
|
+
"validate associated #{@field.inspect}"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def validate_associated(association_name)
|
15
|
+
ValidateAssociatedMatcher.new(association_name)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module Matchers
|
3
|
+
module Validations
|
4
|
+
class ValidateFormatOfMatcher < HaveValidationMatcher
|
5
|
+
def initialize(field)
|
6
|
+
super(field, :format)
|
7
|
+
end
|
8
|
+
|
9
|
+
def with_format(format)
|
10
|
+
@format = format
|
11
|
+
self
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_allow(valid_value)
|
15
|
+
@valid_value = valid_value
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
def not_to_allow(invalid_value)
|
20
|
+
@invalid_value = invalid_value
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
def matches?(actual)
|
25
|
+
return false unless result = super(actual)
|
26
|
+
|
27
|
+
if @format
|
28
|
+
if @validator.options[:with] == @format
|
29
|
+
@positive_result_message = @positive_result_message << " with format #{@validator.options[:format].inspect}"
|
30
|
+
else
|
31
|
+
@negative_result_message = @negative_result_message << " with format #{@validator.options[:format].inspect}"
|
32
|
+
result = false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
if @valid_value
|
37
|
+
if @validator.options[:with] =~ @valid_value
|
38
|
+
@positive_result_message = @positive_result_message << " with #{@valid_value.inspect} as a valid value"
|
39
|
+
else
|
40
|
+
@negative_result_message = @negative_result_message << " with #{@valid_value.inspect} as an invalid value"
|
41
|
+
result = false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
if @invalid_value
|
46
|
+
if !(@invalid_value =~ @validator.options[:with])
|
47
|
+
@positive_result_message = @positive_result_message << " with #{@invalid_value.inspect} as an invalid value"
|
48
|
+
else
|
49
|
+
@negative_result_message = @negative_result_message << " with #{@invalid_value.inspect} as a valid value"
|
50
|
+
result = false
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
result
|
55
|
+
end
|
56
|
+
|
57
|
+
def description
|
58
|
+
options_desc = []
|
59
|
+
options_desc << " with format #{@format.inspect}" if @format
|
60
|
+
options_desc << " allowing the value #{@valid_value.inspect}" if @valid_value
|
61
|
+
options_desc << " not allowing the value #{@invalid_value.inspect}" if @invalid_value
|
62
|
+
super << options_desc.to_sentence
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def validate_format_of(field)
|
67
|
+
ValidateFormatOfMatcher.new(field)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module Matchers
|
3
|
+
module Validations
|
4
|
+
class ValidateInclusionOfMatcher < HaveValidationMatcher
|
5
|
+
def initialize(name)
|
6
|
+
super(name, :inclusion)
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_allow(*values)
|
10
|
+
@allowed_values = [values].flatten
|
11
|
+
self
|
12
|
+
end
|
13
|
+
|
14
|
+
def matches?(actual)
|
15
|
+
return false unless result = super(actual)
|
16
|
+
|
17
|
+
if @allowed_values
|
18
|
+
not_allowed_values = @allowed_values - @validator.options[:in]
|
19
|
+
if not_allowed_values.empty?
|
20
|
+
@positive_result_message = @positive_result_message << " allowing all values mentioned"
|
21
|
+
else
|
22
|
+
@negative_result_message = @negative_result_message << " not allowing the following the ff. values: #{not_allowed_values.inspect}"
|
23
|
+
result = false
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
result
|
28
|
+
end
|
29
|
+
|
30
|
+
def description
|
31
|
+
options_desc = []
|
32
|
+
options_desc << " allowing the ff. values: #{@allowed_values}" if @allowed_values
|
33
|
+
super << options_desc.to_sentence
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def validate_inclusion_of(field)
|
38
|
+
ValidateInclusionOfMatcher.new(field)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module Matchers
|
3
|
+
module Validations
|
4
|
+
class ValidateUniquenessOfMatcher < HaveValidationMatcher
|
5
|
+
def initialize(field)
|
6
|
+
super(field, :uniqueness)
|
7
|
+
end
|
8
|
+
|
9
|
+
def scoped_to(*scope)
|
10
|
+
@scope = [scope].flatten
|
11
|
+
self
|
12
|
+
end
|
13
|
+
alias_method :scoped_on, :scoped_to
|
14
|
+
|
15
|
+
def case_insensitive
|
16
|
+
@case_insensitive = true
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def allow_blank?(allow_blank)
|
21
|
+
@allow_blank = allow_blank
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def with_message(message)
|
26
|
+
@expected_message = message
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
def matches?(actual)
|
31
|
+
return false unless @result = super(actual)
|
32
|
+
|
33
|
+
check_scope if @scope
|
34
|
+
check_allow_blank if @allow_blank
|
35
|
+
check_case_sensitivity if @case_insensitive
|
36
|
+
check_expected_message if @expected_message
|
37
|
+
|
38
|
+
@result
|
39
|
+
end
|
40
|
+
|
41
|
+
def description
|
42
|
+
options_desc = []
|
43
|
+
options_desc << " scoped to #{@scope.inspect}" if @scope
|
44
|
+
options_desc << " allowing blank values" if @allow_blank
|
45
|
+
options_desc << " allowing case insensitive values" if @case_insensitive
|
46
|
+
options_desc << " with message '#{@expected_message}'" if @case_insensitive
|
47
|
+
super << options_desc.to_sentence
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def check_allow_blank
|
53
|
+
if @validator.options[:allow_blank] == @allow_blank
|
54
|
+
@positive_result_message << " with blank values allowed"
|
55
|
+
else
|
56
|
+
@negative_result_message << " with no blank values allowed"
|
57
|
+
@result = false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def check_scope
|
62
|
+
message = "scope to #{@validator.options[:scope]}"
|
63
|
+
if [@validator.options[:scope]].flatten == @scope
|
64
|
+
@positive_result_message << message
|
65
|
+
else
|
66
|
+
@negative_result_message << message
|
67
|
+
@result = false
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def check_case_sensitivity
|
72
|
+
if @validator.options[:case_sensitive] == false
|
73
|
+
@positive_result_message << " with case insensitive values"
|
74
|
+
else
|
75
|
+
@negative_result_message << " without case insensitive values"
|
76
|
+
@result = false
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def check_expected_message
|
81
|
+
actual_message = @validator.options[:message]
|
82
|
+
if actual_message.nil?
|
83
|
+
@negative_result_message << " with no custom message"
|
84
|
+
@result = false
|
85
|
+
elsif actual_message == @expected_message
|
86
|
+
@positive_result_message << " with custom message '#{@expected_message}'"
|
87
|
+
else
|
88
|
+
@negative_result_message << " got message '#{actual_message}'"
|
89
|
+
@result = false
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def validate_uniqueness_of(field)
|
95
|
+
ValidateUniquenessOfMatcher.new(field)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
|
3
|
+
require 'mongoid'
|
4
|
+
require 'rspec'
|
5
|
+
require 'matchers/document'
|
6
|
+
require 'matchers/associations'
|
7
|
+
require 'matchers/validations'
|
8
|
+
require 'matchers/validations/associated'
|
9
|
+
require 'matchers/validations/format_of'
|
10
|
+
require 'matchers/validations/inclusion_of'
|
11
|
+
require 'matchers/validations/length_of'
|
12
|
+
require 'matchers/validations/numericality_of'
|
13
|
+
require 'matchers/validations/presence_of'
|
14
|
+
require 'matchers/validations/uniqueness_of'
|
15
|
+
|
16
|
+
module Mongoid
|
17
|
+
module Matchers
|
18
|
+
include Mongoid::Matchers::Associations
|
19
|
+
include Mongoid::Matchers::Validations
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{mongoid-rspec-mongoid-rc}
|
8
|
+
s.version = "1.3.2"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Evan Sagge"]
|
12
|
+
s.date = %q{2010-11-11}
|
13
|
+
s.description = %q{RSpec matches for Mongoid models, including association and validation matchers}
|
14
|
+
s.email = %q{evansagge@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.markdown"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".bundle/config",
|
21
|
+
".document",
|
22
|
+
".rvmrc",
|
23
|
+
"Gemfile",
|
24
|
+
"Gemfile.lock",
|
25
|
+
"LICENSE",
|
26
|
+
"README.markdown",
|
27
|
+
"Rakefile",
|
28
|
+
"VERSION",
|
29
|
+
"lib/matchers/associations.rb",
|
30
|
+
"lib/matchers/document.rb",
|
31
|
+
"lib/matchers/validations.rb",
|
32
|
+
"lib/matchers/validations/associated.rb",
|
33
|
+
"lib/matchers/validations/format_of.rb",
|
34
|
+
"lib/matchers/validations/inclusion_of.rb",
|
35
|
+
"lib/matchers/validations/length_of.rb",
|
36
|
+
"lib/matchers/validations/numericality_of.rb",
|
37
|
+
"lib/matchers/validations/presence_of.rb",
|
38
|
+
"lib/matchers/validations/uniqueness_of.rb",
|
39
|
+
"lib/mongoid-rspec.rb",
|
40
|
+
"mongoid-rspec.gemspec",
|
41
|
+
"spec/models/article.rb",
|
42
|
+
"spec/models/comment.rb",
|
43
|
+
"spec/models/profile.rb",
|
44
|
+
"spec/models/site.rb",
|
45
|
+
"spec/models/user.rb",
|
46
|
+
"spec/spec_helper.rb",
|
47
|
+
"spec/unit/associations_spec.rb",
|
48
|
+
"spec/unit/document_spec.rb",
|
49
|
+
"spec/unit/validations_spec.rb"
|
50
|
+
]
|
51
|
+
s.homepage = %q{http://github.com/evansagge/mongoid-rspec}
|
52
|
+
s.require_paths = ["lib"]
|
53
|
+
s.rubygems_version = %q{1.3.7}
|
54
|
+
s.summary = %q{RSpec matchers for Mongoid}
|
55
|
+
s.test_files = [
|
56
|
+
"spec/models/article.rb",
|
57
|
+
"spec/models/comment.rb",
|
58
|
+
"spec/models/profile.rb",
|
59
|
+
"spec/models/site.rb",
|
60
|
+
"spec/models/user.rb",
|
61
|
+
"spec/spec_helper.rb",
|
62
|
+
"spec/unit/associations_spec.rb",
|
63
|
+
"spec/unit/document_spec.rb",
|
64
|
+
"spec/unit/validations_spec.rb"
|
65
|
+
]
|
66
|
+
|
67
|
+
if s.respond_to? :specification_version then
|
68
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
69
|
+
s.specification_version = 3
|
70
|
+
|
71
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
72
|
+
s.add_runtime_dependency(%q<mongoid>, ["~> 2.0.0"])
|
73
|
+
s.add_runtime_dependency(%q<rspec>, ["~> 2"])
|
74
|
+
else
|
75
|
+
s.add_dependency(%q<mongoid>, ["~> 2.0.0"])
|
76
|
+
s.add_dependency(%q<rspec>, ["~> 2"])
|
77
|
+
end
|
78
|
+
else
|
79
|
+
s.add_dependency(%q<mongoid>, ["~> 2.0.0"])
|
80
|
+
s.add_dependency(%q<rspec>, ["~> 2"])
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class Article
|
2
|
+
include Mongoid::Document
|
3
|
+
|
4
|
+
field :title
|
5
|
+
field :content
|
6
|
+
field :published, :type => Boolean, :default => false
|
7
|
+
|
8
|
+
embeds_many :comments
|
9
|
+
referenced_in :user, :inverse_of => :articles
|
10
|
+
|
11
|
+
validates :title, :presence => true
|
12
|
+
|
13
|
+
validates_length_of :title, :minimum => 8, :maximum => 16
|
14
|
+
end
|
15
|
+
|
data/spec/models/site.rb
ADDED
data/spec/models/user.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
class User
|
2
|
+
include Mongoid::Document
|
3
|
+
|
4
|
+
field :login
|
5
|
+
field :email
|
6
|
+
field :role
|
7
|
+
|
8
|
+
referenced_in :site, :inverse_of => :users
|
9
|
+
references_one :article
|
10
|
+
references_many :comments
|
11
|
+
references_and_referenced_in_many :children, :class_name => "User"
|
12
|
+
|
13
|
+
embeds_one :profile
|
14
|
+
|
15
|
+
validates :login, :presence => true, :uniqueness => { :scope => :site }, :format => { :with => /^[\w\-]+$/ }
|
16
|
+
validates :email, :uniqueness => { :case_sensitive => false, :scope => :site, :message => "is already taken" }
|
17
|
+
validates :role, :presence => true, :inclusion => { :in => ["admin", "moderator", "member"]}
|
18
|
+
validates :profile, :presence => true, :associated => true
|
19
|
+
|
20
|
+
def admin?
|
21
|
+
false
|
22
|
+
end
|
23
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "lib"))
|
3
|
+
MODELS = File.join(File.dirname(__FILE__), "models")
|
4
|
+
$LOAD_PATH.unshift(MODELS)
|
5
|
+
|
6
|
+
require "rubygems"
|
7
|
+
require "bundler"
|
8
|
+
Bundler.setup
|
9
|
+
|
10
|
+
require 'rspec'
|
11
|
+
require 'rspec/core'
|
12
|
+
require 'rspec/expectations'
|
13
|
+
require 'mongoid'
|
14
|
+
|
15
|
+
Mongoid.configure do |config|
|
16
|
+
name = "mongoid-rspec-test"
|
17
|
+
host = "localhost"
|
18
|
+
config.master = Mongo::Connection.new.db(name)
|
19
|
+
end
|
20
|
+
|
21
|
+
Dir[ File.join(MODELS, "*.rb") ].sort.each { |file| require File.basename(file) }
|
22
|
+
|
23
|
+
require 'mongoid-rspec'
|
24
|
+
|
25
|
+
RSpec.configure do |config|
|
26
|
+
config.include RSpec::Matchers
|
27
|
+
config.include Mongoid::Matchers
|
28
|
+
config.mock_with :rspec
|
29
|
+
config.after :all do
|
30
|
+
Mongoid.master.collections.each(&:drop)
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Associations" do
|
4
|
+
describe User do
|
5
|
+
it { should reference_one :article }
|
6
|
+
it { should have_one :article }
|
7
|
+
it { should reference_many :comments }
|
8
|
+
it { should have_many :comments }
|
9
|
+
it { should embed_one :profile }
|
10
|
+
it { should reference_and_be_referenced_in_many(:children) }
|
11
|
+
it { should have_and_belong_to_many(:children) }
|
12
|
+
end
|
13
|
+
|
14
|
+
describe Profile do
|
15
|
+
it { should be_embedded_in(:user).as_inverse_of(:profile) }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe Article do
|
19
|
+
it { should be_referenced_in(:user).as_inverse_of(:articles) }
|
20
|
+
it { should belong_to(:user).as_inverse_of(:articles) }
|
21
|
+
it { should embed_many(:comments) }
|
22
|
+
end
|
23
|
+
|
24
|
+
describe Comment do
|
25
|
+
it { should be_embedded_in(:article).as_inverse_of(:comments) }
|
26
|
+
it { should be_referenced_in(:user).as_inverse_of(:comments) }
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Validations" do
|
4
|
+
describe Site do
|
5
|
+
it { should validate_presence_of(:name) }
|
6
|
+
it { should validate_uniqueness_of(:name) }
|
7
|
+
end
|
8
|
+
|
9
|
+
describe User do
|
10
|
+
it { should validate_presence_of(:login) }
|
11
|
+
it { should validate_uniqueness_of(:login).scoped_to(:site) }
|
12
|
+
it { should validate_uniqueness_of(:email).case_insensitive.with_message("is already taken") }
|
13
|
+
it { should validate_format_of(:login).to_allow("valid_login").not_to_allow("invalid login") }
|
14
|
+
it { should validate_associated(:profile) }
|
15
|
+
it { should validate_inclusion_of(:role).to_allow("admin", "member") }
|
16
|
+
end
|
17
|
+
|
18
|
+
describe Profile do
|
19
|
+
it { should validate_numericality_of(:age) }
|
20
|
+
end
|
21
|
+
|
22
|
+
describe Article do
|
23
|
+
it { should validate_length_of(:title) }
|
24
|
+
end
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mongoid-rspec-mongoid-rc
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 1
|
7
|
+
- 3
|
8
|
+
- 2
|
9
|
+
version: 1.3.2
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Evan Sagge
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-11-11 00:00:00 +01:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: mongoid
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ~>
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 2
|
30
|
+
- 0
|
31
|
+
- 0
|
32
|
+
version: 2.0.0
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: rspec
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
segments:
|
44
|
+
- 2
|
45
|
+
version: "2"
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
48
|
+
description: RSpec matches for Mongoid models, including association and validation matchers
|
49
|
+
email: evansagge@gmail.com
|
50
|
+
executables: []
|
51
|
+
|
52
|
+
extensions: []
|
53
|
+
|
54
|
+
extra_rdoc_files:
|
55
|
+
- LICENSE
|
56
|
+
- README.markdown
|
57
|
+
files:
|
58
|
+
- .bundle/config
|
59
|
+
- .document
|
60
|
+
- .rvmrc
|
61
|
+
- Gemfile
|
62
|
+
- Gemfile.lock
|
63
|
+
- LICENSE
|
64
|
+
- README.markdown
|
65
|
+
- Rakefile
|
66
|
+
- VERSION
|
67
|
+
- lib/matchers/associations.rb
|
68
|
+
- lib/matchers/document.rb
|
69
|
+
- lib/matchers/validations.rb
|
70
|
+
- lib/matchers/validations/associated.rb
|
71
|
+
- lib/matchers/validations/format_of.rb
|
72
|
+
- lib/matchers/validations/inclusion_of.rb
|
73
|
+
- lib/matchers/validations/length_of.rb
|
74
|
+
- lib/matchers/validations/numericality_of.rb
|
75
|
+
- lib/matchers/validations/presence_of.rb
|
76
|
+
- lib/matchers/validations/uniqueness_of.rb
|
77
|
+
- lib/mongoid-rspec.rb
|
78
|
+
- mongoid-rspec.gemspec
|
79
|
+
- spec/models/article.rb
|
80
|
+
- spec/models/comment.rb
|
81
|
+
- spec/models/profile.rb
|
82
|
+
- spec/models/site.rb
|
83
|
+
- spec/models/user.rb
|
84
|
+
- spec/spec_helper.rb
|
85
|
+
- spec/unit/associations_spec.rb
|
86
|
+
- spec/unit/document_spec.rb
|
87
|
+
- spec/unit/validations_spec.rb
|
88
|
+
has_rdoc: true
|
89
|
+
homepage: http://github.com/evansagge/mongoid-rspec
|
90
|
+
licenses: []
|
91
|
+
|
92
|
+
post_install_message:
|
93
|
+
rdoc_options: []
|
94
|
+
|
95
|
+
require_paths:
|
96
|
+
- lib
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
segments:
|
103
|
+
- 0
|
104
|
+
version: "0"
|
105
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
segments:
|
111
|
+
- 0
|
112
|
+
version: "0"
|
113
|
+
requirements: []
|
114
|
+
|
115
|
+
rubyforge_project:
|
116
|
+
rubygems_version: 1.3.7
|
117
|
+
signing_key:
|
118
|
+
specification_version: 3
|
119
|
+
summary: RSpec matchers for Mongoid
|
120
|
+
test_files:
|
121
|
+
- spec/models/article.rb
|
122
|
+
- spec/models/comment.rb
|
123
|
+
- spec/models/profile.rb
|
124
|
+
- spec/models/site.rb
|
125
|
+
- spec/models/user.rb
|
126
|
+
- spec/spec_helper.rb
|
127
|
+
- spec/unit/associations_spec.rb
|
128
|
+
- spec/unit/document_spec.rb
|
129
|
+
- spec/unit/validations_spec.rb
|