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 CHANGED
@@ -1,10 +1,101 @@
1
1
  assert_same
2
2
  ===========
3
3
 
4
- Please read the API docs in lib/assert_same.rb
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
@@ -2,7 +2,7 @@ require 'rubygems'
2
2
 
3
3
  SPEC = Gem::Specification.new do |s|
4
4
  s.name = "assert_same"
5
- s.version = "0.3"
5
+ s.version = "0.5"
6
6
  s.author = "Pluron, Inc."
7
7
  s.email = "support@pluron.com"
8
8
  s.homepage = "http://github.com/acunote/assert_same"
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(actual, expected = :autofill_expected_value)
154
- if expected.class == String
155
- expected ||= ""
156
- mode = :expecting_string
157
- elsif expected == :autofill_expected_value
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
- mode = :autofill_expected_value
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("Incorrect expected argument for assert_same. It must be either String or Hash.")
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 [:expecting_string, :autofill_expected_value].include? mode
202
- accept_string(actual, mode)
203
- elsif mode == :expecting_file
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
- def accept_string(actual, mode)
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
- unless mode == :autofill_expected_value
266
- #if we're autofilling the value, END/EOS marker will not exist
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 mode == :autofill_expected_value
279
- # add second argument to assert_same if it's omitted
280
- source[expected_text_start_line-1] = "#{source[expected_text_start_line-1].chop}, <<-END\n"
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
- (mode == :autofill_expected_value ? ["#{" "*(indentation-4)}END\n"] : [])+
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 mode == :autofill_expected_value # END marker after actual value
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+")
@@ -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.3'
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: 2012-11-14 00:00:00.000000000 Z
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