mongoid-rspec-mongoid-rc 1.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ ---
2
+ BUNDLE_WITHOUT: ""
3
+ BUNDLE_DISABLE_SHARED_GEMS: "1"
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm 1.9.2
data/Gemfile ADDED
@@ -0,0 +1 @@
1
+ gemspec
@@ -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.
@@ -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
@@ -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,9 @@
1
+ module Mongoid
2
+ module Matchers
3
+ module Validations
4
+ def validate_length_of(field)
5
+ HaveValidationMatcher.new(field, :length)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Mongoid
2
+ module Matchers
3
+ module Validations
4
+ def validate_numericality_of(field)
5
+ HaveValidationMatcher.new(field, :numericality)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Mongoid
2
+ module Matchers
3
+ module Validations
4
+ def validate_presence_of(field)
5
+ HaveValidationMatcher.new(field, :presence)
6
+ end
7
+ end
8
+ end
9
+ 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
+
@@ -0,0 +1,6 @@
1
+ class Comment
2
+ include Mongoid::Document
3
+
4
+ embedded_in :article, :inverse_of => :comments
5
+ referenced_in :user, :inverse_of => :comments
6
+ end
@@ -0,0 +1,11 @@
1
+ class Profile
2
+ include Mongoid::Document
3
+
4
+ field :first_name
5
+ field :last_name
6
+ field :age
7
+
8
+ embedded_in :user, :inverse_of => :profile
9
+
10
+ validates_numericality_of :age
11
+ end
@@ -0,0 +1,10 @@
1
+ class Site
2
+ include Mongoid::Document
3
+
4
+ field :name
5
+
6
+ references_many :users, :inverse_of => :site
7
+
8
+ validates :name, :presence => true, :uniqueness => true
9
+
10
+ end
@@ -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
@@ -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,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Document" do
4
+ describe User do
5
+ it { should have_fields(:email, :login) }
6
+ end
7
+
8
+ describe Article do
9
+ it { should have_field(:published).of_type(Boolean).with_default_value_of(false) }
10
+ end
11
+ 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