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 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,5 @@
1
+ #
2
+ # Gem/require hook
3
+ #
4
+
5
+ require File.dirname(__FILE__) + "/minitest/mustwonted"
@@ -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,8 @@
1
+ #
2
+ # Console runnner
3
+ #
4
+ module MiniTest::MustWonted
5
+ def self.run(args)
6
+ puts args
7
+ end
8
+ 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
@@ -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: []