minitest-mustwonted 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +194 -0
- data/lib/minitest-mustwonted.rb +5 -0
- data/lib/minitest/mustwonted.rb +27 -0
- data/lib/minitest/mustwonted/matcher.rb +31 -0
- data/lib/minitest/mustwonted/matcher/awesome.rb +53 -0
- data/lib/minitest/mustwonted/matcher/have.rb +35 -0
- data/lib/minitest/mustwonted/matcher/legacy.rb +26 -0
- data/lib/minitest/mustwonted/matcher/magick.rb +23 -0
- data/lib/minitest/mustwonted/matcher/valid.rb +49 -0
- data/lib/minitest/mustwonted/object.rb +26 -0
- data/lib/minitest/mustwonted/run.rb +8 -0
- data/lib/minitest/mustwonted/spec.rb +41 -0
- data/test/mustwonted/matcher/awesome_test.rb +100 -0
- data/test/mustwonted/matcher/have_test.rb +68 -0
- data/test/mustwonted/matcher/legacy_test.rb +39 -0
- data/test/mustwonted/matcher/magick_test.rb +54 -0
- data/test/mustwonted/matcher/valid_test.rb +65 -0
- data/test/mustwonted/matcher_test.rb +44 -0
- data/test/mustwonted/object_test.rb +31 -0
- data/test/mustwonted/spec_test.rb +24 -0
- data/test/test_helper.rb +12 -0
- metadata +81 -0
data/README.md
ADDED
@@ -0,0 +1,194 @@
|
|
1
|
+
# Must Wanted Things for MiniTest
|
2
|
+
|
3
|
+
This is a little plugn for [minitest](https://github.com/seattlerb/minitest)
|
4
|
+
which contains a new `must/wont` matchers engine, a set of essential matchers
|
5
|
+
and hooks for testing ruby/rails applications.
|
6
|
+
|
7
|
+
## Usage
|
8
|
+
|
9
|
+
1) Add `gem minitest-mustwonted` into your `Gemfile`
|
10
|
+
2) Enjoy!
|
11
|
+
|
12
|
+
|
13
|
+
## Awesome Matchers
|
14
|
+
|
15
|
+
Awesome matchers are set of easy to read logic-like matchers
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
describe MiniTest::MustWonted do
|
19
|
+
it "must provide awesome matchers" do
|
20
|
+
22.must == 22
|
21
|
+
22.wont == 33
|
22
|
+
22.must != 22
|
23
|
+
|
24
|
+
22.must > 11
|
25
|
+
22.must >= 22
|
26
|
+
22.must <= 23
|
27
|
+
|
28
|
+
"22".must =~ /2/
|
29
|
+
"22".wont =~ /3/
|
30
|
+
end
|
31
|
+
end
|
32
|
+
```
|
33
|
+
|
34
|
+
## Magick Matchers
|
35
|
+
|
36
|
+
Magick matchers are `rspec` like `be_smth` matchers
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
describe MiniTest::MustWonted do
|
40
|
+
it "must provide magick matchers" do
|
41
|
+
[].must be_empty
|
42
|
+
[0].wont be_empty
|
43
|
+
|
44
|
+
nil.must be_nil
|
45
|
+
'0'.wont be_nil
|
46
|
+
|
47
|
+
'0'.must be_a(String)
|
48
|
+
[0].must be_an(Array)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
```
|
52
|
+
|
53
|
+
## Collection Assertions
|
54
|
+
|
55
|
+
Additional `have` matcher will let you write easily readable collection checks
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
describe MiniTest::MustWonted do
|
59
|
+
class User
|
60
|
+
def comments(type=nil)
|
61
|
+
if type
|
62
|
+
Comment.where(type: type, user: self).count
|
63
|
+
else
|
64
|
+
Comment.where(user: self).count
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
it "must provide collection matchers" do
|
70
|
+
@user.must have(3).comments
|
71
|
+
@user.must have(1).comment(:deleted)
|
72
|
+
|
73
|
+
[1,2,3].must have(3).items
|
74
|
+
[1 ].must have(1).item
|
75
|
+
end
|
76
|
+
end
|
77
|
+
```
|
78
|
+
|
79
|
+
__NOTE__: calls will be automatically pluralized and resolved when possible. You
|
80
|
+
also can use the `item` or `items` on plain array-like objects, in which case it
|
81
|
+
will be checking the `size` method by default
|
82
|
+
|
83
|
+
|
84
|
+
## Legacy Matchers
|
85
|
+
|
86
|
+
Most of the `assert_smth` | `refute_smth` methods are piped throught the `must` |
|
87
|
+
`wont` interface automatically and resolved on fly.
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
describe MiniTest::MustWonted do
|
91
|
+
it "must support legacy assertions" do
|
92
|
+
'2'.must equal(3)
|
93
|
+
'3'.wont equal(2)
|
94
|
+
|
95
|
+
'2'.must respond_to(:downcase)
|
96
|
+
[2].wont respond_to(:unknown_method)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
```
|
100
|
+
|
101
|
+
Note, this module will automatically use your custom `assert_something` methods
|
102
|
+
as long as they take the subject as the first argument.
|
103
|
+
|
104
|
+
|
105
|
+
## Validation Matchers
|
106
|
+
|
107
|
+
`MustWonted` comes with a default models validation matchers similar to the
|
108
|
+
`minitest-matchers` validation package
|
109
|
+
|
110
|
+
```ruby
|
111
|
+
describe MiniTest::MustWonted do
|
112
|
+
it "must provide validation matchers" do
|
113
|
+
@user.must have_valid(:name).with("Nikolay", "Vasilisa")
|
114
|
+
@user.wont have_valid(:name).with(nil, '', false)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
```
|
118
|
+
|
119
|
+
|
120
|
+
## Custom Matchers
|
121
|
+
|
122
|
+
There are two ways to define your own custom matchers. Firstly, you can just
|
123
|
+
define the `assert_your_own_stuff` and, if needed `refute_your_own_stuff` methods
|
124
|
+
and they will be automatically available via the `must`|`wont` interface
|
125
|
+
|
126
|
+
```ruby
|
127
|
+
describe Something do
|
128
|
+
def assert_do_my_thing(object, *args)
|
129
|
+
# do something
|
130
|
+
end
|
131
|
+
|
132
|
+
it "must work right away" do
|
133
|
+
something.must do_my_thing(arg)
|
134
|
+
end
|
135
|
+
|
136
|
+
# if you're gonna call 'wont' as well, then define `refutre_` too
|
137
|
+
def refute_do_my_thing(object, *args)
|
138
|
+
# do something
|
139
|
+
end
|
140
|
+
|
141
|
+
it "wont do my thing" do
|
142
|
+
something.wont do_my_thing(arg)
|
143
|
+
ned
|
144
|
+
end
|
145
|
+
```
|
146
|
+
|
147
|
+
If you wanna do something more serious, you can define your matcher as a class
|
148
|
+
|
149
|
+
```ruby
|
150
|
+
class MyAwesomeMatcher
|
151
|
+
def initialize(*args)
|
152
|
+
@args = args
|
153
|
+
end
|
154
|
+
|
155
|
+
def match?(subject, wont)
|
156
|
+
@args # - the args you send into the matcher
|
157
|
+
subject # - the object on which you called `must`|`wont`
|
158
|
+
wont # - gets `true` when you called `wont` and `false` when you called `must`
|
159
|
+
|
160
|
+
if some_awesome_check_failed
|
161
|
+
railse "Oh my god, we all gonna die here!"
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
```
|
166
|
+
|
167
|
+
Once you done, register your matcher with `MiniTest::MustWonted` and start using it
|
168
|
+
|
169
|
+
```ruby
|
170
|
+
MiniTest::MustWonted :method_name, MyAwesomeMatcher
|
171
|
+
|
172
|
+
describe Something do
|
173
|
+
it "must do something" do
|
174
|
+
object.must method_name(arg, arg, arg...)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
```
|
178
|
+
|
179
|
+
|
180
|
+
## Credits
|
181
|
+
|
182
|
+
Most ideas were boldly taken from:
|
183
|
+
|
184
|
+
[minitest-rails](https://github.com/blowmage/minitest-rails)
|
185
|
+
[minitest-matchers](https://github.com/zenspider/minitest-matchers)
|
186
|
+
[shoulda-matchers](https://github.com/thoughtbot/shoulda-matchers)
|
187
|
+
[rspec-rails](https://github.com/rspec/rspec-rails)
|
188
|
+
|
189
|
+
|
190
|
+
## Copyright
|
191
|
+
|
192
|
+
All code in this library is published under the terms of the MIT License
|
193
|
+
|
194
|
+
Copyright (C) 2013 Nikolay Nemshilov
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'minitest/spec'
|
2
|
+
|
3
|
+
module MiniTest::MustWonted
|
4
|
+
VERSION = '1.0.0'
|
5
|
+
|
6
|
+
def self.add(*args)
|
7
|
+
MiniTest::MustWonted::Matcher.add *args
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
%w{
|
12
|
+
matcher
|
13
|
+
matcher/awesome
|
14
|
+
matcher/magick
|
15
|
+
matcher/legacy
|
16
|
+
matcher/valid
|
17
|
+
matcher/have
|
18
|
+
object
|
19
|
+
spec
|
20
|
+
run
|
21
|
+
}.each do |file|
|
22
|
+
require File.dirname(__FILE__) + "/mustwonted/#{file}"
|
23
|
+
end
|
24
|
+
|
25
|
+
# registering the matchers
|
26
|
+
MiniTest::MustWonted.add :have, MiniTest::MustWonted::Matcher::Have
|
27
|
+
MiniTest::MustWonted.add :have_valid, MiniTest::MustWonted::Matcher::Valid
|
@@ -0,0 +1,31 @@
|
|
1
|
+
#
|
2
|
+
# The actual matcher engine
|
3
|
+
#
|
4
|
+
class MiniTest::MustWonted::Matcher
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def must(subject, matcher=nil, flipped=false)
|
8
|
+
if matcher == nil
|
9
|
+
MiniTest::MustWonted::Matcher::Awesome.new(subject, flipped)
|
10
|
+
elsif matcher.respond_to?(:match?)
|
11
|
+
matcher.match?(subject, flipped)
|
12
|
+
subject # returning the reference to the subject in case of chained calls
|
13
|
+
else
|
14
|
+
raise "Your matcher supposed to have method called: 'match?'"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def wont(subject, matcher=nil)
|
19
|
+
must subject, matcher, true
|
20
|
+
end
|
21
|
+
|
22
|
+
def add(name, klass)
|
23
|
+
MiniTest::Unit::TestCase.instance_eval do
|
24
|
+
define_method name do |*args|
|
25
|
+
klass.new *args
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
#
|
2
|
+
# Provides the awesome, pure logick like matchers
|
3
|
+
#
|
4
|
+
# smth.must == smth
|
5
|
+
# smth.must =~ /re/
|
6
|
+
# smth.must > smth
|
7
|
+
# ...
|
8
|
+
#
|
9
|
+
class MiniTest::MustWonted::Matcher::Awesome
|
10
|
+
include MiniTest::Assertions
|
11
|
+
|
12
|
+
attr_reader :subject, :flipped
|
13
|
+
|
14
|
+
def initialize(subject, flipped)
|
15
|
+
@subject = subject
|
16
|
+
@flipped = flipped
|
17
|
+
end
|
18
|
+
|
19
|
+
def ==(value)
|
20
|
+
__call 'equal', false, @subject, value
|
21
|
+
end
|
22
|
+
|
23
|
+
def !=(value)
|
24
|
+
__call 'equal', true, @subject, value
|
25
|
+
end
|
26
|
+
|
27
|
+
def =~(regexp)
|
28
|
+
__call 'match', false, @subject, regexp
|
29
|
+
end
|
30
|
+
|
31
|
+
def > (value)
|
32
|
+
__call 'operator', false, @subject, :>, value
|
33
|
+
end
|
34
|
+
|
35
|
+
def < (value)
|
36
|
+
__call 'operator', false, @subject, :<, value
|
37
|
+
end
|
38
|
+
|
39
|
+
def >= (value)
|
40
|
+
__call 'operator', false, @subject, :>=, value
|
41
|
+
end
|
42
|
+
|
43
|
+
def <= (value)
|
44
|
+
__call 'operator', false, @subject, :<=, value
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def __call(name, flip, *args)
|
50
|
+
__send__ "#{@flipped == flip ? 'assert' : 'refute'}_#{name}", *args
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
#
|
2
|
+
# The unversal `have` matcher
|
3
|
+
#
|
4
|
+
# @user.must have(10).comments
|
5
|
+
# @array.must have(2).items
|
6
|
+
#
|
7
|
+
class MiniTest::MustWonted::Matcher::Have
|
8
|
+
|
9
|
+
def initialize(size)
|
10
|
+
@size = size
|
11
|
+
end
|
12
|
+
|
13
|
+
def match?(subject, wont)
|
14
|
+
if [:items, :item].include?(@name) && !subject.respond_to?(@name)
|
15
|
+
items = subject
|
16
|
+
else
|
17
|
+
items = subject.send @name, *@args
|
18
|
+
end
|
19
|
+
|
20
|
+
if wont ? items.size == @size : items.size != @size
|
21
|
+
raise MiniTest::Assertion, "Expected #{subject.inspect} to have #{
|
22
|
+
@size} ##{@name}(#{@args.join(',')})\nbut instead it has: #{size}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def method_missing(name, *args)
|
27
|
+
name = name.pluralize if name.respond_to?(:pluralize)
|
28
|
+
|
29
|
+
@name = name.to_sym
|
30
|
+
@args = args
|
31
|
+
|
32
|
+
self # returning itself so the end result was always this matcher
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#
|
2
|
+
# This matcher automatically calls the legacy `must_smth`, `refute_something`
|
3
|
+
# matchers if they are exists
|
4
|
+
#
|
5
|
+
class MiniTest::MustWonted::Matcher::Legacy
|
6
|
+
|
7
|
+
def initialize(name, args, test)
|
8
|
+
@name = name
|
9
|
+
@args = args
|
10
|
+
@test = test
|
11
|
+
end
|
12
|
+
|
13
|
+
def match?(subject, wont)
|
14
|
+
# trying the must_smth|wont_smth first, coz they expect the subject first
|
15
|
+
if subject.respond_to?(name = "#{wont ? 'wont' : 'must'}_#{@name}")
|
16
|
+
subject.__send__ name, *@args
|
17
|
+
|
18
|
+
# falling back to aseert|refute methods in case
|
19
|
+
elsif @test.respond_to?(name = "#{wont ? 'refute' : 'assert'}_#{@name}")
|
20
|
+
@test.__send__ name, subject, *@args
|
21
|
+
elsif wont
|
22
|
+
raise "Couldn't find the '#{wont ? 'refute' : 'assert'}_#{@name}' matcher"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#
|
2
|
+
# The Magick `be_smth` matcher
|
3
|
+
#
|
4
|
+
class MiniTest::MustWonted::Matcher::Magick
|
5
|
+
|
6
|
+
def initialize(name, args)
|
7
|
+
@name = name.slice(3, name.size)
|
8
|
+
@name+= '?' if name[name.size - 1] != '?'
|
9
|
+
@args = args
|
10
|
+
end
|
11
|
+
|
12
|
+
def match?(subject, wont)
|
13
|
+
@name = 'is_a?' if @name == 'a?' || @name == 'an?'
|
14
|
+
match = subject.send @name, *@args
|
15
|
+
|
16
|
+
if wont ? match : !match
|
17
|
+
raise MiniTest::Assertion, "Expected #{subject.inspect} ##{
|
18
|
+
@name} to return: #{ wont ? "false" : "true"
|
19
|
+
}\nbut instead have: #{match.inspect}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
#
|
2
|
+
# Generic validations matcher
|
3
|
+
#
|
4
|
+
# user.must have_valid(:name)
|
5
|
+
# user.must have_valid(:name).with('Nikolay', 'Vasilisa', ...)
|
6
|
+
# user.wont have_valid(:name).with(nil, '', false)
|
7
|
+
#
|
8
|
+
# Credits: we're mimicking the minitest-matchers validation matchers here
|
9
|
+
#
|
10
|
+
class MiniTest::MustWonted::Matcher::Valid
|
11
|
+
def initialize(name)
|
12
|
+
@name = name.to_sym
|
13
|
+
@args = []
|
14
|
+
end
|
15
|
+
|
16
|
+
def match?(subject, wont)
|
17
|
+
if @args.size == 0
|
18
|
+
test!(subject, wont)
|
19
|
+
else
|
20
|
+
@args.each do |value|
|
21
|
+
subject.send "#{@name}=", value
|
22
|
+
test!(subject, wont)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def with(*args)
|
28
|
+
@args = args
|
29
|
+
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
def test!(subject, wont)
|
34
|
+
valid = subject.valid?
|
35
|
+
error = subject.errors[@name]
|
36
|
+
|
37
|
+
if error && !wont
|
38
|
+
raise MiniTest::Assertion, "Expected the #{
|
39
|
+
subject.inspect} to have valid #{@name
|
40
|
+
} with #{subject.send(@name).inspect
|
41
|
+
}\nbut had an error instead: #{error.inspect}"
|
42
|
+
elsif wont && !error
|
43
|
+
raise MiniTest::Assertion, "Expected the #{
|
44
|
+
subject.inspect} to have invalid #{@name
|
45
|
+
} with #{subject.send(@name).inspect
|
46
|
+
}\nbut had no errors for this field instead"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#
|
2
|
+
# The object level `must` | `wont` hooks
|
3
|
+
#
|
4
|
+
class Object
|
5
|
+
#
|
6
|
+
# kicks in the `must` assertion on the object
|
7
|
+
#
|
8
|
+
# smth.must smth
|
9
|
+
# smth.must == somth
|
10
|
+
# ....
|
11
|
+
#
|
12
|
+
def must(*args)
|
13
|
+
MiniTest::MustWonted::Matcher.must(self, *args)
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
# kicks in the `wont` assertion on the object
|
18
|
+
#
|
19
|
+
# smth.wont smth
|
20
|
+
# smth.wont == somth
|
21
|
+
# ....
|
22
|
+
#
|
23
|
+
def wont(*args)
|
24
|
+
MiniTest::MustWonted::Matcher.wont(self, *args)
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
#
|
2
|
+
# Extra sweets for the MiniTest::Spec unit
|
3
|
+
#
|
4
|
+
class MiniTest::Spec
|
5
|
+
|
6
|
+
#
|
7
|
+
# A shortcut to `must` directly on current subject
|
8
|
+
#
|
9
|
+
# subject { Something.new }
|
10
|
+
#
|
11
|
+
# it { must do_something }
|
12
|
+
#
|
13
|
+
def must(*args)
|
14
|
+
subject.must(*args)
|
15
|
+
end
|
16
|
+
|
17
|
+
#
|
18
|
+
# A shortcut to `wont` directly on current subject
|
19
|
+
#
|
20
|
+
# subject { Something.new }
|
21
|
+
#
|
22
|
+
# it { wont do_something }
|
23
|
+
#
|
24
|
+
def wont(*args)
|
25
|
+
subject.wont(*args)
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
# Catching up the magick `be_smthing?` matchers
|
30
|
+
#
|
31
|
+
def method_missing(name, *args)
|
32
|
+
if name.slice(0, 3) == 'be_'
|
33
|
+
MiniTest::MustWonted::Matcher::Magick.new(name, args)
|
34
|
+
elsif respond_to?("assert_#{name}")
|
35
|
+
MiniTest::MustWonted::Matcher::Legacy.new(name, args, self)
|
36
|
+
else
|
37
|
+
super name, *args
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe MiniTest::MustWonted::Matcher::Awesome do
|
4
|
+
|
5
|
+
describe "==" do
|
6
|
+
it "must test correctly" do
|
7
|
+
"22".must == "22"
|
8
|
+
"22".wont == "33"
|
9
|
+
end
|
10
|
+
|
11
|
+
it "must fail correctly" do
|
12
|
+
assert_fails_correctly{ "22".must == "33" }
|
13
|
+
assert_fails_correctly{ "22".wont == "22" }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "!=" do
|
18
|
+
it "must test correctly" do
|
19
|
+
"22".must != "33"
|
20
|
+
"22".wont != "22"
|
21
|
+
end
|
22
|
+
|
23
|
+
it "must fail correctly" do
|
24
|
+
assert_fails_correctly{ "22".must != "22" }
|
25
|
+
assert_fails_correctly{ "22".wont != "33" }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "=~" do
|
30
|
+
it "must test correctly" do
|
31
|
+
"22".must =~ /2/
|
32
|
+
"22".wont =~ /3/
|
33
|
+
end
|
34
|
+
|
35
|
+
it "must fail correctly" do
|
36
|
+
assert_fails_correctly{ "22".must =~ /3/ }
|
37
|
+
assert_fails_correctly{ "22".wont =~ /2/ }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe ">" do
|
42
|
+
it "must test correctly" do
|
43
|
+
22.must > 11
|
44
|
+
22.wont > 33
|
45
|
+
end
|
46
|
+
|
47
|
+
it "must fail correctly" do
|
48
|
+
assert_fails_correctly{ 22.must > 33 }
|
49
|
+
assert_fails_correctly{ 22.must > 22 }
|
50
|
+
assert_fails_correctly{ 22.wont > 11 }
|
51
|
+
assert_fails_correctly{ 22.wont > 21 }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "<" do
|
56
|
+
it "must test correctly" do
|
57
|
+
22.must < 33
|
58
|
+
22.wont < 11
|
59
|
+
end
|
60
|
+
|
61
|
+
it "must fail correctly" do
|
62
|
+
assert_fails_correctly{ 22.must < 11 }
|
63
|
+
assert_fails_correctly{ 22.must < 22 }
|
64
|
+
assert_fails_correctly{ 22.wont < 33 }
|
65
|
+
assert_fails_correctly{ 22.wont < 23 }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe ">=" do
|
70
|
+
it "must test correctly" do
|
71
|
+
22.must >= 11
|
72
|
+
22.must >= 22
|
73
|
+
22.wont >= 33
|
74
|
+
22.wont >= 23
|
75
|
+
end
|
76
|
+
|
77
|
+
it "must fail correctly" do
|
78
|
+
assert_fails_correctly{ 22.must >= 33 }
|
79
|
+
assert_fails_correctly{ 22.must >= 23 }
|
80
|
+
assert_fails_correctly{ 22.wont >= 22 }
|
81
|
+
assert_fails_correctly{ 22.wont >= 11 }
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "<=" do
|
86
|
+
it "must test correctly" do
|
87
|
+
22.must <= 33
|
88
|
+
22.must <= 23
|
89
|
+
22.wont <= 21
|
90
|
+
22.wont <= 11
|
91
|
+
end
|
92
|
+
|
93
|
+
it "must fail correctly" do
|
94
|
+
assert_fails_correctly{ 22.must <= 11 }
|
95
|
+
assert_fails_correctly{ 22.must <= 21 }
|
96
|
+
assert_fails_correctly{ 22.wont <= 22 }
|
97
|
+
assert_fails_correctly{ 22.wont <= 33 }
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe MiniTest::MustWonted::Matcher::Have do
|
4
|
+
|
5
|
+
describe 'simple case' do
|
6
|
+
subject{ Struct.new(:dogs, :cats).new([1,2,3],[1,2]) }
|
7
|
+
|
8
|
+
it "must check correctly" do
|
9
|
+
subject.must have(3).dogs
|
10
|
+
subject.must have(2).cats
|
11
|
+
|
12
|
+
subject.wont have(2).dogs
|
13
|
+
subject.wont have(3).cats
|
14
|
+
end
|
15
|
+
|
16
|
+
it "must fail correctly" do
|
17
|
+
assert_fails_correctly{ subject.must have(3).cats }
|
18
|
+
assert_fails_correctly{ subject.wont have(2).cats }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'case with extra arguments' do
|
23
|
+
class Subject
|
24
|
+
DOGS = {large: [1,2,3,4], small: [1,2]}
|
25
|
+
|
26
|
+
def dogs(size=nil)
|
27
|
+
if size
|
28
|
+
DOGS[size]
|
29
|
+
else
|
30
|
+
DOGS[:large] + DOGS[:small]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
subject { Subject.new }
|
36
|
+
|
37
|
+
it "must handle everything correctly" do
|
38
|
+
subject.must have(4).dogs(:large)
|
39
|
+
subject.must have(2).dogs(:small)
|
40
|
+
subject.must have(6).dogs
|
41
|
+
|
42
|
+
subject.wont have(2).dogs(:large)
|
43
|
+
subject.wont have(3).dogs(:small)
|
44
|
+
subject.wont have(4).dogs
|
45
|
+
end
|
46
|
+
|
47
|
+
it "must fail correctly" do
|
48
|
+
assert_fails_correctly{ subject.must have(3).dogs(:large) }
|
49
|
+
assert_fails_correctly{ subject.wont have(4).dogs(:large) }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "fallback with the 'items'" do
|
54
|
+
it "must handle 'items' call as the size one" do
|
55
|
+
[1,2,3].must have(3).items
|
56
|
+
[1 ].must have(1).item
|
57
|
+
|
58
|
+
[1,2,3].wont have(5).items
|
59
|
+
[1,2 ].wont have(1).item
|
60
|
+
end
|
61
|
+
|
62
|
+
it "must fail correctly" do
|
63
|
+
assert_fails_correctly{ [1,2].must have(5).items }
|
64
|
+
assert_fails_correctly{ [1,2].wont have(2).items }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe MiniTest::MustWonted::Matcher::Legacy do
|
4
|
+
|
5
|
+
describe "simple case" do
|
6
|
+
it "must be handled correctly" do
|
7
|
+
'3'.must equal('3')
|
8
|
+
[3].must equal([3])
|
9
|
+
|
10
|
+
'2'.wont equal('3')
|
11
|
+
[2].wont equal([3])
|
12
|
+
end
|
13
|
+
|
14
|
+
it "must fail correctly" do
|
15
|
+
assert_fails_correctly{ '2'.must equal('3') }
|
16
|
+
assert_fails_correctly{ '2'.wont equal('2') }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "custom made assertions" do
|
21
|
+
subject { 'subject' }
|
22
|
+
|
23
|
+
def assert_do_custom_stuff(subj, value)
|
24
|
+
assert_equal subj, subject
|
25
|
+
assert_equal value, 3
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should catch up with them correctly" do
|
29
|
+
subject.must do_custom_stuff(3)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "must fail when called with 'wont' coz there's no refute" do
|
33
|
+
assert_raises RuntimeError, "Couldn't find the 'refute_do_custom_stuff' matcher" do
|
34
|
+
subject.wont do_custom_stuff(3)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe MiniTest::MustWonted::Matcher::Magick do
|
4
|
+
|
5
|
+
describe "plain calls" do
|
6
|
+
|
7
|
+
it "must be handled correctly" do
|
8
|
+
[].must be_empty
|
9
|
+
[].must be_empty?
|
10
|
+
|
11
|
+
[0].wont be_empty
|
12
|
+
[0].wont be_empty?
|
13
|
+
end
|
14
|
+
|
15
|
+
it "must fail correctly" do
|
16
|
+
assert_fails_correctly { [0].must be_empty }
|
17
|
+
assert_fails_correctly { [0].must be_empty? }
|
18
|
+
assert_fails_correctly { [].wont be_empty }
|
19
|
+
assert_fails_correctly { [].wont be_empty? }
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "calls with arguments" do
|
25
|
+
class BeTest
|
26
|
+
def tested?(one, two)
|
27
|
+
one > two
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
subject { BeTest.new }
|
32
|
+
|
33
|
+
it "must handle params correctly" do
|
34
|
+
must be_tested(2, 1)
|
35
|
+
wont be_tested(1, 2)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "must fail correctly" do
|
39
|
+
assert_fails_correctly { must be_tested(1, 2) }
|
40
|
+
assert_fails_correctly { wont be_tested(2, 1) }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe 'be_a/be_an matchers' do
|
45
|
+
it "must handle them correctly" do
|
46
|
+
'0'.must be_a(String)
|
47
|
+
[0].must be_an(Array)
|
48
|
+
|
49
|
+
'0'.wont be_an(Array)
|
50
|
+
[0].wont be_a(String)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe MiniTest::MustWonted::Matcher::Valid do
|
4
|
+
|
5
|
+
class User
|
6
|
+
attr_accessor :name, :email, :errors
|
7
|
+
|
8
|
+
def initialize(params)
|
9
|
+
@name = params[:name]
|
10
|
+
@email = params[:email]
|
11
|
+
end
|
12
|
+
|
13
|
+
def valid?
|
14
|
+
@errors = {}
|
15
|
+
|
16
|
+
@errors[:name] = ["Can't be blank"] if !@name
|
17
|
+
@errors[:email] = ["Can't be blank"] if !@email
|
18
|
+
|
19
|
+
@errors.size == 0
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "without options" do
|
24
|
+
it "must validate objects correctly" do
|
25
|
+
user = User.new(name: 'Nikolay', email: 'nikolay@theosom.com')
|
26
|
+
|
27
|
+
user.must have_valid(:name)
|
28
|
+
user.must have_valid(:email)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "must invalidate objects correctly" do
|
32
|
+
user = User.new({})
|
33
|
+
|
34
|
+
user.wont have_valid(:name)
|
35
|
+
user.wont have_valid(:email)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "must fail correctly" do
|
39
|
+
user = User.new(name: 'Nikolay')
|
40
|
+
|
41
|
+
assert_fails_correctly{ user.must have_valid(:email) }
|
42
|
+
assert_fails_correctly{ user.wont have_valid(:name) }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "with a list of options" do
|
47
|
+
let(:user) { User.new({}) }
|
48
|
+
|
49
|
+
it "must validate objects correctly" do
|
50
|
+
user.must have_valid(:name).with('Nikolay', 'Vasilisa')
|
51
|
+
user.must have_valid(:email).with('nikolay@theosom.com', 'vasilisa@theosom.com')
|
52
|
+
end
|
53
|
+
|
54
|
+
it "must invalidate objects correctly" do
|
55
|
+
user.wont have_valid(:name).with(nil, false)
|
56
|
+
user.wont have_valid(:email).with(nil, false)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "must fail correctly with wrong data" do
|
60
|
+
assert_fails_correctly{ user.must have_valid(:name).with(nil) }
|
61
|
+
assert_fails_correctly{ user.wont have_valid(:name).with("Nikolay") }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe MiniTest::MustWonted::Matcher do
|
4
|
+
subject{ nil }
|
5
|
+
|
6
|
+
Matcher = MiniTest::MustWonted::Matcher
|
7
|
+
|
8
|
+
describe ".must" do
|
9
|
+
describe "without a matcher" do
|
10
|
+
let(:matcher) { Matcher.must(subject) }
|
11
|
+
|
12
|
+
it "must create an Awesome matcher" do
|
13
|
+
assert_instance_of Matcher::Awesome, matcher
|
14
|
+
end
|
15
|
+
|
16
|
+
it "must assign the current subject to the matcher" do
|
17
|
+
matcher.subject.must_equal subject
|
18
|
+
end
|
19
|
+
|
20
|
+
it "must set the matcher as a straight one" do
|
21
|
+
matcher.flipped.must_equal false
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe ".wont" do
|
27
|
+
describe "without a matcher" do
|
28
|
+
let(:matcher) { Matcher.wont(subject) }
|
29
|
+
|
30
|
+
it "must create an Awesome matcher" do
|
31
|
+
assert_instance_of Matcher::Awesome, matcher
|
32
|
+
end
|
33
|
+
|
34
|
+
it "must assign the current subject to the matcher" do
|
35
|
+
matcher.subject.must_equal subject
|
36
|
+
end
|
37
|
+
|
38
|
+
it "must set the matcher as a flipped one" do
|
39
|
+
matcher.flipped.must_equal true
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Object do
|
4
|
+
|
5
|
+
subject { nil }
|
6
|
+
|
7
|
+
describe "#must" do
|
8
|
+
it "must be present on any object" do
|
9
|
+
assert subject.respond_to?(:must)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "must bypass the call into Matcher.must" do
|
13
|
+
MiniTest::MustWonted::Matcher.expects(:must).with(subject, 'something')
|
14
|
+
|
15
|
+
subject.must 'something'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#wont" do
|
20
|
+
it "must be present on any object" do
|
21
|
+
assert subject.respond_to?(:wont)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "must bypass the call into Matcher.wont" do
|
25
|
+
MiniTest::MustWonted::Matcher.expects(:wont).with(subject, 'something')
|
26
|
+
|
27
|
+
subject.wont 'something'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
|
4
|
+
describe MiniTest::Spec do
|
5
|
+
subject { {} }
|
6
|
+
|
7
|
+
it "must allow to use must" do
|
8
|
+
assert respond_to?(:must)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "must allow to use wont" do
|
12
|
+
assert respond_to?(:wont)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should bypass the 'must' calls to the current subject" do
|
16
|
+
subject.expects(:must).with('something')
|
17
|
+
must 'something'
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should bypass the 'wont' calls to the current subject" do
|
21
|
+
subject.expects(:wont).with('something')
|
22
|
+
wont 'something'
|
23
|
+
end
|
24
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require_relative "../lib/minitest-mustwonted"
|
2
|
+
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require 'minitest/pride'
|
5
|
+
require 'mocha/setup'
|
6
|
+
|
7
|
+
class MiniTest::Spec
|
8
|
+
def assert_fails_correctly
|
9
|
+
# TODO make sure that the errors are raised with correct file/line references
|
10
|
+
-> { yield }.must_raise MiniTest::Assertion
|
11
|
+
end
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: minitest-mustwonted
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Nikolay Nemshilov
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-01-29 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: minitest
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
description: Provides a new unversal and esily extendable matchers engine
|
31
|
+
email: nemshilov@gmail.com
|
32
|
+
executables: []
|
33
|
+
extensions: []
|
34
|
+
extra_rdoc_files: []
|
35
|
+
files:
|
36
|
+
- lib/minitest/mustwonted/matcher/awesome.rb
|
37
|
+
- lib/minitest/mustwonted/matcher/have.rb
|
38
|
+
- lib/minitest/mustwonted/matcher/legacy.rb
|
39
|
+
- lib/minitest/mustwonted/matcher/magick.rb
|
40
|
+
- lib/minitest/mustwonted/matcher/valid.rb
|
41
|
+
- lib/minitest/mustwonted/matcher.rb
|
42
|
+
- lib/minitest/mustwonted/object.rb
|
43
|
+
- lib/minitest/mustwonted/run.rb
|
44
|
+
- lib/minitest/mustwonted/spec.rb
|
45
|
+
- lib/minitest/mustwonted.rb
|
46
|
+
- lib/minitest-mustwonted.rb
|
47
|
+
- test/mustwonted/matcher/awesome_test.rb
|
48
|
+
- test/mustwonted/matcher/have_test.rb
|
49
|
+
- test/mustwonted/matcher/legacy_test.rb
|
50
|
+
- test/mustwonted/matcher/magick_test.rb
|
51
|
+
- test/mustwonted/matcher/valid_test.rb
|
52
|
+
- test/mustwonted/matcher_test.rb
|
53
|
+
- test/mustwonted/object_test.rb
|
54
|
+
- test/mustwonted/spec_test.rb
|
55
|
+
- test/test_helper.rb
|
56
|
+
- README.md
|
57
|
+
homepage: http://github.com/MadRabbit/minitest-mustwonted
|
58
|
+
licenses: []
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options: []
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
71
|
+
requirements:
|
72
|
+
- - ! '>='
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
requirements: []
|
76
|
+
rubyforge_project:
|
77
|
+
rubygems_version: 1.8.23
|
78
|
+
signing_key:
|
79
|
+
specification_version: 3
|
80
|
+
summary: new must/wont matchers engine for minitest
|
81
|
+
test_files: []
|