clean_test 0.11.0 → 1.0.0.rc1
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.rdoc +15 -8
- data/Rakefile +52 -6
- data/clean_test.gemspec +1 -0
- data/lib/clean_test/any.rb +45 -112
- data/lib/clean_test/given_when_then.rb +68 -98
- data/lib/clean_test/version.rb +1 -1
- data/test/test_any.rb +0 -51
- data/test/{test_simple_given.rb → test_given_when_then.rb} +23 -1
- metadata +99 -37
data/README.rdoc
CHANGED
@@ -8,6 +8,9 @@ Get your Test::Unit test cases readable and fluent, without RSpec, magic, or cra
|
|
8
8
|
|
9
9
|
This library is a set of small, simple tools to make your Test::Unit test cases easy to understand. This isn't a massive change in how you write tests, but simply some helpful things will make your tests easier to read.
|
10
10
|
|
11
|
+
* {Source}[http://www.github.com/davetron5000/clean_test]
|
12
|
+
* {RDoc}[http://davetron5000.github.com/clean_test/rdoc]
|
13
|
+
|
11
14
|
The main problems this library solves are:
|
12
15
|
|
13
16
|
* Understanding what part of a test method is setup, test, and evaluation
|
@@ -94,7 +97,7 @@ But, don't fret, this is not an all-or-nothing proposition. Use whichever parts
|
|
94
97
|
|
95
98
|
I'm tired of unreadable tests. Tests should be good, clean code, and it shoud be easy to see what's being tested. This is especially important when there is a lot of setup required to simulate something.
|
96
99
|
|
97
|
-
I also don't believe we need to resort
|
100
|
+
I also don't believe we need to resort to a lot of metaprogramming tricks just to get our tests in this shape. RSpec, for example, creates strange constructs for things that are much more straightforward in plain Ruby. I like Test::Unit, and with just a bit of helper methods, we can make nice, readable tests, using just Ruby.
|
98
101
|
|
99
102
|
=== But the test methods are longer!
|
100
103
|
|
@@ -260,11 +263,11 @@ In both cases, the language is the same, and the person is slightly different.
|
|
260
263
|
|
261
264
|
=== What did that have to do with this gem?
|
262
265
|
|
263
|
-
Nothing. That's the point. You have the power already.
|
266
|
+
Nothing. That's the point. You have the power already. That being said, +Given+ and friends can take a symbol representing the name of a method to call, in lieu of a block:
|
264
267
|
|
265
268
|
class SalutationTest << Clean::Test::TestCase
|
266
269
|
test_that "greeting works" do
|
267
|
-
Given english_salutation_for
|
270
|
+
Given :english_salutation_for,male_with_first_name("David")
|
268
271
|
When {
|
269
272
|
@greeting = @salutation.greeting
|
270
273
|
}
|
@@ -274,7 +277,7 @@ Nothing. That's the point. You have the power already. Note that, since +Give
|
|
274
277
|
end
|
275
278
|
|
276
279
|
test_that "greeting works for no first name" do
|
277
|
-
Given english_salutation_for(
|
280
|
+
Given :english_salutation_for,male_with_no_first_name("Copeland")
|
278
281
|
When {
|
279
282
|
@greeting = @salutation.greeting
|
280
283
|
}
|
@@ -293,13 +296,10 @@ Nothing. That's the point. You have the power already. Note that, since +Give
|
|
293
296
|
end
|
294
297
|
|
295
298
|
def english_salutation_for(person)
|
296
|
-
|
297
|
-
@salutation = Salutation.new(person,Language.new("English","en"))
|
298
|
-
}
|
299
|
+
@salutation = Salutation.new(person,Language.new("English","en"))
|
299
300
|
end
|
300
301
|
end
|
301
302
|
|
302
|
-
This sort of thing can get confusing, but sometimes works well.
|
303
303
|
|
304
304
|
=== Why Any instead of Faker?
|
305
305
|
|
@@ -314,6 +314,13 @@ Again, FactoryGirl goes through metaprogramming hoops to do something we can alr
|
|
314
314
|
|
315
315
|
Further, the +Any+ module is extensible, in that you can do stuff like <tt>any Person</tt>, but you can, and should, just use methods. Any helps out with primitives that we tend to use a lot: numbers and strings. It's just simpler and, with less moving parts, more predictable. This means you spend more time on your tests than on your test infrastructure.
|
316
316
|
|
317
|
+
=== Any uses random numbers and strings. Tests aren't repeatable!
|
318
|
+
|
319
|
+
You can make them repeatable by explicitly setting the random seed to a literal value. Also, including Any will record
|
320
|
+
the random seed used and output it. You can then set +RANDOM_SEED+ in the environment to re-run he tests using that seed.
|
321
|
+
|
322
|
+
Keep in mind that if _any_ value will work, random values shouldn't be a problem.
|
323
|
+
|
317
324
|
=== What about not using the base class?
|
318
325
|
|
319
326
|
To use Any on its own:
|
data/Rakefile
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
require 'bundler'
|
2
|
-
gem 'rdoc' # I need to use the installed RDoc gem, not what comes with the system
|
3
2
|
require 'rake/clean'
|
4
3
|
require 'rake/testtask'
|
5
|
-
require '
|
4
|
+
require 'sdoc'
|
6
5
|
|
7
6
|
include Rake::DSL
|
8
7
|
|
@@ -17,12 +16,59 @@ Rake::TestTask.new do |t|
|
|
17
16
|
end
|
18
17
|
|
19
18
|
desc 'build rdoc'
|
20
|
-
|
19
|
+
task :rdoc => [:build_rdoc, :hack_css]
|
20
|
+
|
21
|
+
RDoc::Task.new(:build_rdoc) do |rd|
|
21
22
|
rd.main = "README.rdoc"
|
22
|
-
rd.
|
23
|
+
rd.options << '-f' << 'sdoc'
|
24
|
+
rd.template = 'direct'
|
23
25
|
rd.rdoc_files.include("README.rdoc","lib/**/*.rb","bin/**/*")
|
24
|
-
rd.title = 'Test
|
25
|
-
rd.markup =
|
26
|
+
rd.title = 'Clean Test - make your Test::Unit test cases clean and readable'
|
27
|
+
rd.markup = 'tomdoc'
|
28
|
+
end
|
29
|
+
CLOBBER << 'html'
|
30
|
+
|
31
|
+
FONT_FIX = {
|
32
|
+
"0.82em" => "16px",
|
33
|
+
"0.833em" => "16px",
|
34
|
+
"0.85em" => "16px",
|
35
|
+
"1.15em" => "20px",
|
36
|
+
"1.1em" => "20px",
|
37
|
+
"1.2em" => "20px",
|
38
|
+
"1.4em" => "24px",
|
39
|
+
"1.5em" => "24px",
|
40
|
+
"1.6em" => "32px",
|
41
|
+
"1em" => "16px",
|
42
|
+
"2.1em" => "38px",
|
43
|
+
}
|
44
|
+
|
45
|
+
|
46
|
+
task :hack_css do
|
47
|
+
maincss = File.open('html/css/main.css').readlines
|
48
|
+
File.open('html/css/main.css','w') do |file|
|
49
|
+
file.puts '@import url(https://fonts.googleapis.com/css?family=Lato:300italic,700italic,300,700);'
|
50
|
+
maincss.each do |line|
|
51
|
+
if line.strip == 'font-family: "Helvetica Neue", Arial, sans-serif;'
|
52
|
+
file.puts 'font-family: Lato, "Helvetica Neue", Arial, sans-serif;'
|
53
|
+
elsif line.strip == 'font-family: monospace;'
|
54
|
+
file.puts 'font-family: Monaco, monospace;'
|
55
|
+
elsif line =~ /^pre\s*$/
|
56
|
+
file.puts "pre {
|
57
|
+
font-family: Monaco, monospace;
|
58
|
+
margin-bottom: 1em;
|
59
|
+
}
|
60
|
+
pre.original"
|
61
|
+
elsif line =~ /^\s*font-size:\s*(.*)\s*;/
|
62
|
+
if FONT_FIX[$1]
|
63
|
+
file.puts "font-size: #{FONT_FIX[$1]};"
|
64
|
+
else
|
65
|
+
file.puts line.chomp
|
66
|
+
end
|
67
|
+
else
|
68
|
+
file.puts line.chomp
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
26
72
|
end
|
27
73
|
CLOBBER << 'coverage'
|
28
74
|
|
data/clean_test.gemspec
CHANGED
data/lib/clean_test/any.rb
CHANGED
@@ -3,14 +3,9 @@ require 'faker'
|
|
3
3
|
module Clean #:nodoc:
|
4
4
|
module Test #:nodoc:
|
5
5
|
# Public: Provides the ability to vend arbitrary values without using literals, or
|
6
|
-
# long calls to Faker. This
|
7
|
-
#
|
8
|
-
#
|
9
|
-
# to make it clear what numbers, ints, and strings in your tests are
|
10
|
-
# relevant. Arbitrary values should use one of these any_ helpers.
|
11
|
-
#
|
12
|
-
# any sort of any - you can define your own "any" values by using #new_any, which allows you to
|
13
|
-
# extend things if you like. Of course, you could just make your own any_method as well.
|
6
|
+
# long calls to Faker. This produced random values, so you must be sure that your code truly
|
7
|
+
# should work with any value. The random seed used will be output, and you can use
|
8
|
+
# the environment variable +RANDOM_SEED+ to recreate the conditions of a particular test.
|
14
9
|
#
|
15
10
|
# Example:
|
16
11
|
#
|
@@ -46,6 +41,16 @@ module Clean #:nodoc:
|
|
46
41
|
# }
|
47
42
|
# }
|
48
43
|
module Any
|
44
|
+
def self.included(k)
|
45
|
+
seed = if ENV['RANDOM_SEED']
|
46
|
+
ENV['RANDOM_SEED'].to_i
|
47
|
+
else
|
48
|
+
srand() # generate random seed
|
49
|
+
seed = srand() # save it (but we've now generated another one)
|
50
|
+
end
|
51
|
+
srand(seed) # set it explicitly
|
52
|
+
puts "Random seed was #{seed}; re-use it via environment variable RANDOM_SEED"
|
53
|
+
end
|
49
54
|
MAX_RAND = 50000 #:nodoc:
|
50
55
|
|
51
56
|
# Public: Get any number; one that doesn't matter
|
@@ -54,12 +59,19 @@ module Clean #:nodoc:
|
|
54
59
|
# :positive - make sure that the number is greater than zero
|
55
60
|
# :negative - make sure that the number is less than zero
|
56
61
|
def any_number(*options)
|
57
|
-
|
62
|
+
number = (rand(2 * MAX_RAND) - MAX_RAND).to_f/100.0
|
63
|
+
if options.include? :positive
|
64
|
+
number + MAX_RAND
|
65
|
+
elsif options.include? :negative
|
66
|
+
number - MAX_RAND
|
67
|
+
else
|
68
|
+
number
|
69
|
+
end
|
58
70
|
end
|
59
71
|
|
60
72
|
# Public: Returns an integer. options is the same as for #any_number
|
61
73
|
def any_int(*options)
|
62
|
-
|
74
|
+
any_number(*options).to_i
|
63
75
|
end
|
64
76
|
|
65
77
|
# Public: Get an arbitrary string of any potential positive length
|
@@ -74,77 +86,6 @@ module Clean #:nodoc:
|
|
74
86
|
# any_string :min => 1024 # at least 1024 characters
|
75
87
|
#
|
76
88
|
def any_string(options = {})
|
77
|
-
any :string,options
|
78
|
-
end
|
79
|
-
|
80
|
-
# Public: Get an arbitrary symbol, for example to use as a Hash key. The symbol
|
81
|
-
# will be between 2 and 20 characters long. If you need super-long symbols for some reason,
|
82
|
-
# use <code>any_string.to_sym</code>.
|
83
|
-
def any_symbol
|
84
|
-
(any_string :min => 2, :max => 20).to_sym
|
85
|
-
end
|
86
|
-
|
87
|
-
# Public: Get an arbitrary sentence of arbitrary words of any potential length. Currently,
|
88
|
-
# this returns a sentence between 10 and 21 words, though you can control that with options
|
89
|
-
#
|
90
|
-
# options - options to control the returned sentence
|
91
|
-
# :max - the maximum number of words you want returned
|
92
|
-
# :min - the minimum number of words you want returned; the sentence will be between
|
93
|
-
# :min and (:min + 10) words
|
94
|
-
#
|
95
|
-
# Example
|
96
|
-
#
|
97
|
-
# any_sentence :min => 20 # at least a 20-word sentence
|
98
|
-
# any_sentence :max => 4 # no more than four words
|
99
|
-
#
|
100
|
-
def any_sentence(options = {})
|
101
|
-
any :sentence,options
|
102
|
-
end
|
103
|
-
|
104
|
-
# Public: Get a predefined, arbitrary any.
|
105
|
-
#
|
106
|
-
# sym - the any that has been defined already. By default, the following are defined:
|
107
|
-
# :string - does any_string
|
108
|
-
# String - does any_string
|
109
|
-
# :number - does any_number
|
110
|
-
# Numeric - does any_number
|
111
|
-
# Float - does any_number
|
112
|
-
# :int - does any_int
|
113
|
-
# Fixnum - does any_int
|
114
|
-
# Integer - does any_int
|
115
|
-
# options - whatever options are relevant to the user-defined any
|
116
|
-
#
|
117
|
-
# Example
|
118
|
-
#
|
119
|
-
# new_any(:foo) do |options|
|
120
|
-
# if options[:bar]
|
121
|
-
# 'bar'
|
122
|
-
# else
|
123
|
-
# 'quux'
|
124
|
-
# end
|
125
|
-
# end
|
126
|
-
#
|
127
|
-
# some_foo = any :foo
|
128
|
-
# some_other_foo = any :foo, :bar => true
|
129
|
-
def any(sym,options = {})
|
130
|
-
anies[sym].call(options)
|
131
|
-
end
|
132
|
-
|
133
|
-
# Public: Create a new any that can be retrieved via #any
|
134
|
-
#
|
135
|
-
# any - the identifer of your new any. Can be anything though a Symbol or classname would be appropriate
|
136
|
-
# block - the block that will be called whenever you #any your any.
|
137
|
-
def new_any(any,&block)
|
138
|
-
anies[any] = block
|
139
|
-
end
|
140
|
-
|
141
|
-
private
|
142
|
-
|
143
|
-
def anies
|
144
|
-
@anies ||= default_anies
|
145
|
-
end
|
146
|
-
|
147
|
-
ANY_STRING = Proc.new do |options| #:nodoc:
|
148
89
|
if options[:min] && options[:max]
|
149
90
|
raise ":min must be less than :max" if options[:min] > options[:max]
|
150
91
|
end
|
@@ -156,8 +97,8 @@ module Clean #:nodoc:
|
|
156
97
|
max_size = options[:max]
|
157
98
|
|
158
99
|
if min_size.nil? && max_size.nil?
|
159
|
-
min_size = rand(
|
160
|
-
max_size = min_size + rand(
|
100
|
+
min_size = rand(80) + 1
|
101
|
+
max_size = min_size + rand(80)
|
161
102
|
elsif min_size.nil?
|
162
103
|
min_size = max_size - rand(max_size)
|
163
104
|
min_size = 1 if min_size < 1
|
@@ -165,26 +106,35 @@ module Clean #:nodoc:
|
|
165
106
|
max_size = min_size + rand(min_size) + 1
|
166
107
|
end
|
167
108
|
|
168
|
-
string = Faker::Lorem.words(1).join('')
|
109
|
+
string = Faker::Lorem.words(1).join(' ')
|
169
110
|
while string.length < min_size
|
170
|
-
string += Faker::Lorem.words(1).join('')
|
111
|
+
string += Faker::Lorem.words(1).join(' ')
|
171
112
|
end
|
172
113
|
|
173
114
|
string[0..(max_size-1)]
|
174
115
|
end
|
175
116
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
number - MAX_RAND
|
182
|
-
else
|
183
|
-
number
|
184
|
-
end
|
117
|
+
# Public: Get an arbitrary symbol, for example to use as a Hash key. The symbol
|
118
|
+
# will be between 2 and 20 characters long. If you need super-long symbols for some reason,
|
119
|
+
# use <code>any_string.to_sym</code>.
|
120
|
+
def any_symbol
|
121
|
+
(any_string :min => 2, :max => 20).to_sym
|
185
122
|
end
|
186
123
|
|
187
|
-
|
124
|
+
# Public: Get an arbitrary sentence of arbitrary words of any potential length. Currently,
|
125
|
+
# this returns a sentence between 10 and 21 words, though you can control that with options
|
126
|
+
#
|
127
|
+
# options - options to control the returned sentence
|
128
|
+
# :max - the maximum number of words you want returned
|
129
|
+
# :min - the minimum number of words you want returned; the sentence will be between
|
130
|
+
# :min and (:min + 10) words
|
131
|
+
#
|
132
|
+
# Example
|
133
|
+
#
|
134
|
+
# any_sentence :min => 20 # at least a 20-word sentence
|
135
|
+
# any_sentence :max => 4 # no more than four words
|
136
|
+
#
|
137
|
+
def any_sentence(options = {})
|
188
138
|
min = 11
|
189
139
|
max = 21
|
190
140
|
|
@@ -198,23 +148,6 @@ module Clean #:nodoc:
|
|
198
148
|
|
199
149
|
Faker::Lorem.words(rand(max - min) + min).join(' ')
|
200
150
|
end
|
201
|
-
|
202
|
-
ANY_INT = Proc.new do |options| #:nodoc:
|
203
|
-
(ANY_NUMBER.call(options)).to_i
|
204
|
-
end
|
205
|
-
|
206
|
-
def default_anies
|
207
|
-
{ :string => ANY_STRING,
|
208
|
-
String => ANY_STRING,
|
209
|
-
:number => ANY_NUMBER,
|
210
|
-
Numeric => ANY_NUMBER,
|
211
|
-
Float => ANY_NUMBER,
|
212
|
-
:int => ANY_INT,
|
213
|
-
Fixnum => ANY_INT,
|
214
|
-
Integer => ANY_INT,
|
215
|
-
:sentence => ANY_SENTENCE,
|
216
|
-
}
|
217
|
-
end
|
218
151
|
end
|
219
152
|
end
|
220
153
|
end
|
@@ -21,117 +21,98 @@ module Clean #:nodoc:
|
|
21
21
|
# #mocks_shouldve_been_called to assist with creating readable tests that use mocks. See those
|
22
22
|
# methods for an example
|
23
23
|
module GivenWhenThen
|
24
|
-
# Public:
|
24
|
+
# Public: Declare a step in your test, based on the following conventions:
|
25
25
|
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
26
|
+
# Given - This sets up conditions for the test
|
27
|
+
# When - This executes the code under test
|
28
|
+
# Then - This asserts that that the code under test worked correctly
|
29
|
+
# And - Extend a Given/When/Then when using lambda/method form (see below)
|
30
|
+
# But - Extend a Given/When/Then when using lambda/method form (see below)
|
30
31
|
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
# Given {
|
34
|
-
# @foo = "bar"
|
35
|
-
# }
|
32
|
+
# There are three forms for calling this method, in order of preference:
|
36
33
|
#
|
37
|
-
#
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
#
|
42
|
-
#
|
43
|
-
#
|
44
|
-
#
|
45
|
-
#
|
46
|
-
# by this When. If existing_block is non-nil, this is ignored
|
47
|
-
#
|
48
|
-
# Examples
|
49
|
-
#
|
50
|
-
# When {
|
51
|
-
# @foo.go
|
52
|
-
# }
|
34
|
+
# block - in this form, you pass a block that contains the test code. This should be preferred as it
|
35
|
+
# keeps your test code in your test
|
36
|
+
# method - in this form, you pass a symbol that is the name of a method in your test class. This method
|
37
|
+
# should set up or perform or assert whatever is needed. This can be useful to re-use test helper
|
38
|
+
# methods in an expedient fashion. In this case, you can pass parameters by simply listing
|
39
|
+
# them after the symbol. See the example.
|
40
|
+
# lambda - in this form, you declare a method that returns a lambda and that is used as the
|
41
|
+
# block for this step of the test. This is least desirable, as it requires methods to return
|
42
|
+
# lambdas, which is an extra bit of indirection that adds noise.
|
53
43
|
#
|
54
|
-
#
|
55
|
-
def When(existing_block=nil,&block)
|
56
|
-
Given(existing_block,&block)
|
57
|
-
end
|
58
|
-
|
59
|
-
# Public: Verify the results of the test
|
44
|
+
# Parameters:
|
60
45
|
#
|
61
46
|
# existing_block - a callable object (e.g. a Proc) that will be called immediately
|
62
|
-
# by this
|
47
|
+
# by this Given. If this is a Symbol, a method in the current scope will be converted into
|
48
|
+
# a block and used. If nil, &block is expected to be passed
|
49
|
+
# other_args - a list of arguments to be passed to the block. This is mostly useful when using method form.
|
63
50
|
# block - a block given to this call that will be executed immediately
|
64
|
-
# by this
|
51
|
+
# by this Given. If existing_block is non-nil, this is ignored
|
65
52
|
#
|
66
53
|
# Examples
|
67
54
|
#
|
68
|
-
#
|
69
|
-
#
|
55
|
+
# # block form
|
56
|
+
# Given {
|
57
|
+
# @foo = "bar"
|
70
58
|
# }
|
71
59
|
#
|
72
|
-
#
|
73
|
-
def
|
74
|
-
|
75
|
-
end
|
76
|
-
|
77
|
-
# Public: Continue the previous Given/When/Then in a new block. The reason
|
78
|
-
# you might do this is if you wanted to use the existing block form of a
|
79
|
-
# Given/When/Then, but also need to do something custom. This allows you to
|
80
|
-
# write your test more fluently.
|
81
|
-
#
|
82
|
-
# existing_block - a callable object (e.g. a Proc) that will be called immediately
|
83
|
-
# by this Then. If nil, &block is expected to be passed
|
84
|
-
# block - a block given to this call that will be executed immediately
|
85
|
-
# by this Then. If existing_block is non-nil, this is ignored
|
86
|
-
#
|
87
|
-
# Examples
|
88
|
-
#
|
89
|
-
# def circle(radius)
|
90
|
-
# lambda { @circle = Circle.new(radius) }
|
60
|
+
# # method form
|
61
|
+
# def assert_valid_person
|
62
|
+
# assert @person.valid?,"Person invalid: #{@person.errors.full_messages}"
|
91
63
|
# end
|
92
64
|
#
|
93
|
-
# Given
|
94
|
-
#
|
95
|
-
# @another_circle = Circle.new(30)
|
65
|
+
# Given {
|
66
|
+
# @person = Person.new(:last_name => 'Copeland', :first_name => 'Dave')
|
96
67
|
# }
|
68
|
+
# Then :assert_valid_person
|
97
69
|
#
|
98
|
-
#
|
99
|
-
def
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
# Public: Continue the previous Given/When/Then in a new block. The reason
|
104
|
-
# you might do this is if you wanted to use the existing block form of a
|
105
|
-
# Given/When/Then, but also need to do something custom, and that custom thing
|
106
|
-
# contradicts or overrides the flow, so an "And" wouldn't read properly. This allows you to
|
107
|
-
# write your test more fluently.
|
70
|
+
# # method form with arguments
|
71
|
+
# def assert_invalid_person(error_field)
|
72
|
+
# assert !@person.valid?
|
73
|
+
# assert @person.errors[error_field].present?
|
74
|
+
# end
|
108
75
|
#
|
109
|
-
#
|
110
|
-
#
|
111
|
-
#
|
112
|
-
#
|
76
|
+
# Given {
|
77
|
+
# @person = Person.new(:last_name => 'Copeland')
|
78
|
+
# }
|
79
|
+
# Then :assert_invalid_person,:first_name
|
113
80
|
#
|
114
|
-
#
|
115
|
-
#
|
116
|
-
#
|
117
|
-
#
|
118
|
-
# @options = {
|
119
|
-
# :foo => 'bar',
|
120
|
-
# :quux => 'baz',
|
121
|
-
# }
|
81
|
+
# # lambda form
|
82
|
+
# def assert_valid_person
|
83
|
+
# lambda {
|
84
|
+
# assert @person.valid?,"Person invalid: #{@person.errors.full_messages}"
|
122
85
|
# }
|
123
86
|
# end
|
124
87
|
#
|
125
|
-
# Given
|
126
|
-
#
|
127
|
-
# @options[:foo] = 'baz'
|
88
|
+
# Given {
|
89
|
+
# @person = Person.new(:last_name => 'Copeland', :first_name => 'Dave')
|
128
90
|
# }
|
91
|
+
# Then assert_valid_person
|
129
92
|
#
|
130
93
|
# Returns the block that was executed
|
131
|
-
def
|
132
|
-
|
94
|
+
def Given(existing_block=nil,*other_args,&block)
|
95
|
+
if existing_block.nil?
|
96
|
+
block.call(*other_args)
|
97
|
+
block
|
98
|
+
else
|
99
|
+
if existing_block.kind_of?(Symbol)
|
100
|
+
existing_block = method(existing_block)
|
101
|
+
end
|
102
|
+
existing_block.call(*other_args)
|
103
|
+
existing_block
|
104
|
+
end
|
133
105
|
end
|
134
106
|
|
107
|
+
# Public: Execute the code under test. Behavior identical to Given
|
108
|
+
alias :When :Given
|
109
|
+
# Public: Assert the results of the test. Behavior identical to Given
|
110
|
+
alias :Then :Given
|
111
|
+
# Public: Extend a Given/When/Then when using method or lambda form. Behavior identical to Given
|
112
|
+
alias :And :Given
|
113
|
+
# Public: Extend a Given/When/Then when using method or lambda form. Behavior identical to Given
|
114
|
+
alias :But :Given
|
115
|
+
|
135
116
|
# Public: Used to make clear the structure of tests using mocks.
|
136
117
|
# This returns a no-op, and is intended to be used with a "When"
|
137
118
|
# to delineate the creation of a mock in a Given, and the
|
@@ -165,22 +146,11 @@ module Clean #:nodoc:
|
|
165
146
|
# frameworks do not require an explicit "verify" step, you often have tests
|
166
147
|
# that have no explicit asserts, the assertions being simply that the mocks were called
|
167
148
|
# as expected. This step, which is a no-op, allows you to document that you are
|
168
|
-
# expecting mocks to be called
|
149
|
+
# expecting mocks to be called (rather than forgot to assert anything).
|
150
|
+
# See the example in #mocks_are_called for usage.
|
169
151
|
def mocks_shouldve_been_called
|
170
152
|
lambda {}
|
171
153
|
end
|
172
|
-
|
173
|
-
private
|
174
|
-
|
175
|
-
def call_block_param_or_block_given(existing_block,&block)
|
176
|
-
if existing_block.nil?
|
177
|
-
block.call
|
178
|
-
block
|
179
|
-
else
|
180
|
-
existing_block.call
|
181
|
-
existing_block
|
182
|
-
end
|
183
|
-
end
|
184
154
|
end
|
185
155
|
end
|
186
156
|
end
|
data/lib/clean_test/version.rb
CHANGED
data/test/test_any.rb
CHANGED
@@ -106,38 +106,6 @@ class TestAny < Clean::Test::TestCase
|
|
106
106
|
}
|
107
107
|
|
108
108
|
|
109
|
-
test_that "we can register custom anys" do
|
110
|
-
Given {
|
111
|
-
new_any :foo do
|
112
|
-
"bar"
|
113
|
-
end
|
114
|
-
}
|
115
|
-
When {
|
116
|
-
@result = any :foo
|
117
|
-
}
|
118
|
-
Then {
|
119
|
-
assert_equal 'bar',@result
|
120
|
-
}
|
121
|
-
end
|
122
|
-
|
123
|
-
test_that "custom anys can take options" do
|
124
|
-
Given {
|
125
|
-
new_any :foo do |options|
|
126
|
-
if options[:baaz]
|
127
|
-
'quux'
|
128
|
-
else
|
129
|
-
'bar'
|
130
|
-
end
|
131
|
-
end
|
132
|
-
}
|
133
|
-
When {
|
134
|
-
@result = any :foo, :baaz => true
|
135
|
-
}
|
136
|
-
Then {
|
137
|
-
assert_equal 'quux',@result
|
138
|
-
}
|
139
|
-
end
|
140
|
-
|
141
109
|
test_that "any_symbol works" do
|
142
110
|
When {
|
143
111
|
@symbol = any_symbol
|
@@ -148,23 +116,4 @@ class TestAny < Clean::Test::TestCase
|
|
148
116
|
assert @symbol.to_s.length < 20
|
149
117
|
}
|
150
118
|
end
|
151
|
-
|
152
|
-
[String,[Integer,Fixnum],Fixnum,Float,[Numeric,Float]].each do |klass|
|
153
|
-
test_that "can get an any #{klass}" do
|
154
|
-
Given {
|
155
|
-
@class = @expected_class = klass
|
156
|
-
if @class.kind_of? Array
|
157
|
-
@expected_class = @class[1]
|
158
|
-
@class = @class[0]
|
159
|
-
end
|
160
|
-
}
|
161
|
-
When {
|
162
|
-
@value = any @class
|
163
|
-
}
|
164
|
-
Then {
|
165
|
-
assert_not_nil @value
|
166
|
-
assert_equal @expected_class,@value.class
|
167
|
-
}
|
168
|
-
end
|
169
|
-
end
|
170
119
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
require 'clean_test/test_case'
|
3
3
|
|
4
|
-
class
|
4
|
+
class TestGivenWhenThen < Clean::Test::TestCase
|
5
5
|
|
6
6
|
def test_basics
|
7
7
|
Given {
|
@@ -84,6 +84,20 @@ class TestSimpleGiven < Clean::Test::TestCase
|
|
84
84
|
}
|
85
85
|
end
|
86
86
|
|
87
|
+
def test_can_use_symbols_for_methods
|
88
|
+
Given :a_string
|
89
|
+
Then {
|
90
|
+
assert_equal "foo",@string
|
91
|
+
}
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_can_pass_params_to_symbols
|
95
|
+
Given :a_string, 4
|
96
|
+
Then {
|
97
|
+
assert_equal 4,@string.length
|
98
|
+
}
|
99
|
+
end
|
100
|
+
|
87
101
|
def test_invert_for_block_based_asserts
|
88
102
|
Given a_nil_x
|
89
103
|
Then {
|
@@ -97,6 +111,14 @@ class TestSimpleGiven < Clean::Test::TestCase
|
|
97
111
|
|
98
112
|
private
|
99
113
|
|
114
|
+
def a_string(length=3)
|
115
|
+
if length == 3
|
116
|
+
@string = "foo"
|
117
|
+
else
|
118
|
+
@string = "quux"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
100
122
|
def a_nil_x
|
101
123
|
Proc.new { @x = nil }
|
102
124
|
end
|
metadata
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: clean_test
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 1.0.0.rc1
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- David Copeland
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-06-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: faker
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,15 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: rdoc
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ! '>='
|
@@ -32,10 +37,31 @@ dependencies:
|
|
32
37
|
version: '0'
|
33
38
|
type: :development
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: sdoc
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
36
62
|
- !ruby/object:Gem::Dependency
|
37
63
|
name: rake
|
38
|
-
requirement:
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
39
65
|
none: false
|
40
66
|
requirements:
|
41
67
|
- - ! '>='
|
@@ -43,10 +69,15 @@ dependencies:
|
|
43
69
|
version: '0'
|
44
70
|
type: :development
|
45
71
|
prerelease: false
|
46
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
47
78
|
- !ruby/object:Gem::Dependency
|
48
79
|
name: simplecov
|
49
|
-
requirement:
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
50
81
|
none: false
|
51
82
|
requirements:
|
52
83
|
- - ! '>='
|
@@ -54,7 +85,12 @@ dependencies:
|
|
54
85
|
version: '0'
|
55
86
|
type: :development
|
56
87
|
prerelease: false
|
57
|
-
version_requirements:
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
58
94
|
description: You can easily make your plain Ruby Test::Unit test cases clean and clear
|
59
95
|
with Given/When/Then, placeholder values, and textual descriptions without resorting
|
60
96
|
to metaprogramming or complex frameworks. Use as much or as little as you like
|
@@ -64,24 +100,42 @@ executables: []
|
|
64
100
|
extensions: []
|
65
101
|
extra_rdoc_files: []
|
66
102
|
files:
|
67
|
-
-
|
68
|
-
|
69
|
-
-
|
70
|
-
|
71
|
-
-
|
72
|
-
|
73
|
-
-
|
74
|
-
|
75
|
-
-
|
76
|
-
|
77
|
-
-
|
78
|
-
|
79
|
-
-
|
80
|
-
|
81
|
-
-
|
82
|
-
|
83
|
-
-
|
84
|
-
|
103
|
+
- !binary |-
|
104
|
+
LmdpdGlnbm9yZQ==
|
105
|
+
- !binary |-
|
106
|
+
LnJ2bXJj
|
107
|
+
- !binary |-
|
108
|
+
LnRyYXZpcy55bWw=
|
109
|
+
- !binary |-
|
110
|
+
R2VtZmlsZQ==
|
111
|
+
- !binary |-
|
112
|
+
TElDRU5TRS50eHQ=
|
113
|
+
- !binary |-
|
114
|
+
UkVBRE1FLnJkb2M=
|
115
|
+
- !binary |-
|
116
|
+
UmFrZWZpbGU=
|
117
|
+
- !binary |-
|
118
|
+
Y2xlYW5fdGVzdC5nZW1zcGVj
|
119
|
+
- !binary |-
|
120
|
+
bGliL2NsZWFuX3Rlc3QvYW55LnJi
|
121
|
+
- !binary |-
|
122
|
+
bGliL2NsZWFuX3Rlc3QvZ2l2ZW5fd2hlbl90aGVuLnJi
|
123
|
+
- !binary |-
|
124
|
+
bGliL2NsZWFuX3Rlc3QvdGVzdF9jYXNlLnJi
|
125
|
+
- !binary |-
|
126
|
+
bGliL2NsZWFuX3Rlc3QvdGVzdF90aGF0LnJi
|
127
|
+
- !binary |-
|
128
|
+
bGliL2NsZWFuX3Rlc3QvdmVyc2lvbi5yYg==
|
129
|
+
- !binary |-
|
130
|
+
dGVzdC9ib290c3RyYXAucmI=
|
131
|
+
- !binary |-
|
132
|
+
dGVzdC90ZXN0X2FueS5yYg==
|
133
|
+
- !binary |-
|
134
|
+
dGVzdC90ZXN0X2NpcmNsZS5yYg==
|
135
|
+
- !binary |-
|
136
|
+
dGVzdC90ZXN0X2dpdmVuX3doZW5fdGhlbi5yYg==
|
137
|
+
- !binary |-
|
138
|
+
dGVzdC90ZXN0X3Rlc3RfdGhhdC5yYg==
|
85
139
|
homepage: ''
|
86
140
|
licenses: []
|
87
141
|
post_install_message:
|
@@ -94,21 +148,29 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
94
148
|
- - ! '>='
|
95
149
|
- !ruby/object:Gem::Version
|
96
150
|
version: '0'
|
151
|
+
segments:
|
152
|
+
- 0
|
153
|
+
hash: -2779224397029811565
|
97
154
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
155
|
none: false
|
99
156
|
requirements:
|
100
|
-
- - ! '
|
157
|
+
- - ! '>'
|
101
158
|
- !ruby/object:Gem::Version
|
102
|
-
version:
|
159
|
+
version: 1.3.1
|
103
160
|
requirements: []
|
104
161
|
rubyforge_project: clean_test
|
105
|
-
rubygems_version: 1.8.
|
162
|
+
rubygems_version: 1.8.24
|
106
163
|
signing_key:
|
107
164
|
specification_version: 3
|
108
165
|
summary: Clean up your Test::Unit tests
|
109
166
|
test_files:
|
110
|
-
-
|
111
|
-
|
112
|
-
-
|
113
|
-
|
114
|
-
-
|
167
|
+
- !binary |-
|
168
|
+
dGVzdC9ib290c3RyYXAucmI=
|
169
|
+
- !binary |-
|
170
|
+
dGVzdC90ZXN0X2FueS5yYg==
|
171
|
+
- !binary |-
|
172
|
+
dGVzdC90ZXN0X2NpcmNsZS5yYg==
|
173
|
+
- !binary |-
|
174
|
+
dGVzdC90ZXN0X2dpdmVuX3doZW5fdGhlbi5yYg==
|
175
|
+
- !binary |-
|
176
|
+
dGVzdC90ZXN0X3Rlc3RfdGhhdC5yYg==
|