assert 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +3 -1
- data/README.rdoc +6 -6
- data/Rakefile +2 -3
- data/assert.gemspec +1 -0
- data/lib/assert/assertions.rb +30 -30
- data/lib/assert/context.rb +71 -66
- data/lib/assert/macro.rb +14 -0
- data/lib/assert/macros/methods.rb +52 -0
- data/lib/assert/rake_tasks.rb +31 -13
- data/lib/assert/result.rb +12 -4
- data/lib/assert/result_set.rb +2 -2
- data/lib/assert/runner.rb +2 -6
- data/lib/assert/setup/autorun.rb +0 -1
- data/lib/assert/suite.rb +19 -15
- data/lib/assert/test.rb +6 -17
- data/lib/assert/version.rb +1 -1
- data/lib/assert/view/base.rb +1 -1
- data/lib/assert/view/terminal.rb +8 -30
- data/test/assertions/assert_block_test.rb +1 -1
- data/test/assertions/assert_empty_test.rb +43 -0
- data/test/assertions/assert_equal_test.rb +43 -0
- data/test/assertions/assert_includes_test.rb +44 -0
- data/test/assertions/assert_instance_of_test.rb +4 -4
- data/test/assertions/assert_kind_of_test.rb +3 -3
- data/test/assertions/assert_match_test.rb +43 -0
- data/test/assertions/assert_nil_test.rb +43 -0
- data/test/assertions/assert_not_block_test.rb +1 -1
- data/test/assertions/assert_not_empty_test.rb +43 -0
- data/test/assertions/assert_not_equal_test.rb +43 -0
- data/test/assertions/assert_not_included_test.rb +44 -0
- data/test/assertions/assert_not_instance_of_test.rb +4 -4
- data/test/assertions/assert_not_kind_of_test.rb +2 -2
- data/test/assertions/assert_not_match_test.rb +43 -0
- data/test/assertions/assert_not_nil_test.rb +43 -0
- data/test/assertions/assert_not_respond_to_test.rb +6 -6
- data/test/assertions/assert_not_same_test.rb +45 -0
- data/test/assertions/assert_respond_to_test.rb +6 -6
- data/test/assertions/assert_same_test.rb +45 -0
- data/test/assertions_test.rb +21 -298
- data/test/context/class_methods_test.rb +81 -112
- data/test/context_test.rb +35 -40
- data/test/helper.rb +5 -2
- data/test/irb.rb +2 -5
- data/test/macro_test.rb +99 -0
- data/test/options_test.rb +2 -2
- data/test/result_set_test.rb +47 -54
- data/test/result_test.rb +4 -17
- data/test/runner_test.rb +2 -10
- data/test/suite_test.rb +85 -13
- data/test/test/running_test.rb +19 -28
- data/test/test_test.rb +130 -128
- data/test/view_test.rb +3 -17
- metadata +50 -7
data/Gemfile.lock
CHANGED
data/README.rdoc
CHANGED
@@ -4,16 +4,16 @@ Test::Unit style testing framework, just better than Test::Unit.
|
|
4
4
|
|
5
5
|
== What Assert is
|
6
6
|
|
7
|
-
* *
|
8
|
-
* *First Class
|
9
|
-
* *MVC
|
10
|
-
* *Backwards compatible
|
7
|
+
* *Framework*: you define tests and the context they run in - Assert runs them. Everything is pure ruby so use any 3rd party testing tools you like. Create 3rd party tools that extend Assert behavior.
|
8
|
+
* *First Class*: everything is a first class object and can be extended to your liking (and should be)
|
9
|
+
* *MVC*: tests and how they are defined (M) and executed (C) are distinct from how you view the test results (V).
|
10
|
+
* *Backwards compatible*: (assuming a few minor tweaks) with Test::Unit test suites
|
11
11
|
|
12
12
|
== What Assert is not
|
13
13
|
|
14
14
|
* *Rspec*
|
15
|
-
* *Unit/Functional/Integration/etc
|
16
|
-
* *Mock/Spec/BDD/Factories/etc
|
15
|
+
* *Unit/Functional/Integration/etc*: Assert is agnostic - you define whatever kinds of tests you like (one or more of the above) and assert runs them in context.
|
16
|
+
* *Mock/Spec/BDD/Factories/etc*: Assert is the framework and there are a variety of 3rd party tools to do such things - feel free to use whatever you like.
|
17
17
|
|
18
18
|
== Description
|
19
19
|
|
data/Rakefile
CHANGED
data/assert.gemspec
CHANGED
data/lib/assert/assertions.rb
CHANGED
@@ -67,7 +67,7 @@ module Assert
|
|
67
67
|
|
68
68
|
|
69
69
|
|
70
|
-
def assert_respond_to(
|
70
|
+
def assert_respond_to(method, object, fail_desc=nil)
|
71
71
|
what_failed_msg = [
|
72
72
|
"Expected #{object.inspect} (#{object.class}) to ",
|
73
73
|
"respond to ##{method}."
|
@@ -75,7 +75,7 @@ module Assert
|
|
75
75
|
assert(object.respond_to?(method), fail_desc, what_failed_msg)
|
76
76
|
end
|
77
77
|
|
78
|
-
def assert_not_respond_to(
|
78
|
+
def assert_not_respond_to(method, object, fail_desc=nil)
|
79
79
|
what_failed_msg = [
|
80
80
|
"#{object.inspect} (#{object.class}) not expected to ",
|
81
81
|
"respond to ##{method}."
|
@@ -86,59 +86,58 @@ module Assert
|
|
86
86
|
|
87
87
|
|
88
88
|
|
89
|
-
def assert_same(
|
89
|
+
def assert_same(expected, actual, fail_desc=nil)
|
90
90
|
what_failed_msg = [
|
91
|
-
"Expected #{
|
92
|
-
"as #{
|
91
|
+
"Expected #{expected} (#{expected.object_id}) to be the same ",
|
92
|
+
"as #{actual} (#{actual.object_id})."
|
93
93
|
].join
|
94
|
-
assert(
|
94
|
+
assert(actual.equal?(expected), fail_desc, what_failed_msg)
|
95
95
|
end
|
96
96
|
|
97
|
-
def assert_not_same(
|
97
|
+
def assert_not_same(expected, actual, fail_desc=nil)
|
98
98
|
what_failed_msg = [
|
99
|
-
"#{
|
100
|
-
"as #{
|
99
|
+
"#{expected} (#{expected.object_id}) not expected to be the same ",
|
100
|
+
"as #{actual} (#{actual.object_id})."
|
101
101
|
].join
|
102
|
-
assert(!
|
102
|
+
assert(!actual.equal?(expected), fail_desc, what_failed_msg)
|
103
103
|
end
|
104
104
|
alias_method :refute_same, :assert_not_same
|
105
105
|
|
106
106
|
|
107
107
|
|
108
|
-
def assert_equal(
|
109
|
-
what_failed_msg = "Expected #{
|
110
|
-
assert(
|
108
|
+
def assert_equal(expected, actual, fail_desc=nil)
|
109
|
+
what_failed_msg = "Expected #{expected.inspect}, not #{actual.inspect}."
|
110
|
+
assert(actual == expected, fail_desc, what_failed_msg)
|
111
111
|
end
|
112
112
|
|
113
|
-
def assert_not_equal(
|
113
|
+
def assert_not_equal(expected, actual, fail_desc=nil)
|
114
114
|
what_failed_msg = [
|
115
|
-
"#{
|
115
|
+
"#{expected.inspect} not expected to be equal ", "to #{actual.inspect}."
|
116
116
|
].join
|
117
|
-
assert(
|
117
|
+
assert(actual != expected, fail_desc, what_failed_msg)
|
118
118
|
end
|
119
119
|
alias_method :refute_equal, :assert_not_equal
|
120
120
|
|
121
121
|
|
122
122
|
|
123
|
-
def assert_match(
|
124
|
-
what_failed_msg = "Expected #{
|
125
|
-
|
126
|
-
assert(
|
123
|
+
def assert_match(expected, actual, fail_desc=nil)
|
124
|
+
what_failed_msg = "Expected #{actual.inspect} to match #{expected.inspect}."
|
125
|
+
expected = /#{Regexp.escape(expected)}/ if String === expected && String === actual
|
126
|
+
assert(actual =~ expected, fail_desc, what_failed_msg)
|
127
127
|
end
|
128
128
|
|
129
|
-
def assert_not_match(
|
129
|
+
def assert_not_match(expected, actual, fail_desc=nil)
|
130
130
|
what_failed_msg = [
|
131
|
-
"#{
|
131
|
+
"#{actual.inspect} not expected to ", "match #{expected.inspect}."
|
132
132
|
].join
|
133
|
-
|
134
|
-
assert(
|
133
|
+
expected = /#{Regexp.escape(expected)}/ if String === expected && String === actual
|
134
|
+
assert(actual !~ expected, fail_desc, what_failed_msg)
|
135
135
|
end
|
136
136
|
alias_method :refute_match, :assert_not_match
|
137
137
|
alias_method :assert_no_match, :assert_not_match
|
138
138
|
|
139
139
|
|
140
140
|
|
141
|
-
# TODO: tests!
|
142
141
|
def assert_empty(collection, fail_desc=nil)
|
143
142
|
what_failed_msg = "Expected #{collection.inspect} to be empty."
|
144
143
|
assert(collection.empty?, fail_desc, what_failed_msg)
|
@@ -152,21 +151,22 @@ module Assert
|
|
152
151
|
|
153
152
|
|
154
153
|
|
155
|
-
|
156
|
-
def assert_includes(collection, object, fail_desc=nil)
|
154
|
+
def assert_includes(object, collection, fail_desc=nil)
|
157
155
|
what_failed_msg = "Expected #{collection.inspect} to include #{object.inspect}."
|
158
156
|
assert(collection.include?(object), fail_desc, what_failed_msg)
|
159
157
|
end
|
158
|
+
alias_method :assert_included, :assert_includes
|
160
159
|
|
161
|
-
def
|
160
|
+
def assert_not_includes(object, collection, fail_desc=nil)
|
162
161
|
what_failed_msg = "Expected #{collection.inspect} to not include #{object.inspect}."
|
163
162
|
assert(!collection.include?(object), fail_desc, what_failed_msg)
|
164
163
|
end
|
165
|
-
alias_method :
|
164
|
+
alias_method :assert_not_included, :assert_not_includes
|
165
|
+
alias_method :refute_includes, :assert_not_includes
|
166
|
+
alias_method :refute_included, :assert_not_includes
|
166
167
|
|
167
168
|
|
168
169
|
|
169
|
-
# TODO: tests!
|
170
170
|
def assert_nil(object, fail_desc=nil)
|
171
171
|
what_failed_msg = "Expected nil, not #{object.inspect}."
|
172
172
|
assert(object.nil?, fail_desc, what_failed_msg)
|
data/lib/assert/context.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
require 'assert/suite'
|
2
2
|
require 'assert/assertions'
|
3
3
|
require 'assert/result'
|
4
|
+
require 'assert/macros/methods'
|
4
5
|
|
5
6
|
module Assert
|
6
7
|
class Context
|
7
8
|
include Assert::Assertions
|
9
|
+
include Assert::Macros::Methods
|
8
10
|
|
9
11
|
# a Context is a scope for tests to run in. Contexts have setup and
|
10
12
|
# teardown blocks, subjects, and descriptions. Tests are run in the
|
@@ -19,7 +21,6 @@ module Assert
|
|
19
21
|
|
20
22
|
# put all logic here to keep context instances pure for running tests
|
21
23
|
class << self
|
22
|
-
attr_accessor :subject_block
|
23
24
|
|
24
25
|
def setup_once(&block)
|
25
26
|
Assert.suite.setup(&block)
|
@@ -31,84 +32,86 @@ module Assert
|
|
31
32
|
end
|
32
33
|
alias_method :after_once, :teardown_once
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
35
|
+
# Add a setup block to run before each test or run the list of teardown blocks in given scope
|
36
|
+
def setup(scope=nil, &block)
|
37
|
+
if block_given?
|
38
|
+
self.setups << block
|
39
|
+
elsif scope
|
40
|
+
# setup parent before child
|
41
|
+
self.superclass.setup(scope) if self.superclass.respond_to?(:setup)
|
42
|
+
self.setups.each{|setup| scope.instance_eval(&setup)}
|
43
|
+
end
|
37
44
|
end
|
38
45
|
alias_method :before, :setup
|
39
46
|
|
40
|
-
|
41
|
-
|
42
|
-
|
47
|
+
# Add a teardown block to run after each test or run the list of teardown blocks in given scope
|
48
|
+
def teardown(scope=nil, &block)
|
49
|
+
if block_given?
|
50
|
+
self.teardowns << block
|
51
|
+
elsif scope
|
52
|
+
# teardown child before parent
|
53
|
+
self.teardowns.each{|teardown| scope.instance_eval(&teardown)}
|
54
|
+
self.superclass.teardown(scope) if self.superclass.respond_to?(:teardown)
|
55
|
+
end
|
43
56
|
end
|
44
57
|
alias_method :after, :teardown
|
45
58
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
59
|
+
# Add a piece of description text or return the full description for the context
|
60
|
+
def description(text=nil)
|
61
|
+
if text
|
62
|
+
self.descriptions << text.to_s
|
63
|
+
else
|
64
|
+
parent = self.superclass.desc if self.superclass.respond_to?(:desc)
|
65
|
+
own = self.descriptions
|
66
|
+
[parent, *own].compact.reject do |p|
|
67
|
+
p.to_s.empty?
|
68
|
+
end.join(" ")
|
69
|
+
end
|
52
70
|
end
|
71
|
+
alias_method :desc, :description
|
53
72
|
|
54
|
-
def
|
55
|
-
|
56
|
-
|
73
|
+
def subject(&block)
|
74
|
+
if block_given?
|
75
|
+
@subject = block
|
76
|
+
else
|
77
|
+
@subject || if superclass.respond_to?(:subject)
|
78
|
+
superclass.subject
|
79
|
+
end
|
57
80
|
end
|
58
|
-
(inherited_blocks || []) + self.setup_blocks
|
59
81
|
end
|
60
82
|
|
61
|
-
def
|
62
|
-
|
63
|
-
|
83
|
+
def should(desc_or_macro, &block)
|
84
|
+
if desc_or_macro.kind_of?(Macro)
|
85
|
+
instance_eval(&desc_or_macro)
|
86
|
+
else
|
87
|
+
raise ArgumentError, "please provide a test block" unless block_given?
|
88
|
+
method_name = "test: should #{desc_or_macro}"
|
89
|
+
if method_defined?(method_name)
|
90
|
+
from = caller.first
|
91
|
+
puts "WARNING: should #{desc_or_macro.inspect} is redefining #{method_name}!"
|
92
|
+
puts " from: #{from}"
|
93
|
+
end
|
94
|
+
define_method(method_name, &block)
|
64
95
|
end
|
65
|
-
(inherited_blocks || []) + self.teardown_blocks
|
66
96
|
end
|
67
97
|
|
68
|
-
def desc
|
69
|
-
|
70
|
-
self.descriptions << text
|
98
|
+
def should_eventually(desc, &block)
|
99
|
+
should(desc) { skip }
|
71
100
|
end
|
72
|
-
alias_method :
|
101
|
+
alias_method :should_skip, :should_eventually
|
102
|
+
|
103
|
+
protected
|
73
104
|
|
74
105
|
def descriptions
|
75
106
|
@descriptions ||= []
|
76
107
|
end
|
77
108
|
|
78
|
-
def
|
79
|
-
|
80
|
-
superclass.full_description
|
81
|
-
end
|
82
|
-
parts = [ inherited_description ].push(self.descriptions).flatten.reject do |part|
|
83
|
-
!part || part.to_s.empty?
|
84
|
-
end
|
85
|
-
parts.join(" ") if !parts.empty?
|
86
|
-
end
|
87
|
-
|
88
|
-
def subject(&block)
|
89
|
-
raise ArgumentError, "please provide a subject block" unless block_given?
|
90
|
-
self.subject_block = block
|
91
|
-
end
|
92
|
-
|
93
|
-
def subject_block
|
94
|
-
@subject_block ||= if superclass.respond_to?(:subject_block)
|
95
|
-
superclass.subject_block
|
96
|
-
end
|
109
|
+
def setups
|
110
|
+
@setups ||= []
|
97
111
|
end
|
98
112
|
|
99
|
-
def
|
100
|
-
|
101
|
-
method_name = "test: should #{desc}"
|
102
|
-
if method_defined?(method_name)
|
103
|
-
from = caller.first
|
104
|
-
puts "WARNING: should #{desc.inspect} is redefining #{method_name}!"
|
105
|
-
puts " from: #{from}"
|
106
|
-
end
|
107
|
-
define_method(method_name, &block)
|
108
|
-
end
|
109
|
-
|
110
|
-
def should_eventually(desc, &block)
|
111
|
-
should(desc){ skip }
|
113
|
+
def teardowns
|
114
|
+
@teardowns ||= []
|
112
115
|
end
|
113
116
|
|
114
117
|
end
|
@@ -166,8 +169,8 @@ module Assert
|
|
166
169
|
end
|
167
170
|
|
168
171
|
def subject
|
169
|
-
if
|
170
|
-
instance_eval(&
|
172
|
+
if subj = self.class.subject
|
173
|
+
instance_eval(&subj)
|
171
174
|
end
|
172
175
|
end
|
173
176
|
|
@@ -177,6 +180,15 @@ module Assert
|
|
177
180
|
|
178
181
|
protected
|
179
182
|
|
183
|
+
# Returns a Proc that will output a custom message along with the default fail message.
|
184
|
+
def fail_message(fail_desc=nil, &what_failed)
|
185
|
+
fail_desc.kind_of?(::Proc) ? fail_desc : Proc.new do
|
186
|
+
[ fail_desc, what_failed.call ].compact.join("\n")
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
private
|
191
|
+
|
180
192
|
def capture_result
|
181
193
|
if block_given?
|
182
194
|
result = yield @__running_test__.name, caller
|
@@ -185,12 +197,5 @@ module Assert
|
|
185
197
|
end
|
186
198
|
end
|
187
199
|
|
188
|
-
# Returns a Proc that will output a custom message along with the default fail message.
|
189
|
-
def fail_message(fail_desc=nil, &what_failed)
|
190
|
-
fail_desc.kind_of?(::Proc) ? fail_desc : Proc.new do
|
191
|
-
[ what_failed.call, fail_desc ].compact.join("\n")
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
200
|
end
|
196
201
|
end
|
data/lib/assert/macro.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
module Assert
|
2
|
+
class Macro < ::Proc
|
3
|
+
|
4
|
+
# this class is essentially a way to define a custom set of tests using
|
5
|
+
# arguments. When passed as an argument to the 'should' method, a macro
|
6
|
+
# will be instance_eval'd in that Assert::Context.
|
7
|
+
|
8
|
+
def initialize(*args, &block)
|
9
|
+
raise ArgumentError unless block_given?
|
10
|
+
super()
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'assert/macro'
|
2
|
+
|
3
|
+
module Assert::Macros
|
4
|
+
module Methods
|
5
|
+
|
6
|
+
def self.included(receiver)
|
7
|
+
receiver.send(:extend, ClassMethods)
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
|
12
|
+
def have_instance_method(*methods)
|
13
|
+
Assert::Macro.new do
|
14
|
+
methods.each do |method|
|
15
|
+
should "respond to instance method ##{method}" do
|
16
|
+
assert_respond_to method, subject, "#{subject.class.name} does not have instance method ##{method}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
alias_method :have_instance_methods, :have_instance_method
|
22
|
+
|
23
|
+
def have_class_method(*methods)
|
24
|
+
Assert::Macro.new do
|
25
|
+
methods.each do |method|
|
26
|
+
should "respond to class method ##{method}" do
|
27
|
+
assert_respond_to method, subject.class, "#{subject.class.name} does not have class method ##{method}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
alias_method :have_class_methods, :have_class_method
|
33
|
+
|
34
|
+
def have_reader(*methods)
|
35
|
+
have_instance_methods(*methods)
|
36
|
+
end
|
37
|
+
alias_method :have_readers, :have_reader
|
38
|
+
|
39
|
+
def have_writer(*methods)
|
40
|
+
have_instance_methods(*methods.collect{|m| "#{m}="})
|
41
|
+
end
|
42
|
+
alias_method :have_writers, :have_writer
|
43
|
+
|
44
|
+
def have_accessor(*methods)
|
45
|
+
have_instance_methods(*methods.collect{|m| [m, "#{m}="]}.flatten)
|
46
|
+
end
|
47
|
+
alias_method :have_accessors, :have_accessor
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|