assert_same 0.3 → 0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README +92 -1
- data/assert_same.gemspec +1 -1
- data/lib/assert_same.rb +66 -21
- data/test/assert_same_test.rb +69 -0
- data/test/logs/assert_same_exception_with_files.log.ref +1 -0
- metadata +5 -2
data/README
CHANGED
@@ -1,10 +1,101 @@
|
|
1
1
|
assert_same
|
2
2
|
===========
|
3
3
|
|
4
|
-
|
4
|
+
Checks that two strings are same and "magically" replace expected value
|
5
|
+
with the actual in case the new behavior (and new actual value) is correct.
|
6
|
+
Support two kind of arguments: string and code block.
|
7
|
+
|
8
|
+
String Example:
|
9
|
+
---------------
|
10
|
+
|
11
|
+
It is better to start with no expected value
|
12
|
+
|
13
|
+
assert_same "foo"
|
14
|
+
|
15
|
+
Then run tests as usual with "rake test". As a result you will see
|
16
|
+
diff between expected and actual values:
|
17
|
+
|
18
|
+
Failure:
|
19
|
+
@@ -1,0, +1,1 @@
|
20
|
+
+foo
|
21
|
+
Accept the new value: yes to all, no to all, yes, no? [Y/N/y/n] (y):
|
22
|
+
|
23
|
+
If you accept the new value your test will be automatically modified to
|
24
|
+
|
25
|
+
assert_same "foo", <<-END
|
26
|
+
foo
|
27
|
+
END
|
28
|
+
|
29
|
+
Block Example:
|
30
|
+
--------------
|
31
|
+
|
32
|
+
assert_same supports code block as argument. If executed block raise exception
|
33
|
+
exception message is returned as actual value:
|
34
|
+
|
35
|
+
assert_same do
|
36
|
+
nil+1
|
37
|
+
end
|
38
|
+
|
39
|
+
Run tests
|
40
|
+
|
41
|
+
Failure:
|
42
|
+
@@ -1,0, +1,1 @@
|
43
|
+
+Exception NoMethodError: undefined method `+' for nil:NilClass
|
44
|
+
Accept the new value: yes to all, no to all, yes, no? [Y/N/y/n] (y):
|
45
|
+
|
46
|
+
After new value is accepted
|
47
|
+
|
48
|
+
assert_same(<<-END) do
|
49
|
+
Exception NoMethodError: undefined method `+' for nil:NilClass
|
50
|
+
END
|
51
|
+
nil + 1
|
52
|
+
end
|
53
|
+
|
54
|
+
Options:
|
55
|
+
--------
|
56
|
+
|
57
|
+
--no-interactive skips all questions and just reports failures
|
58
|
+
--autoaccept prints diffs and automatically accepts all new actual values
|
59
|
+
--no-canonicalize turns off expected and actual value canonicalization (see below for details)
|
60
|
+
|
61
|
+
Additional options can be passed during both single test file run and rake test run:
|
62
|
+
|
63
|
+
In Ruby 1.8:
|
64
|
+
|
65
|
+
ruby test/unit/foo_test.rb -- --autoaccept
|
66
|
+
rake test TESTOPTS="-- --autoaccept"
|
67
|
+
|
68
|
+
In Ruby 1.9:
|
69
|
+
|
70
|
+
ruby test/unit/foo_test.rb --autoaccept
|
71
|
+
rake test TESTOPTS="--autoaccept"
|
72
|
+
|
73
|
+
Canonicalization:
|
74
|
+
-----------------
|
75
|
+
|
76
|
+
Before comparing expected and actual strings, assert_same canonicalizes both using these rules:
|
77
|
+
|
78
|
+
- indentation is ignored (except for indentation relative to the first line of the expected/actual string)
|
79
|
+
- ruby-style comments after "#" are ignored
|
80
|
+
- empty lines are ignored
|
81
|
+
- trailing whitespaces are ignored
|
82
|
+
|
83
|
+
You can turn canonicalization off with --no-canonicalize option. This is useful
|
84
|
+
when you need to regenerate expected test strings.
|
85
|
+
To regenerate the whole test suite, run:
|
86
|
+
|
87
|
+
In Ruby 1.8:
|
88
|
+
|
89
|
+
rake test TESTOPTS="-- --no-canonicalize --autoaccept"
|
90
|
+
|
91
|
+
In Ruby 1.9:
|
92
|
+
|
93
|
+
rake test TESTOPTS="--no-canonicalize --autoaccept"
|
5
94
|
|
6
95
|
|
7
96
|
Changelog
|
97
|
+
---------
|
98
|
+
- 0.4: Added support for code blocks as argument
|
8
99
|
- 0.3: Ruby 1.9 is supported
|
9
100
|
- 0.2: Make assert_same useful as a standalone gem. Bugfixes
|
10
101
|
- 0.1: Initial release
|
data/assert_same.gemspec
CHANGED
data/lib/assert_same.rb
CHANGED
@@ -49,6 +49,15 @@ else
|
|
49
49
|
end
|
50
50
|
|
51
51
|
|
52
|
+
#Use this to raise internal error with a given message
|
53
|
+
#You can define your own method for your application
|
54
|
+
unless defined? internal_error
|
55
|
+
def internal_error(message = 'internal error')
|
56
|
+
raise message
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
|
52
61
|
module Test::Unit::Assertions
|
53
62
|
|
54
63
|
#Hash[filename][line_number] = offset
|
@@ -68,6 +77,14 @@ module Test::Unit::Assertions
|
|
68
77
|
# bar
|
69
78
|
# zee
|
70
79
|
# END
|
80
|
+
#
|
81
|
+
# You can also use assert_same for blocks. Then you can assert block result or raised exception
|
82
|
+
# assert_same(<<-END) do
|
83
|
+
# Exception NoMethodError: undefined method `+' for nil:NilClass
|
84
|
+
# END
|
85
|
+
# # Code block starts here
|
86
|
+
# c = nil + 1
|
87
|
+
# end
|
71
88
|
#
|
72
89
|
# Then run tests as usual:
|
73
90
|
# rake test:units
|
@@ -150,16 +167,29 @@ module Test::Unit::Assertions
|
|
150
167
|
# assert_same something
|
151
168
|
# in fact, this is the preferred way to create assert_same tests - you write empty
|
152
169
|
# assert_same, run tests and they will fill expected values for you automatically
|
153
|
-
def assert_same(
|
154
|
-
if
|
155
|
-
|
156
|
-
|
157
|
-
|
170
|
+
def assert_same(*args)
|
171
|
+
if block_given?
|
172
|
+
mode = :block
|
173
|
+
expected = args[0]
|
174
|
+
actual = ""
|
175
|
+
begin
|
176
|
+
actual = yield.to_s
|
177
|
+
rescue Exception => e
|
178
|
+
actual = "Exception #{e.class}: #{e.message}"
|
179
|
+
end
|
180
|
+
else
|
181
|
+
mode = :scalar
|
182
|
+
expected = args[1]
|
183
|
+
actual = args[0]
|
184
|
+
end
|
185
|
+
|
186
|
+
if expected.nil?
|
158
187
|
expected = ""
|
159
|
-
|
188
|
+
change = :create_expected_string
|
189
|
+
elsif expected.class == String
|
190
|
+
change = :update_expected_string
|
160
191
|
elsif expected.class == Hash
|
161
192
|
raise ":log key is missing" unless expected.has_key? :log
|
162
|
-
mode = :expecting_file
|
163
193
|
log_file = expected[:log]
|
164
194
|
if defined? RAILS_ROOT
|
165
195
|
log_file = File.expand_path(log_file, RAILS_ROOT)
|
@@ -167,8 +197,9 @@ module Test::Unit::Assertions
|
|
167
197
|
log_file = File.expand_path(log_file, Dir.pwd)
|
168
198
|
end
|
169
199
|
expected = File.exists?(log_file) ? File.read(log_file) : ""
|
200
|
+
change = :update_file_with_expected_string
|
170
201
|
else
|
171
|
-
internal_error("
|
202
|
+
internal_error("Invalid expected class #{excepted.class}")
|
172
203
|
end
|
173
204
|
|
174
205
|
# interactive mode is turned on by default, except when
|
@@ -198,10 +229,12 @@ module Test::Unit::Assertions
|
|
198
229
|
end
|
199
230
|
|
200
231
|
if accept
|
201
|
-
if [:
|
202
|
-
accept_string(actual, mode)
|
203
|
-
elsif
|
232
|
+
if [:create_expected_string, :update_expected_string].include? change
|
233
|
+
accept_string(actual, change, mode)
|
234
|
+
elsif change == :update_file_with_expected_string
|
204
235
|
accept_file(actual, log_file)
|
236
|
+
else
|
237
|
+
internal_error("Invalid change #{change}")
|
205
238
|
end
|
206
239
|
end
|
207
240
|
end
|
@@ -246,7 +279,10 @@ private
|
|
246
279
|
end
|
247
280
|
end
|
248
281
|
|
249
|
-
|
282
|
+
# actual - actual value of the scalar or result of the executed block
|
283
|
+
# change - what to do with expected value (:create_expected_string or :update_expected_string)
|
284
|
+
# mode - describes signature of assert_same call by type of main argument (:block or :scalar)
|
285
|
+
def accept_string(actual, change, mode)
|
250
286
|
file, method, line = get_caller_location(:depth => 3)
|
251
287
|
|
252
288
|
# read source file, construct the new source, replacing everything
|
@@ -262,11 +298,13 @@ private
|
|
262
298
|
end
|
263
299
|
|
264
300
|
expected_text_end_line = expected_text_start_line = line.to_i + offset
|
265
|
-
|
266
|
-
#
|
267
|
-
#(second arg to assert_same is omitted)
|
268
|
-
#else we search for it
|
301
|
+
if change == :update_expected_string
|
302
|
+
#search for the end of expected value in code
|
269
303
|
expected_text_end_line += 1 while !["END", "EOS"].include?(source[expected_text_end_line].strip)
|
304
|
+
elsif change == :create_expected_string
|
305
|
+
# The is no expected value yet. expected_text_end_line is unknown
|
306
|
+
else
|
307
|
+
internal_error("Invalid change #{change}")
|
270
308
|
end
|
271
309
|
|
272
310
|
expected_length = expected_text_end_line - expected_text_start_line
|
@@ -275,18 +313,25 @@ private
|
|
275
313
|
indentation = source[expected_text_start_line-1] =~ /^(\s+)/ ? $1.length : 0
|
276
314
|
indentation += 4
|
277
315
|
|
278
|
-
if
|
279
|
-
|
280
|
-
|
316
|
+
if change == :create_expected_string
|
317
|
+
if mode == :scalar
|
318
|
+
# add second argument to assert_same if it's omitted
|
319
|
+
source[expected_text_start_line-1] = "#{source[expected_text_start_line-1].chop}, <<-END\n"
|
320
|
+
elsif mode == :block
|
321
|
+
# add expected value as argument to assert_same before block call
|
322
|
+
source[expected_text_start_line-1] = source[expected_text_start_line-1].sub(/assert_same(\(.*?\))*/, "assert_same(<<-END)")
|
323
|
+
else
|
324
|
+
internal_error("Invalid mode #{mode}")
|
325
|
+
end
|
281
326
|
end
|
282
327
|
source = source[0, expected_text_start_line] +
|
283
328
|
actual.split("\n").map { |l| "#{" "*(indentation)}#{l}\n"} +
|
284
|
-
(
|
329
|
+
(change == :create_expected_string ? ["#{" "*(indentation-4)}END\n"] : [])+
|
285
330
|
source[expected_text_end_line, source.length]
|
286
331
|
|
287
332
|
# recalculate line number adjustments
|
288
333
|
actual_length = actual.split("\n").length
|
289
|
-
actual_length += 1 if
|
334
|
+
actual_length += 1 if change == :create_expected_string # END marker after expected value
|
290
335
|
@@file_offsets[file][line.to_i] = actual_length - expected_length
|
291
336
|
|
292
337
|
source_file = File.open(file, "w+")
|
data/test/assert_same_test.rb
CHANGED
@@ -15,4 +15,73 @@ class AssertSameTest < Test::Unit::TestCase
|
|
15
15
|
assert_same "foo", :log => 'test/logs/assert_same_with_files.log.ref'
|
16
16
|
end
|
17
17
|
|
18
|
+
def test_assert_same_empty_string
|
19
|
+
# These two calls are the same
|
20
|
+
assert_same ""
|
21
|
+
assert_same "", <<-END
|
22
|
+
END
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_assert_same_exception
|
26
|
+
assert_same(<<-END) do
|
27
|
+
Exception NoMethodError: undefined method `+' for nil:NilClass
|
28
|
+
END
|
29
|
+
nil + 1
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_assert_same_for_block_value
|
34
|
+
assert_same(<<-END) do
|
35
|
+
All Ok!
|
36
|
+
END
|
37
|
+
a = "All Ok!"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_assert_same_exception_with_files
|
42
|
+
assert_same(:log => 'test/logs/assert_same_exception_with_files.log.ref') do
|
43
|
+
nil + 1
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_assert_same_block_alternative_syntax
|
48
|
+
assert_same(<<-END) {
|
49
|
+
Exception NoMethodError: undefined method `+' for nil:NilClass
|
50
|
+
END
|
51
|
+
nil + 1
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_assert_same_block_alternative_syntax_one_liner
|
56
|
+
assert_same(<<-END) { nil + 1 }
|
57
|
+
Exception NoMethodError: undefined method `+' for nil:NilClass
|
58
|
+
END
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_assert_same_for_empty_block
|
62
|
+
# These calls are the same
|
63
|
+
assert_same { }
|
64
|
+
|
65
|
+
assert_same do end
|
66
|
+
|
67
|
+
assert_same(<<-END) { }
|
68
|
+
END
|
69
|
+
|
70
|
+
assert_same(<<-END) do end
|
71
|
+
END
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_assert_same_for_nil_block_result
|
75
|
+
# These calls are the same
|
76
|
+
assert_same { nil }
|
77
|
+
|
78
|
+
assert_same do nil end
|
79
|
+
|
80
|
+
assert_same(<<-END) { nil }
|
81
|
+
END
|
82
|
+
|
83
|
+
assert_same(<<-END) do nil end
|
84
|
+
END
|
85
|
+
end
|
86
|
+
|
18
87
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Exception NoMethodError: undefined method `+' for nil:NilClass
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: assert_same
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.5'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-08-07 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: assert_same assertion
|
15
15
|
email: support@pluron.com
|
@@ -28,6 +28,7 @@ files:
|
|
28
28
|
- lib/assert_same.rb
|
29
29
|
- lib/text_diff.rb
|
30
30
|
- test/assert_same_test.rb
|
31
|
+
- test/logs/assert_same_exception_with_files.log.ref
|
31
32
|
- test/logs/assert_same_with_files.log.ref
|
32
33
|
homepage: http://github.com/acunote/assert_same
|
33
34
|
licenses: []
|
@@ -57,4 +58,6 @@ summary: Assert which checks that two strings (expected and actual) are same and
|
|
57
58
|
new actual value) is correct
|
58
59
|
test_files:
|
59
60
|
- test/assert_same_test.rb
|
61
|
+
- test/logs/assert_same_exception_with_files.log.ref
|
60
62
|
- test/logs/assert_same_with_files.log.ref
|
63
|
+
has_rdoc: true
|