mongoid-rspec 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.bundle/config 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