minitest-mustwonted 1.0.0
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/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: []
|