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.
@@ -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