mongoid-minitest 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.DS_Store
@@ -0,0 +1 @@
1
+ 1.9.3-p125
@@ -0,0 +1,30 @@
1
+ ### 0.0.1
2
+
3
+ + Added `of_type` matcher to `HaveAssociationMatcher`.
4
+ + Added `have_many` association matcher.
5
+ + Added `Mongoid::Matchers::Associations` module.
6
+ + Added `to_not_allow` matcher to `ValidateExclusionMatcher`.
7
+ + Added `validate_exclusion_of` matcher.
8
+ + Added `to_not_allow` matcher to `ValidateFormatMatcher`.
9
+ + Added `to_allow` matcher to `ValidateFormatMatcher`.
10
+ + Added `validate_format_of` matcher.
11
+ + Added `with_max` alias to `with_maximum` matcher.
12
+ + Added `with_maximum` matcher to `ValidateLengthMatcher`
13
+ + Added `with_min` alias to `with_minimum` matcher.
14
+ + Added `with_minimum` matcher to `ValidateLengthMatcher`.
15
+ + Added `validate_length_of` matcher.
16
+ + Added `case_sensitive` matcher to `ValidateUniquenessMatcher`.
17
+ + Added `validate_uniqueness_of` matcher.
18
+ + Added `validate_presence_of` matcher.
19
+ + Added `have_fields` matcher.
20
+ + Added `be_timestamped` document matcher.
21
+ + Added `be_versioned` document matcher.
22
+ + Added `be_paranoid` document matcher.
23
+ + Added default failure messages based on description matcher.
24
+ + Added `be_document` document matcher.
25
+ + Added `with_default_value` matcher to `HaveFieldMatcher`.
26
+ + Added `of_type` matcher to `HaveFieldMatcher`.
27
+ + Added `must` and `wont` methods to `MiniTest::Spec`.
28
+ + Added `have_field` matcher.
29
+ + Added `must` and `wont` expectations.
30
+ + Added `assert_must` and `assert_wont` to `MiniTest::Assertions`.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mongoid-minitest.gemspec
4
+ gemspec
@@ -0,0 +1,7 @@
1
+ guard 'minitest' do
2
+ watch(%r|^test/(.*)_test\.rb|)
3
+ watch(%r|^test/test_helper\.rb|) { "test" }
4
+ watch(%r|^test/models/(.*)\.rb|) { "test" }
5
+ watch(%r|^lib/mongoid-minitest\.rb|) { "test" }
6
+ watch(%r|^lib/matchers/(.*)\.rb|) { "test" }
7
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Francesco Rodriguez
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,166 @@
1
+ # mongoid-minitest
2
+
3
+ MiniTest matchers for Mongoid.
4
+
5
+ Requires Ruby 1.9.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'mongoid-minitest'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install mongoid-minitest
20
+
21
+ ## Usage
22
+
23
+ Matchers are available at `Mongoid::Matchers` module.
24
+ Setup matchers according to your testing preference:
25
+
26
+ ### minitest/unit
27
+
28
+ class MiniTest::Unit::TestCase
29
+ include Mongoid::Matchers
30
+ end
31
+
32
+ ### minitest/spec
33
+
34
+ class MiniTest::Spec
35
+ include Mongoid::Matchers
36
+ end
37
+
38
+ See the following examples:
39
+
40
+ # minitest/unit
41
+ class DummyTest < MiniTest::Unit::TestCase
42
+ def test_matchers
43
+ assert_must Dummy, have_field(:name)
44
+ assert_wont Dummy, have_field(:none)
45
+ end
46
+ end
47
+
48
+ # minitest/spec
49
+ describe Dummy
50
+ it "sould test matchers" do
51
+ Dummy.must have_field(:name)
52
+ Dummy.wont have_field(:none)
53
+ end
54
+ end
55
+
56
+ # minitest/spec with subject
57
+ describe Dummy
58
+ it { must have_field(:name) }
59
+ it { wont have_field(:none) }
60
+ end
61
+
62
+ ## Matchers
63
+
64
+ `Mongoid::Matchers` include the following modules:
65
+
66
+ Module Mongoid
67
+ Module Matchers
68
+ include Mongoid::Matchers::Document
69
+ include Mongoid::Matchers::Validations
70
+ include Mongoid::Matchers::Associations
71
+ end
72
+ end
73
+
74
+ ### Document Matchers
75
+
76
+ describe Mongoid::Matchers::Document do
77
+ subject { Person }
78
+
79
+ it { must be_document }
80
+ it { must be_paranoid }
81
+ it { must be_versioned }
82
+ it { must be_timestamped }
83
+
84
+ it { must have_field(:name) }
85
+ it { must have_field(:name).of_type(String) }
86
+ it { must have_field(:name).with_default_value("me") }
87
+ it { must have_field(:name).of_type(String).with_default_value("me") }
88
+
89
+ it { must have_fields(:name, :login) }
90
+ it { must have_fields(:name, :login).of_type(String) }
91
+ it { must have_fields(:name, :login).with_default_value("me") }
92
+ it { must have_fields(:name, :login).of_type(String).with_default_value("me") }
93
+ end
94
+
95
+ ### Validations Matchers
96
+
97
+ describe Mongoid::Matchers::Validations do
98
+ subject { Person }
99
+
100
+ it { must validate_presence_of(:name) }
101
+
102
+ it { must validate_uniqueness_of(:login).case_insensitive }
103
+
104
+ it { must validate_length_of(:password).with_min(8) }
105
+ it { must validate_length_of(:password).with_minimum(8) }
106
+ it { must validate_length_of(:password).with_max(16) }
107
+ it { must validate_length_of(:password).with_maximum(16) }
108
+
109
+ it { must validate_format_of(:email).to_allow("foo@bar.com") }
110
+ it { must validate_format_of(:email).to_not_allow("foo_bar_com") }
111
+
112
+ it { must validate_exclusion_of(:email).to_not_allow("foo@bar.com", "fizz@buzz.com") }
113
+ end
114
+
115
+ ### Association Matchers
116
+
117
+ describe Mongoid::Matchers::Associations do
118
+ subject { Person }
119
+
120
+ it { must have_many(:pets).of_type(Pet) }
121
+ end
122
+
123
+ ## Contributing
124
+
125
+ 1. Fork it
126
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
127
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
128
+ 4. Push to the branch (`git push origin my-new-feature`)
129
+ 5. Create new Pull Request
130
+
131
+ ## Unit Tests
132
+
133
+ To run unit tests, run `bundle exec rake` or `bundle exec guard` to run in auto mode.
134
+
135
+ ## License
136
+
137
+ Copyright (c) 2012 Francesco Rodriguez
138
+
139
+ MIT License
140
+
141
+ Permission is hereby granted, free of charge, to any person obtaining
142
+ a copy of this software and associated documentation files (the
143
+ "Software"), to deal in the Software without restriction, including
144
+ without limitation the rights to use, copy, modify, merge, publish,
145
+ distribute, sublicense, and/or sell copies of the Software, and to
146
+ permit persons to whom the Software is furnished to do so, subject to
147
+ the following conditions:
148
+
149
+ The above copyright notice and this permission notice shall be
150
+ included in all copies or substantial portions of the Software.
151
+
152
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
153
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
154
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
155
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
156
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
157
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
158
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
159
+
160
+ ## Last words
161
+
162
+ At [EpicLabs](https://github.com/epiclabs/), We're migrating all the tests from `rspec` to `minitest`. I've been using
163
+ [mongoid-rspec gem](https://github.com/evansagge/mongoid-rspec) by [evanssage](https://github.com/evansagge).
164
+ So, this gem is heavily inspired in Evan's gem and [minitest-matchers](https://github.com/zenspider/minitest-matchers) gem
165
+ by [zenspider](https://github.com/zenspider). We love [minitest](https://github.com/seattlerb/minitest) and
166
+ we hope that this will be helpful for you. Thanks!
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ require "rake/testtask"
5
+
6
+ Rake::TestTask.new do |t|
7
+ t.libs << "test"
8
+ t.pattern = "test/*/*_test.rb"
9
+ end
10
+
11
+ task :default => [:test]
@@ -0,0 +1,98 @@
1
+ module Mongoid
2
+ module Matchers
3
+ module Associations
4
+ HAS_MANY = Mongoid::Relations::Referenced::Many
5
+
6
+ class HaveAssociationMatcher
7
+ def initialize(name, type)
8
+ @association = {}
9
+ @association[:name] = name.to_s
10
+ @association[:type] = type
11
+ @expectation_message = "#{type_description} #{@association[:name].inspect}"
12
+ end
13
+
14
+ def of_type(klass)
15
+ @association[:class] = klass
16
+ @expectation_message << " of type #{@association[:class].inspect}"
17
+ self
18
+ end
19
+
20
+ def matches?(klass)
21
+ @klass = klass.is_a?(Class) ? klass : klass.class
22
+ @metadata = @klass.relations[@association[:name]]
23
+ @result = true
24
+
25
+ check_association_name
26
+ check_association_type if @result
27
+ check_association_class if @result
28
+
29
+ @result
30
+ end
31
+
32
+ def failure_message
33
+ "Expected #{@klass} to #{@expectation_message}, got #{@negative_message}"
34
+ end
35
+
36
+ def negative_failure_message
37
+ "Expected #{@klass} to not #{@expectation_message}, got #{@positive_message}"
38
+ end
39
+
40
+ def description
41
+ @expectation_message
42
+ end
43
+
44
+ private
45
+
46
+ def check_association_name
47
+ if @metadata.nil?
48
+ @negative_message = "no association named #{@association[:name]}"
49
+ @result = false
50
+ else
51
+ @positive_message = "association named #{@association[:name]}"
52
+ end
53
+ end
54
+
55
+ def check_association_type
56
+ @relation = @metadata.relation
57
+ if @relation != @association[:type]
58
+ @negative_message = association_type_failure_message
59
+ @result = false
60
+ else
61
+ @positive_message = association_type_failure_message
62
+ end
63
+ end
64
+
65
+ def association_type_failure_message
66
+ msg = "#{@klass.inspect}"
67
+ msg << " #{type_description(@relation, false)}"
68
+ msg << " #{@association[:name].inspect}"
69
+
70
+ msg
71
+ end
72
+
73
+ def check_association_class
74
+ if !@association[:class].nil? and @association[:class] != @metadata.klass
75
+ @negative_message = "#{@positive_message} of type #{@metadata.klass}"
76
+ @result = false
77
+ else
78
+ @positive_message << " of type #{@metadata.klass}" if @association[:class]
79
+ end
80
+ end
81
+
82
+ def type_description(type = nil, passive = true)
83
+ type ||= @association[:type]
84
+ case type.name
85
+ when HAS_MANY.name
86
+ (passive ? "reference" : "references") << " many"
87
+ else
88
+ raise "Unknown association type '%s'" % type
89
+ end
90
+ end
91
+ end
92
+
93
+ def have_many(association_name)
94
+ HaveAssociationMatcher.new(association_name, HAS_MANY)
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,20 @@
1
+ module Mongoid
2
+ module Matchers
3
+ module Document
4
+ class BeDocumentMatcher
5
+ def matches?(klass)
6
+ @klass = klass
7
+ @klass.included_modules.include?(Mongoid::Document)
8
+ end
9
+
10
+ def description
11
+ "be a Mongoid document"
12
+ end
13
+ end
14
+
15
+ def be_document
16
+ BeDocumentMatcher.new
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module Mongoid
2
+ module Matchers
3
+ module Document
4
+ class BeParanoidMatcher
5
+ def matches?(klass)
6
+ @klass = klass
7
+ @klass.included_modules.include?(Mongoid::Paranoia)
8
+ end
9
+
10
+ def description
11
+ "be a paranoid Mongoid document"
12
+ end
13
+ end
14
+
15
+ def be_paranoid
16
+ BeParanoidMatcher.new
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module Mongoid
2
+ module Matchers
3
+ module Document
4
+ class BeTimestamped
5
+ def matches?(klass)
6
+ @klass = klass
7
+ @klass.included_modules.include?(Mongoid::Timestamps)
8
+ end
9
+
10
+ def description
11
+ "be timestamped Mongoid document"
12
+ end
13
+ end
14
+
15
+ def be_timestamped
16
+ BeTimestamped.new
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module Mongoid
2
+ module Matchers
3
+ module Document
4
+ class BeVersionedMatcher
5
+ def matches?(klass)
6
+ @klass = klass
7
+ @klass.included_modules.include?(Mongoid::Versioning)
8
+ end
9
+
10
+ def description
11
+ "be a versioned Mongoid document"
12
+ end
13
+ end
14
+
15
+ def be_versioned
16
+ BeVersionedMatcher.new
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,72 @@
1
+ module Mongoid
2
+ module Matchers
3
+ module Document
4
+ class HaveFieldMatcher
5
+ include Mongoid::Matchers::Helpers
6
+
7
+ def initialize(*fields)
8
+ @fields = fields.collect(&:to_s)
9
+ end
10
+
11
+ def of_type(type)
12
+ @type = type
13
+ self
14
+ end
15
+
16
+ def with_default_value(default)
17
+ @default = default
18
+ self
19
+ end
20
+
21
+ def matches?(klass)
22
+ @klass = klass.is_a?(Class) ? klass : klass.class
23
+ @errors = []
24
+
25
+ @fields.each do |field|
26
+ if @klass.fields.include?(field)
27
+ error = ""
28
+ result_field = @klass.fields[field]
29
+
30
+ if @type && result_field.type != @type
31
+ error << " of type #{result_field.type.inspect}"
32
+ end
33
+
34
+ if !@default.nil? && !result_field.default.nil? && result_field.default != @default
35
+ error << " with default value of #{result_field.default.inspect}"
36
+ end
37
+
38
+ @errors << "field #{field.inspect << error}" if !error.blank?
39
+ else
40
+ @errors << "no field named #{field.inspect}"
41
+ end
42
+ end
43
+
44
+ @errors.empty?
45
+ end
46
+
47
+ def failure_message
48
+ "Expected #{@klass.inspect} to #{description}, got #{@errors.to_sentence}"
49
+ end
50
+
51
+ def negative_failure_message
52
+ msg = "Expected #{@klass.inspect} to not #{description}, "
53
+ msg << "got #{@klass.inspect} to #{description}"
54
+ end
55
+
56
+ def description
57
+ desc = "have #{@fields.size > 1 ? 'fields' : 'field'} named"
58
+ desc << " #{to_sentence(@fields)}"
59
+ desc << " of type #{@type.inspect}" if @type
60
+ desc << " with default value of #{@default.inspect}" if !@default.nil?
61
+ desc
62
+ end
63
+ end
64
+
65
+ def have_field(*fields)
66
+ HaveFieldMatcher.new(*fields)
67
+ end
68
+ alias :have_fields :have_field
69
+
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,9 @@
1
+ module Mongoid
2
+ module Matchers
3
+ module Helpers
4
+ def to_sentence(ary)
5
+ ary.collect(&:inspect).to_sentence
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,43 @@
1
+ module Mongoid
2
+ module Matchers
3
+ module Validations
4
+ class ValidateExclusionMatcher < HaveValidationMatcher
5
+ def initialize(field)
6
+ super(field, :exclusion)
7
+ end
8
+
9
+ def to_not_allow(*values)
10
+ @not_allowed_values = values.flatten
11
+ self
12
+ end
13
+
14
+ def matches?(actual)
15
+ return false unless result = super(actual)
16
+
17
+ if @not_allowed_values
18
+ allowed_values = @not_allowed_values - @validator.options[:in]
19
+ if allowed_values.empty?
20
+ @positive_message << " not allowing all values mentioned"
21
+ else
22
+ @negative_message << " allowing the values:"
23
+ @negative_message << " #{to_sentence(allowed_values)}"
24
+ result = false
25
+ end
26
+ end
27
+
28
+ result
29
+ end
30
+
31
+ def description
32
+ if @not_allowed_values
33
+ super << " not allowing the values: #{to_sentence(@not_allowed_values)}"
34
+ end
35
+ end
36
+ end
37
+
38
+ def validate_exclusion_of(field)
39
+ ValidateExclusionMatcher.new(field)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,65 @@
1
+ module Mongoid
2
+ module Matchers
3
+ module Validations
4
+ class ValidateFormatMatcher < HaveValidationMatcher
5
+ def initialize(field)
6
+ super(field, :format)
7
+ end
8
+
9
+ def to_allow(valid_value)
10
+ @valid = valid_value
11
+ self
12
+ end
13
+
14
+ def to_not_allow(invalid_value)
15
+ @invalid = invalid_value
16
+ self
17
+ end
18
+
19
+ def matches?(klass)
20
+ return false unless @result = super(klass)
21
+
22
+ check_valid_value if @valid
23
+ check_invalid_value if @invalid
24
+
25
+ @result
26
+ end
27
+
28
+ def description
29
+ desc = []
30
+ desc << " allowing the value #{@valid.inspect}" if @valid
31
+ desc << " not allowing the value #{@invalid.inspect}" if @invalid
32
+ super << desc.to_sentence
33
+ end
34
+
35
+ private
36
+
37
+ def check_valid_value
38
+ if format =~ @valid
39
+ @positive_message << " with #{@valid.inspect} as a valid value"
40
+ else
41
+ @negative_message << " with #{@valid.inspect} as an invalid value"
42
+ @result = false
43
+ end
44
+ end
45
+
46
+ def check_invalid_value
47
+ if !(format =~ @invalid)
48
+ @positive_message << " with #{@invalid.inspect} as a invalid value"
49
+ else
50
+ @negative_message << " with #{@invalid.inspect} as a valid value"
51
+ @result = false
52
+ end
53
+ end
54
+
55
+ def format
56
+ @validator.options[:with]
57
+ end
58
+ end
59
+
60
+ def validate_format_of(field)
61
+ ValidateFormatMatcher.new(field)
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,65 @@
1
+ module Mongoid
2
+ module Matchers
3
+ module Validations
4
+ class ValidateLengthMatcher < HaveValidationMatcher
5
+ def initialize(field)
6
+ super(field, :length)
7
+ end
8
+
9
+ def with_minimum(value)
10
+ @minimum = value
11
+ self
12
+ end
13
+ alias :with_min :with_minimum
14
+
15
+ def with_maximum(value)
16
+ @maximum = value
17
+ self
18
+ end
19
+ alias :with_max :with_maximum
20
+
21
+ def matches?(klass)
22
+ return false unless @result = super(klass)
23
+
24
+ check_minimum if @minimum
25
+ check_maximum if @maximum
26
+
27
+ @result
28
+ end
29
+
30
+ def description
31
+ desc = []
32
+ desc << " with minimum #{@minimum}" if @minimum
33
+ desc << " with maximum #{@maximum}" if @maximum
34
+ super << desc.to_sentence
35
+ end
36
+
37
+ private
38
+
39
+ def check_minimum
40
+ actual = @validator.options[:minimum]
41
+ if actual == @minimum
42
+ @positive_message << " with minimum of #{@minimum}"
43
+ else
44
+ @negative_message << " with minimum of #{actual}"
45
+ @result = false
46
+ end
47
+ end
48
+
49
+ def check_maximum
50
+ actual = @validator.options[:maximum]
51
+ if actual == @maximum
52
+ @positive_message << " with maximum of #{@maximum}"
53
+ else
54
+ @negative_message << " with maximum of #{actual}"
55
+ @result = false
56
+ end
57
+ end
58
+ end
59
+
60
+ def validate_length_of(field)
61
+ ValidateLengthMatcher.new(field)
62
+ end
63
+ end
64
+ end
65
+ 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,43 @@
1
+ module Mongoid
2
+ module Matchers
3
+ module Validations
4
+ class ValidateUniquenessMatcher < HaveValidationMatcher
5
+ def initialize(field)
6
+ super(field, :uniqueness)
7
+ end
8
+
9
+ def case_insensitive
10
+ @case_insensitive = true
11
+ self
12
+ end
13
+
14
+ def matches?(klass)
15
+ return false unless @result = super(klass)
16
+
17
+ check_case_sensivity if @case_insensitive
18
+
19
+ @result
20
+ end
21
+
22
+ def check_case_sensivity
23
+ if @validator.options[:case_sensitive] == false
24
+ @positive_message << " with case insensitive values"
25
+ else
26
+ @negative_message << " without case insensitive values"
27
+ @result = false
28
+ end
29
+ end
30
+
31
+ def description
32
+ desc = []
33
+ desc << " allowing case insensitive values" if @case_insensitive
34
+ super << desc.to_sentence
35
+ end
36
+ end
37
+
38
+ def validate_uniqueness_of(field)
39
+ ValidateUniquenessMatcher.new(field)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,41 @@
1
+ module Mongoid
2
+ module Matchers
3
+ module Validations
4
+ class HaveValidationMatcher
5
+ include Mongoid::Matchers::Helpers
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
+ @validator = @klass.validators_on(@field).detect { |v| v.kind.to_s == @type }
15
+
16
+ if @validator
17
+ @negative_message = "#{@type.inspect} validator on #{@field.inspect}"
18
+ @positive_message = "#{@type.inspect} validator on #{@field.inspect}"
19
+ else
20
+ @negative_message = "no #{@type.inspect} validator on #{@field.inspect}"
21
+ return false
22
+ end
23
+
24
+ true
25
+ end
26
+
27
+ def failure_message
28
+ "Expected #{@klass.inspect} to #{description}; instead got #{@negative_message}"
29
+ end
30
+
31
+ def negative_failure_message
32
+ "Expected #{@klass.inspect} to not #{description}; instead got #{@positive_message}"
33
+ end
34
+
35
+ def description
36
+ "validate #{@type.inspect} of #{@field.inspect}"
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,42 @@
1
+ module MiniTest
2
+ module Assertions
3
+ def assert_must(subject, matcher, msg = nil)
4
+ msg = message(msg) do
5
+ if matcher.respond_to? :failure_message
6
+ matcher.failure_message
7
+ else
8
+ "Expected #{subject.inspect} to #{matcher.description}"
9
+ end
10
+ end
11
+
12
+ assert matcher.matches?(subject), msg
13
+ end
14
+
15
+ def assert_wont(subject, matcher, msg = nil)
16
+ msg = message(msg) do
17
+ if matcher.respond_to? :negative_failure_message
18
+ matcher.negative_failure_message
19
+ else
20
+ "Expected not to #{matcher.description}"
21
+ end
22
+ end
23
+
24
+ refute matcher.matches?(subject), msg
25
+ end
26
+ end
27
+
28
+ module Expectations
29
+ infect_an_assertion :assert_must, :must, :reverse
30
+ infect_an_assertion :assert_wont, :wont, :reverse
31
+ end
32
+ end
33
+
34
+ class MiniTest::Spec
35
+ def must(*args, &block)
36
+ subject.must(*args, &block)
37
+ end
38
+
39
+ def wont(*args, &block)
40
+ subject.wont(*args, &block)
41
+ end
42
+ end
@@ -0,0 +1,26 @@
1
+ gem "minitest"
2
+ require "mongoid"
3
+ require "minitest/spec"
4
+
5
+ require "minitest/matchers"
6
+ require "matchers/helpers"
7
+ require "matchers/document/have_field"
8
+ require "matchers/document/be_document"
9
+ require "matchers/document/be_paranoid"
10
+ require "matchers/document/be_versioned"
11
+ require "matchers/document/be_timestamped"
12
+ require "matchers/validations/validations"
13
+ require "matchers/validations/presence_of"
14
+ require "matchers/validations/uniqueness_of"
15
+ require "matchers/validations/length_of"
16
+ require "matchers/validations/format_of"
17
+ require "matchers/validations/exclusion_of"
18
+ require "matchers/associations/associations"
19
+
20
+ module Mongoid
21
+ module Matchers
22
+ include Mongoid::Matchers::Document
23
+ include Mongoid::Matchers::Validations
24
+ include Mongoid::Matchers::Associations
25
+ end
26
+ end
@@ -0,0 +1,5 @@
1
+ module Mongoid
2
+ module MiniTest
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path("../lib/mongoid-minitest/version", __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Francesco Rodriguez"]
6
+ gem.email = ["lrodriguezsanc@gmail.com"]
7
+ gem.description = %q{Minitest matchers for Mongoid}
8
+ gem.summary = %q{Minitest matchers for Mongoid}
9
+ gem.homepage = "https://github.com/frodsan/mongoid-minitest"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "mongoid-minitest"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Mongoid::MiniTest::VERSION
17
+
18
+ gem.add_dependency "minitest", "~> 2.12.0"
19
+ gem.add_dependency "mongoid" , "~> 2.4.7"
20
+ gem.add_development_dependency "bson_ext", "~> 1.6.1"
21
+ gem.add_development_dependency "guard-minitest"
22
+ gem.add_development_dependency "rake", "~> 0.9.2"
23
+ end
@@ -0,0 +1,15 @@
1
+ require 'test_helper'
2
+
3
+ describe Mongoid::Matchers::Associations do
4
+
5
+ describe "have_many" do
6
+ subject { Person }
7
+
8
+ it { must have_many(:pets) }
9
+ it { wont have_many(:accounts) }
10
+
11
+ it { must have_many(:pets).of_type(Pet) }
12
+ it { wont have_many(:pets).of_type(Person) }
13
+ end
14
+
15
+ end
@@ -0,0 +1,28 @@
1
+ require "test_helper"
2
+
3
+ describe Mongoid::Matchers::Document do
4
+ subject { Person }
5
+
6
+ it { must be_document }
7
+ it { must be_paranoid }
8
+ it { must be_versioned }
9
+ it { must be_timestamped }
10
+
11
+ it { must have_field(:name) }
12
+ it { wont have_field(:noexist) }
13
+
14
+ it { must have_field(:name).of_type(String) }
15
+ it { wont have_field(:name).of_type(Integer) }
16
+
17
+ it { must have_field(:name).with_default_value("me") }
18
+ it { wont have_field(:name).with_default_value("nodefault") }
19
+ it { must have_field(:name).of_type(String).with_default_value("me") }
20
+ it { wont have_field(:name).of_type(String).with_default_value("nodefault") }
21
+
22
+ it { must have_fields(:name, :login) }
23
+ it { wont have_fields(:noexist, :noexistagain) }
24
+ it { must have_fields(:name, :login).of_type(String) }
25
+ it { wont have_fields(:name, :login).of_type(Integer) }
26
+ it { must have_fields(:name, :login).with_default_value("me") }
27
+ it { must have_fields(:name, :login).of_type(String).with_default_value("me") }
28
+ end
@@ -0,0 +1,29 @@
1
+ require "test_helper"
2
+
3
+ describe Mongoid::Matchers::Validations do
4
+ subject { Person }
5
+
6
+ it { must validate_presence_of(:name) }
7
+ it { wont validate_presence_of(:age) }
8
+
9
+ it { must validate_uniqueness_of(:login).case_insensitive }
10
+ it { wont validate_uniqueness_of(:email).case_insensitive }
11
+
12
+ it { must validate_length_of(:password).with_min(8) }
13
+ it { wont validate_length_of(:password).with_min(0) }
14
+ it { must validate_length_of(:password).with_minimum(8) }
15
+ it { wont validate_length_of(:password).with_minimum(0) }
16
+ it { must validate_length_of(:password).with_max(16) }
17
+ it { wont validate_length_of(:password).with_max(8) }
18
+ it { must validate_length_of(:password).with_maximum(16) }
19
+ it { wont validate_length_of(:password).with_maximum(8) }
20
+
21
+ it { must validate_format_of(:email).to_allow("foo@bar.com") }
22
+ it { wont validate_format_of(:email).to_allow("foo_bar_com") }
23
+ it { must validate_format_of(:email).to_not_allow("foo_bar_com") }
24
+ it { wont validate_format_of(:email).to_not_allow("foo@bar.com") }
25
+
26
+ it { must validate_exclusion_of(:email).to_not_allow("foo@bar.com") }
27
+ it { must validate_exclusion_of(:email).to_not_allow("foo@bar.com", "fizz@buzz.com") }
28
+ it { wont validate_exclusion_of(:email).to_not_allow("foo_bar.com") }
29
+ end
@@ -0,0 +1,25 @@
1
+ class Person
2
+ include Mongoid::Document
3
+ include Mongoid::Paranoia
4
+ include Mongoid::Versioning
5
+ include Mongoid::Timestamps
6
+
7
+ field :login, type: String, default: "me"
8
+ field :password, type: String
9
+ field :name, type: String, default: "me"
10
+ field :age, type: Integer
11
+ field :email, type: String
12
+
13
+ has_many :pets
14
+
15
+ validates_presence_of(:name)
16
+ validates_uniqueness_of(:email)
17
+ validates_uniqueness_of(:login, case_sensitive: false)
18
+ validates_length_of(:password, minimum: 8, maximum: 16)
19
+ validates_format_of(:email, with: /^([^\s]+)((?:[-a-z0-9]\.)[a-z]{2,})$/i)
20
+ validates_exclusion_of(:email, in: ["foo@bar.com", "fizz@buzz.com"])
21
+ end
22
+
23
+ class Pet
24
+ include Mongoid::Document
25
+ end
@@ -0,0 +1,12 @@
1
+ require "mongoid-minitest"
2
+ require "minitest/autorun"
3
+
4
+ Dir[File.dirname(__FILE__) + "/models/*.rb"].each { |f| require f }
5
+
6
+ Mongoid.configure do |config|
7
+ config.master = Mongo::Connection.new.db("mongoid-minitest-test")
8
+ end
9
+
10
+ class MiniTest::Spec
11
+ include Mongoid::Matchers
12
+ end
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mongoid-minitest
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Francesco Rodriguez
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-12 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: minitest
16
+ requirement: &70195620634560 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 2.12.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70195620634560
25
+ - !ruby/object:Gem::Dependency
26
+ name: mongoid
27
+ requirement: &70195620634020 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 2.4.7
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70195620634020
36
+ - !ruby/object:Gem::Dependency
37
+ name: bson_ext
38
+ requirement: &70195620633540 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 1.6.1
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70195620633540
47
+ - !ruby/object:Gem::Dependency
48
+ name: guard-minitest
49
+ requirement: &70195620633040 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70195620633040
58
+ - !ruby/object:Gem::Dependency
59
+ name: rake
60
+ requirement: &70195620632340 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: 0.9.2
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70195620632340
69
+ description: Minitest matchers for Mongoid
70
+ email:
71
+ - lrodriguezsanc@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - .gitignore
77
+ - .rbenv-version
78
+ - CHANGELOG.md
79
+ - Gemfile
80
+ - Guardfile
81
+ - LICENSE
82
+ - README.md
83
+ - Rakefile
84
+ - lib/matchers/associations/associations.rb
85
+ - lib/matchers/document/be_document.rb
86
+ - lib/matchers/document/be_paranoid.rb
87
+ - lib/matchers/document/be_timestamped.rb
88
+ - lib/matchers/document/be_versioned.rb
89
+ - lib/matchers/document/have_field.rb
90
+ - lib/matchers/helpers.rb
91
+ - lib/matchers/validations/exclusion_of.rb
92
+ - lib/matchers/validations/format_of.rb
93
+ - lib/matchers/validations/length_of.rb
94
+ - lib/matchers/validations/presence_of.rb
95
+ - lib/matchers/validations/uniqueness_of.rb
96
+ - lib/matchers/validations/validations.rb
97
+ - lib/minitest/matchers.rb
98
+ - lib/mongoid-minitest.rb
99
+ - lib/mongoid-minitest/version.rb
100
+ - mongoid-minitest.gemspec
101
+ - test/matchers/associations_test.rb
102
+ - test/matchers/document_test.rb
103
+ - test/matchers/validations_test.rb
104
+ - test/models/models.rb
105
+ - test/test_helper.rb
106
+ homepage: https://github.com/frodsan/mongoid-minitest
107
+ licenses: []
108
+ post_install_message:
109
+ rdoc_options: []
110
+ require_paths:
111
+ - lib
112
+ required_ruby_version: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ required_rubygems_version: !ruby/object:Gem::Requirement
119
+ none: false
120
+ requirements:
121
+ - - ! '>='
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ requirements: []
125
+ rubyforge_project:
126
+ rubygems_version: 1.8.11
127
+ signing_key:
128
+ specification_version: 3
129
+ summary: Minitest matchers for Mongoid
130
+ test_files:
131
+ - test/matchers/associations_test.rb
132
+ - test/matchers/document_test.rb
133
+ - test/matchers/validations_test.rb
134
+ - test/models/models.rb
135
+ - test/test_helper.rb