assert 0.1.0 → 0.2.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/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
|