mongoid-rspec 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/.bundle/config ADDED
@@ -0,0 +1,2 @@
1
+ ---
2
+ BUNDLE_WITHOUT: ""
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm 1.9.2-head
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ # A sample Gemfile
2
+ source :gemcutter
3
+
4
+ gem "rails", "3.0.0.beta3"
5
+
6
+ gem "mongoid", "2.0.0.beta4"
7
+ gem "bson_ext", "0.20.1"
8
+
9
+ gem 'redgreen'
10
+
11
+ gem 'rspec-rails', ">= 2.0.0.beta.7"
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.rdoc ADDED
@@ -0,0 +1,3 @@
1
+ = mongoid-rspec
2
+
3
+ RSpec matchers for Mongoid
data/Rakefile ADDED
@@ -0,0 +1,49 @@
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.beta4"
14
+ gem.add_dependency "bson_ext", "0.20.1"
15
+ gem.add_dependency "rspec-rails", ">= 2.0.0.beta.7"
16
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
17
+ end
18
+ Jeweler::GemcutterTasks.new
19
+ rescue LoadError
20
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
21
+ end
22
+
23
+ require 'rspec/core'
24
+ require 'rspec/core/rake_task'
25
+
26
+ task :default => :spec
27
+
28
+ Rspec::Core::RakeTask.new(:spec) do |spec|
29
+ spec.pattern = "./spec/**/*_spec.rb"
30
+ end
31
+
32
+ Rspec::Core::RakeTask.new(:rcov) do |spec|
33
+ spec.pattern = "./spec/**/*_spec.rb"
34
+ spec.rcov = true
35
+ end
36
+
37
+ task :spec => :check_dependencies
38
+
39
+ require 'rake/rdoctask'
40
+ Rake::RDocTask.new do |rdoc|
41
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
42
+
43
+ rdoc.rdoc_dir = 'rdoc'
44
+ rdoc.title = "mongoid-rspec #{version}"
45
+ rdoc.rdoc_files.include('README*')
46
+ rdoc.rdoc_files.include('lib/**/*.rb')
47
+ end
48
+
49
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.0.3
@@ -0,0 +1,126 @@
1
+ module Mongoid
2
+ module Matchers
3
+ module Associations
4
+ class HaveAssociationMatcher
5
+ def initialize(name, association_type)
6
+ @association = {}
7
+ @association[:name] = name.to_s
8
+ @association[:type] = association_type
9
+ begin
10
+ @association[:class] = name.to_s.classify.constantize
11
+ rescue
12
+ end
13
+ @expectation_message = "#{type_description} #{@association[:name].inspect}"
14
+ @expectation_message << " of type #{@association[:class].inspect}"
15
+ end
16
+
17
+ def of_type(klass)
18
+ @association[:class] = klass
19
+ @expectation_message << " of type #{@association[:class].inspect}"
20
+ self
21
+ end
22
+
23
+ def as_inverse_of(association_inverse_name)
24
+ raise "#{@association[:type].inspect} does not respond to :inverse_of" unless [Mongoid::Associations::BelongsToRelated, Mongoid::Associations::EmbeddedIn].include?(@association[:type])
25
+ @association[:inverse_of] = association_inverse_name.to_s
26
+ @expectation_message << " which is an inverse of #{@association[:inverse_of].inspect}"
27
+ self
28
+ end
29
+
30
+ def matches?(actual)
31
+ @actual = actual.is_a?(Class) ? actual : actual.class
32
+ association = @actual.associations[@association[:name]]
33
+
34
+
35
+ if association.nil?
36
+ @negative_result_message = "no association named #{@association[:name]}"
37
+ return false
38
+ else
39
+ @positive_result_message = "association named #{@association[:name]}"
40
+ end
41
+
42
+ if association.association != @association[:type]
43
+ @negative_result_message = "#{@actual.inspect} #{type_description(association.association, false)} #{@association[:name]}"
44
+ return false
45
+ else
46
+ @positive_result_message = "#{@actual.inspect} #{type_description(association.association, false)} #{@association[:name]}"
47
+ end
48
+
49
+ if @association[:class] != association.klass
50
+ @negative_result_message = "#{@positive_result_message} of type #{association.klass.inspect}"
51
+ return false
52
+ else
53
+ @positive_result_message = "#{@positive_result_message} of type #{association.klass.inspect}"
54
+ end
55
+
56
+ if @association[:inverse_of]
57
+ if @association[:inverse_of].to_s != association.inverse_of.to_s
58
+ @negative_result_message = "#{@positive_result_message} which is an inverse of #{association.inverse_of}"
59
+ return false
60
+ else
61
+ @positive_result_message = "#{@positive_result_message} which is an inverse of #{association.inverse_of}"
62
+ end
63
+ end
64
+
65
+ true
66
+ end
67
+
68
+ def failure_message_for_should
69
+ "Expected #{@actual.inspect} to #{@expectation_message}, got #{@negative_result_message}"
70
+ end
71
+
72
+ def failure_message_for_should_not
73
+ "Expected #{@actual.inspect} to not #{@expectation_message}, got #{@positive_result_message}"
74
+ end
75
+
76
+ def description
77
+ @expectation_message
78
+ end
79
+
80
+ def type_description(type = nil, passive = true)
81
+ type ||= @association[:type]
82
+ case type.name
83
+ when "Mongoid::Associations::EmbedsOne"
84
+ (passive ? 'embed' : 'embeds') << ' one'
85
+ when "Mongoid::Associations::EmbedsMany"
86
+ (passive ? 'embed' : 'embeds') << ' many'
87
+ when "Mongoid::Associations::EmbeddedIn"
88
+ (passive ? 'be' : 'is') << ' embedded in'
89
+ when "Mongoid::Associations::HasOneRelated"
90
+ (passive ? 'have' : 'has') << ' one related'
91
+ when "Mongoid::Associations::HasManyRelated"
92
+ (passive ? 'have' : 'has') << ' many related'
93
+ when "Mongoid::Associations::BelongsToRelated"
94
+ (passive ? 'belong' : 'belongs') << ' to related'
95
+ else
96
+ raise "Unknown association type"
97
+ end
98
+ end
99
+ end
100
+
101
+ def embed_one(association_name)
102
+ HaveAssociationMatcher.new(association_name, Mongoid::Associations::EmbedsOne)
103
+ end
104
+
105
+ def embed_many(association_name)
106
+ HaveAssociationMatcher.new(association_name, Mongoid::Associations::EmbedsMany)
107
+ end
108
+
109
+ def be_embedded_in(association_name)
110
+ HaveAssociationMatcher.new(association_name, Mongoid::Associations::EmbeddedIn)
111
+ end
112
+
113
+ def have_one_related(association_name)
114
+ HaveAssociationMatcher.new(association_name, Mongoid::Associations::HasOneRelated)
115
+ end
116
+
117
+ def have_many_related(association_name)
118
+ HaveAssociationMatcher.new(association_name, Mongoid::Associations::HasManyRelated)
119
+ end
120
+
121
+ def belong_to_related(association_name)
122
+ HaveAssociationMatcher.new(association_name, Mongoid::Associations::BelongsToRelated)
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,102 @@
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
+
61
+ class SaveMatcher
62
+ def initialize(attributes = {})
63
+ @attributes = attributes
64
+ end
65
+
66
+ def matches?(actual)
67
+ @actual = actual.is_a?(Class) ?
68
+ ( defined?(::Factory) ? ::Factory.build(actual.name.underscore, @attributes) : actual.new(@attributes)) :
69
+ actual
70
+ @actual.valid? and @actual.save
71
+ end
72
+
73
+ def failure_message_for_should
74
+ "Expected #{@actual.inspect} to save properly, got #{@actual.errors.full_messages.to_sentence}"
75
+ end
76
+
77
+ def failure_message_for_should_not
78
+ "Expected #{@actual.inspect} to not save, got saved instead"
79
+ end
80
+
81
+ def description
82
+ "save properly"
83
+ end
84
+ end
85
+
86
+ def save(attributes = {})
87
+ SaveMatcher.new(attributes)
88
+ end
89
+ alias_method :save_properly, :save
90
+
91
+ end
92
+ end
93
+
94
+ Rspec::Matchers.define :have_instance_method do |name|
95
+ match do |klass|
96
+ klass.instance_methods.include?(name.to_sym)
97
+ end
98
+
99
+ description do
100
+ "have instance method #{name.to_s}"
101
+ end
102
+ 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_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,52 @@
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 allow_blank?(allow_blank)
16
+ @allow_blank = allow_blank
17
+ end
18
+
19
+ def matches?(actual)
20
+ return false unless result = super(actual)
21
+
22
+ if [@validator.options[:scope]].flatten == @scope
23
+ @positive_result_message = @positive_result_message << "scope to #{@validator.options[:scope]}"
24
+ else
25
+ @negative_result_message = @negative_result_message << "scope to #{@validator.options[:scope]}"
26
+ result = false
27
+ end if @scope
28
+
29
+ if @validator.options[:allow_blank] == @allow_blank
30
+ @positive_result_message = @positive_result_message << " with blank values allowed"
31
+ else
32
+ @negative_result_message = @negative_result_message << " with no blank values allowed"
33
+ result = false
34
+ end if @allow_blank
35
+
36
+ result
37
+ end
38
+
39
+ def description
40
+ options_desc = []
41
+ options_desc << " scoped to #{@scope.inspect}" if @scope
42
+ options_desc << " allowing blank values" if @allow_blank
43
+ super << options_desc.to_sentence
44
+ end
45
+ end
46
+
47
+ def validate_uniqueness_of(field)
48
+ ValidateUniquenessOfMatcher.new(field)
49
+ end
50
+ end
51
+ end
52
+ 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,18 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+
3
+ require 'matchers/document'
4
+ require 'matchers/associations'
5
+ require 'matchers/validations'
6
+ require 'matchers/validations/associated'
7
+ require 'matchers/validations/format_of'
8
+ require 'matchers/validations/inclusion_of'
9
+ require 'matchers/validations/numericality_of'
10
+ require 'matchers/validations/presence_of'
11
+ require 'matchers/validations/uniqueness_of'
12
+
13
+ module Mongoid
14
+ module Matchers
15
+ include Mongoid::Matchers::Associations
16
+ include Mongoid::Matchers::Validations
17
+ end
18
+ end
@@ -0,0 +1,84 @@
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}
8
+ s.version = "1.0.3"
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-05-09}
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.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".bundle/config",
21
+ ".document",
22
+ ".gitignore",
23
+ ".rvmrc",
24
+ "Gemfile",
25
+ "LICENSE",
26
+ "README.rdoc",
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/numericality_of.rb",
36
+ "lib/matchers/validations/presence_of.rb",
37
+ "lib/matchers/validations/uniqueness_of.rb",
38
+ "lib/mongoid-rspec.rb",
39
+ "mongoid-rspec.gemspec",
40
+ "spec/models/article.rb",
41
+ "spec/models/comment.rb",
42
+ "spec/models/profile.rb",
43
+ "spec/models/user.rb",
44
+ "spec/spec_helper.rb",
45
+ "spec/unit/associations_spec.rb",
46
+ "spec/unit/document_spec.rb",
47
+ "spec/unit/validations_spec.rb"
48
+ ]
49
+ s.homepage = %q{http://github.com/evansagge/mongoid-rspec}
50
+ s.rdoc_options = ["--charset=UTF-8"]
51
+ s.require_paths = ["lib"]
52
+ s.rubygems_version = %q{1.3.6}
53
+ s.summary = %q{RSpec matchers for Mongoid}
54
+ s.test_files = [
55
+ "spec/models/article.rb",
56
+ "spec/models/comment.rb",
57
+ "spec/models/profile.rb",
58
+ "spec/models/user.rb",
59
+ "spec/spec_helper.rb",
60
+ "spec/unit/associations_spec.rb",
61
+ "spec/unit/document_spec.rb",
62
+ "spec/unit/validations_spec.rb"
63
+ ]
64
+
65
+ if s.respond_to? :specification_version then
66
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
67
+ s.specification_version = 3
68
+
69
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
70
+ s.add_runtime_dependency(%q<mongoid>, ["= 2.0.0.beta4"])
71
+ s.add_runtime_dependency(%q<bson_ext>, ["= 0.20.1"])
72
+ s.add_runtime_dependency(%q<rspec-rails>, [">= 2.0.0.beta.7"])
73
+ else
74
+ s.add_dependency(%q<mongoid>, ["= 2.0.0.beta4"])
75
+ s.add_dependency(%q<bson_ext>, ["= 0.20.1"])
76
+ s.add_dependency(%q<rspec-rails>, [">= 2.0.0.beta.7"])
77
+ end
78
+ else
79
+ s.add_dependency(%q<mongoid>, ["= 2.0.0.beta4"])
80
+ s.add_dependency(%q<bson_ext>, ["= 0.20.1"])
81
+ s.add_dependency(%q<rspec-rails>, [">= 2.0.0.beta.7"])
82
+ end
83
+ end
84
+
@@ -0,0 +1,13 @@
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
+ belongs_to_related :user, :inverse_of => :articles
10
+
11
+ validates :title, :presence => true
12
+ end
13
+
@@ -0,0 +1,6 @@
1
+ class Comment
2
+ include Mongoid::Document
3
+
4
+ embedded_in :article, :inverse_of => :comments
5
+ belongs_to_related :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,21 @@
1
+ class User
2
+ include Mongoid::Document
3
+
4
+ field :login
5
+ field :email
6
+ field :role
7
+
8
+ has_many_related :articles
9
+ has_many_related :comments
10
+
11
+ embeds_one :profile
12
+
13
+ validates :login, :presence => true, :uniqueness => true, :format => { :with => /^[\w\-]+$/ }
14
+ validates :email, :presence => true, :uniqueness => true
15
+ validates :role, :presence => true, :inclusion => { :in => ["admin", "moderator", "member"]}
16
+ validates :profile, :presence => true, :associated => true
17
+
18
+ def admin?
19
+ false
20
+ end
21
+ 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,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Associations" do
4
+ describe User do
5
+ subject { User }
6
+
7
+ it { should have_many_related :articles }
8
+ it { should have_many_related :comments }
9
+ it { should embed_one :profile }
10
+ end
11
+
12
+ describe Profile do
13
+ subject { Profile }
14
+
15
+ it { should be_embedded_in(:user).as_inverse_of(:profile) }
16
+ end
17
+
18
+ describe Article do
19
+ subject { Article }
20
+
21
+ it { should belong_to_related(:user).as_inverse_of(:articles) }
22
+ it { should embed_many(:comments) }
23
+ end
24
+
25
+ describe Comment do
26
+ subject { Comment }
27
+
28
+ it { should be_embedded_in(:article).as_inverse_of(:comments) }
29
+ it { should belong_to_related(:user).as_inverse_of(:comments) }
30
+ end
31
+ 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,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Validations" do
4
+ describe User do
5
+ it { should validate_presence_of(:login) }
6
+ it { should validate_uniqueness_of(:login) }
7
+ it { should validate_format_of(:login).to_allow("valid_login").not_to_allow("invalid login") }
8
+ it { should validate_associated(:profile) }
9
+ it { should validate_inclusion_of(:role).to_allow("admin", "member") }
10
+ end
11
+
12
+ describe Profile do
13
+ it { should validate_numericality_of(:age) }
14
+ end
15
+ end
metadata ADDED
@@ -0,0 +1,141 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mongoid-rspec
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 0
8
+ - 3
9
+ version: 1.0.3
10
+ platform: ruby
11
+ authors:
12
+ - Evan Sagge
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-05-09 00:00:00 +08: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
+ requirements:
25
+ - - "="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 2
29
+ - 0
30
+ - 0
31
+ - beta4
32
+ version: 2.0.0.beta4
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: bson_ext
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - "="
41
+ - !ruby/object:Gem::Version
42
+ segments:
43
+ - 0
44
+ - 20
45
+ - 1
46
+ version: 0.20.1
47
+ type: :runtime
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: rspec-rails
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ segments:
57
+ - 2
58
+ - 0
59
+ - 0
60
+ - beta
61
+ - 7
62
+ version: 2.0.0.beta.7
63
+ type: :runtime
64
+ version_requirements: *id003
65
+ description: RSpec matches for Mongoid models, including association and validation matchers
66
+ email: evansagge@gmail.com
67
+ executables: []
68
+
69
+ extensions: []
70
+
71
+ extra_rdoc_files:
72
+ - LICENSE
73
+ - README.rdoc
74
+ files:
75
+ - .bundle/config
76
+ - .document
77
+ - .gitignore
78
+ - .rvmrc
79
+ - Gemfile
80
+ - LICENSE
81
+ - README.rdoc
82
+ - Rakefile
83
+ - VERSION
84
+ - lib/matchers/associations.rb
85
+ - lib/matchers/document.rb
86
+ - lib/matchers/validations.rb
87
+ - lib/matchers/validations/associated.rb
88
+ - lib/matchers/validations/format_of.rb
89
+ - lib/matchers/validations/inclusion_of.rb
90
+ - lib/matchers/validations/numericality_of.rb
91
+ - lib/matchers/validations/presence_of.rb
92
+ - lib/matchers/validations/uniqueness_of.rb
93
+ - lib/mongoid-rspec.rb
94
+ - mongoid-rspec.gemspec
95
+ - spec/models/article.rb
96
+ - spec/models/comment.rb
97
+ - spec/models/profile.rb
98
+ - spec/models/user.rb
99
+ - spec/spec_helper.rb
100
+ - spec/unit/associations_spec.rb
101
+ - spec/unit/document_spec.rb
102
+ - spec/unit/validations_spec.rb
103
+ has_rdoc: true
104
+ homepage: http://github.com/evansagge/mongoid-rspec
105
+ licenses: []
106
+
107
+ post_install_message:
108
+ rdoc_options:
109
+ - --charset=UTF-8
110
+ require_paths:
111
+ - lib
112
+ required_ruby_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ segments:
117
+ - 0
118
+ version: "0"
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ segments:
124
+ - 0
125
+ version: "0"
126
+ requirements: []
127
+
128
+ rubyforge_project:
129
+ rubygems_version: 1.3.6
130
+ signing_key:
131
+ specification_version: 3
132
+ summary: RSpec matchers for Mongoid
133
+ test_files:
134
+ - spec/models/article.rb
135
+ - spec/models/comment.rb
136
+ - spec/models/profile.rb
137
+ - spec/models/user.rb
138
+ - spec/spec_helper.rb
139
+ - spec/unit/associations_spec.rb
140
+ - spec/unit/document_spec.rb
141
+ - spec/unit/validations_spec.rb