assert 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -9,29 +9,38 @@ module Assert
9
9
  include Assert::Options
10
10
  options do
11
11
  default_capture_output false
12
+ default_halt_on_fail true
13
+ end
14
+
15
+ def self.halt_on_fail?
16
+ ENV['halt_on_fail'] == 'true' || self.options.halt_on_fail
12
17
  end
13
18
 
14
19
  # a Test is some code/method to run in the scope of a Context. After a
15
20
  # a test runs, it should have some assertions which are its results.
16
21
 
17
- attr_reader :name, :code, :context_class
22
+ attr_reader :name, :code, :context_info
18
23
  attr_accessor :results, :output
19
24
 
20
- def initialize(name, context_class, code = nil, &block)
21
- @context_class = context_class
25
+ def initialize(name, suite_context_info, code = nil, &block)
26
+ @context_info = suite_context_info
22
27
  @name = name_from_context(name)
23
28
  @code = (code || block)
24
29
  @results = ResultSet.new
25
30
  @output = ""
26
31
  end
27
32
 
33
+ def context_class
34
+ self.context_info.klass
35
+ end
36
+
28
37
  def run(view=nil)
29
38
  @results.view = view
30
- run_scope = @context_class.new(self)
39
+ run_scope = self.context_class.new(self)
31
40
  capture_output(StringIO.new(@output, "w+")) do
32
41
  begin
33
42
  # run any assert style 'setup do' setups
34
- @context_class.setup(run_scope)
43
+ self.context_class.setup(run_scope)
35
44
  # run any classic test/unit style 'def setup' setups
36
45
  if run_scope.respond_to?(:setup)
37
46
  run_scope.setup
@@ -43,10 +52,12 @@ module Assert
43
52
  elsif run_scope.respond_to?(@code.to_s)
44
53
  run_scope.send(@code.to_s)
45
54
  end
55
+ rescue Result::TestFailure => err
56
+ @results << Result::Fail.new(self, err)
46
57
  rescue Result::TestSkipped => err
47
- @results << Result::Skip.new(self.name, err)
58
+ @results << Result::Skip.new(self, err)
48
59
  rescue Exception => err
49
- @results << Result::Error.new(self.name, err)
60
+ @results << Result::Error.new(self, err)
50
61
  ensure
51
62
  begin
52
63
  # run any classic test/unit style 'def teardown' teardowns
@@ -54,9 +65,9 @@ module Assert
54
65
  run_scope.teardown
55
66
  end
56
67
  # run any assert style 'teardown do' teardowns
57
- @context_class.teardown(run_scope)
68
+ self.context_class.teardown(run_scope)
58
69
  rescue Exception => teardown_err
59
- @results << Result::Error.new(self.name, teardown_err)
70
+ @results << Result::Error.new(self, teardown_err)
60
71
  end
61
72
  end
62
73
  end
@@ -83,7 +94,7 @@ module Assert
83
94
  end
84
95
 
85
96
  def inspect
86
- attributes_string = ([ :name, :context_class, :results ].collect do |attr|
97
+ attributes_string = ([ :name, :context_info, :results ].collect do |attr|
87
98
  "@#{attr}=#{self.send(attr).inspect}"
88
99
  end).join(" ")
89
100
  "#<#{self.class} #{attributes_string}>"
@@ -103,7 +114,7 @@ module Assert
103
114
  end
104
115
 
105
116
  def name_from_context(name)
106
- [ @context_class.description,
117
+ [ self.context_class.description,
107
118
  name.gsub(/^test:\s+should/, "should")
108
119
  ].compact.reject{|p| p.empty?}.join(" ")
109
120
  end
@@ -1,3 +1,3 @@
1
1
  module Assert
2
- VERSION = "0.6.0"
2
+ VERSION = "0.7.0"
3
3
  end
@@ -28,7 +28,7 @@ module Assert::Assertions
28
28
  desc "ignored assertions helpers"
29
29
  setup do
30
30
  @tests = Assert::Assertions::IGNORED_ASSERTION_HELPERS.collect do |helper|
31
- Factory.test("ignored assertion helper #{helper}", @context_class) do
31
+ Factory.test("ignored assertion helper #{helper}", Factory.context_info(@context_class)) do
32
32
  self.send(helper, "doesn't matter")
33
33
  end
34
34
  end
@@ -5,11 +5,14 @@ class Assert::Context
5
5
  class ClassMethodsTest < Assert::Context
6
6
  desc "Assert context class"
7
7
  setup do
8
+ @orig_assert_suite = Assert.suite
9
+ Assert.options.suite TEST_ASSERT_SUITE
8
10
  @test = Factory.test
9
11
  @context_class = @test.context_class
10
12
  end
11
13
  teardown do
12
- TEST_ASSERT_SUITE.clear
14
+ TEST_ASSERT_SUITE.tests.clear
15
+ Assert.options.suite @orig_assert_suite
13
16
  end
14
17
  subject{ @context_class }
15
18
 
@@ -296,19 +299,21 @@ class Assert::Context
296
299
  class TestMethTest < ClassMethodsTest
297
300
  desc "test method"
298
301
  setup do
302
+ @test_count_before = Assert.suite.tests.size
303
+
299
304
  @should_desc = "be true"
300
305
  @should_block = ::Proc.new{ assert(true) }
301
306
  @method_name = "test: #{@should_desc}"
302
307
 
303
308
  d, b = @should_desc, @should_block
304
309
  @context_class = Factory.context_class { test(d, &b) }
305
- @context = @context_class.new(Factory.test("something", @context_class))
310
+ @context = @context_class.new(Factory.test("something", Factory.context_info(@context_class)))
306
311
  end
307
312
  subject{ @context }
308
313
 
309
314
  should "define a test method named after the should desc" do
310
- assert_respond_to @method_name, subject
311
- assert_equal subject.instance_eval(&@should_block), subject.send(@method_name)
315
+ assert_equal @test_count_before+1, Assert.suite.tests.size
316
+ assert_equal @should_block, Assert.suite.tests.last.code
312
317
  end
313
318
 
314
319
  end
@@ -318,13 +323,13 @@ class Assert::Context
318
323
  setup do
319
324
  d = @should_desc
320
325
  @context_class = Factory.context_class { test(d) }
321
- @context = @context_class.new(Factory.test("something", @context_class))
326
+ @context = @context_class.new(Factory.test("something", Factory.context_info(@context_class)))
322
327
  end
323
328
  subject{ @context }
324
329
 
325
330
  should "define a test method named after the should desc that raises a test skipped" do
326
331
  assert_raises(Assert::Result::TestSkipped) do
327
- subject.send(@method_name)
332
+ subject.instance_eval(&Assert.suite.tests.last.code)
328
333
  end
329
334
  end
330
335
 
@@ -337,14 +342,13 @@ class Assert::Context
337
342
  @context_class = Factory.context_class do
338
343
  test_eventually(d, &b)
339
344
  end
340
- @context = @context_class.new(Factory.test("something", @context_class))
345
+ @context = @context_class.new(Factory.test("something", Factory.context_info(@context_class)))
341
346
  end
342
347
  subject{ @context }
343
348
 
344
349
  should "define a test method named after the should desc that raises a test skipped" do
345
- assert_respond_to @method_name, subject
346
350
  assert_raises(Assert::Result::TestSkipped) do
347
- subject.send(@method_name)
351
+ subject.instance_eval(&Assert.suite.tests.last.code)
348
352
  end
349
353
  end
350
354
 
@@ -355,19 +359,21 @@ class Assert::Context
355
359
  class ShouldTest < ClassMethodsTest
356
360
  desc "'should' method"
357
361
  setup do
362
+ @test_count_before = Assert.suite.tests.size
363
+
358
364
  @should_desc = "be true"
359
365
  @should_block = ::Proc.new{ assert(true) }
360
366
  @method_name = "test: should #{@should_desc}"
361
367
 
362
368
  d, b = @should_desc, @should_block
363
369
  @context_class = Factory.context_class { should(d, &b) }
364
- @context = @context_class.new(Factory.test("something", @context_class))
370
+ @context = @context_class.new(Factory.test("something", Factory.context_info(@context_class)))
365
371
  end
366
372
  subject{ @context }
367
373
 
368
374
  should "define a test method named after the should desc" do
369
- assert_respond_to @method_name, subject
370
- assert_equal subject.instance_eval(&@should_block), subject.send(@method_name)
375
+ assert_equal @test_count_before+1, Assert.suite.tests.size
376
+ assert_equal @should_block, Assert.suite.tests.last.code
371
377
  end
372
378
 
373
379
  end
@@ -377,13 +383,13 @@ class Assert::Context
377
383
  setup do
378
384
  d = @should_desc
379
385
  @context_class = Factory.context_class { should(d) }
380
- @context = @context_class.new(Factory.test("something", @context_class))
386
+ @context = @context_class.new(Factory.test("something", Factory.context_info(@context_class)))
381
387
  end
382
388
  subject{ @context }
383
389
 
384
390
  should "define a test method named after the should desc that raises a test skipped" do
385
391
  assert_raises(Assert::Result::TestSkipped) do
386
- subject.send(@method_name)
392
+ subject.instance_eval(&Assert.suite.tests.last.code)
387
393
  end
388
394
  end
389
395
 
@@ -394,14 +400,13 @@ class Assert::Context
394
400
  setup do
395
401
  d, b = @should_desc, @should_block
396
402
  @context_class = Factory.context_class { should_eventually(d, &b) }
397
- @context = @context_class.new(Factory.test("something", @context_class))
403
+ @context = @context_class.new(Factory.test("something", Factory.context_info(@context_class)))
398
404
  end
399
405
  subject{ @context }
400
406
 
401
407
  should "define a test method named after the should desc that raises a test skipped" do
402
- assert_respond_to @method_name, subject
403
408
  assert_raises(Assert::Result::TestSkipped) do
404
- subject.send(@method_name)
409
+ subject.instance_eval(&Assert.suite.tests.last.code)
405
410
  end
406
411
  end
407
412
 
@@ -10,7 +10,7 @@ class Assert::Context
10
10
  @context = @context_class.new(@test)
11
11
  end
12
12
  teardown do
13
- TEST_ASSERT_SUITE.clear
13
+ TEST_ASSERT_SUITE.tests.clear
14
14
  end
15
15
  subject{ @context }
16
16
 
@@ -18,6 +18,11 @@ class Assert::Context
18
18
  should have_instance_methods :skip, :pass, :fail, :flunk, :ignore
19
19
  should have_instance_methods :subject
20
20
 
21
+ def test_should_collect_context_info
22
+ assert_match /test\/context_test.rb$/, @__running_test__.context_info.file
23
+ assert_equal self.class, @__running_test__.context_info.klass
24
+ end
25
+
21
26
  end
22
27
 
23
28
 
@@ -86,7 +91,7 @@ class Assert::Context
86
91
 
87
92
 
88
93
 
89
- class FailTest < BasicTest
94
+ class FailTests < BasicTest
90
95
  desc "fail method"
91
96
  setup do
92
97
  @result = @context.fail
@@ -98,11 +103,28 @@ class Assert::Context
98
103
  end
99
104
  should "set the calling backtrace on the result" do
100
105
  assert_kind_of Array, subject.backtrace
101
- assert_match /assert\/test\/context_test\.rb/, subject.trace
106
+ assert_equal Factory.context_info_called_from, subject.trace
107
+ end
108
+ end
109
+
110
+ class FlunkTest < BasicTest
111
+ desc "flunk method"
112
+ setup do
113
+ @flunk_msg = "It flunked."
114
+ @result = @context.flunk(@flunk_msg)
115
+ end
116
+ subject{ @result }
117
+
118
+ should "create a fail result" do
119
+ assert_kind_of Assert::Result::Fail, subject
120
+ end
121
+ should "set the message passed to it on the result" do
122
+ assert_equal @flunk_msg, subject.message
102
123
  end
124
+
103
125
  end
104
126
 
105
- class StringMessageTest < FailTest
127
+ class StringMessageTests < FailTests
106
128
  desc "with a string message"
107
129
  setup do
108
130
  @fail_msg = "Didn't work"
@@ -115,7 +137,7 @@ class Assert::Context
115
137
 
116
138
  end
117
139
 
118
- class ProcMessageTest < FailTest
140
+ class ProcMessageTests < FailTests
119
141
  desc "with a proc message"
120
142
  setup do
121
143
  @fail_msg = ::Proc.new{ "Still didn't work" }
@@ -130,25 +152,55 @@ class Assert::Context
130
152
 
131
153
 
132
154
 
133
- class FlunkTest < BasicTest
134
- desc "flunk method"
155
+
156
+
157
+
158
+ class SaveRestoreHaltOnFailTests < BasicTest
159
+ desc "when not halting on fails"
135
160
  setup do
136
- @flunk_msg = "It flunked."
137
- @result = @context.flunk(@flunk_msg)
161
+ @prev_halt_option = Assert::Test.options.halt_on_fail
162
+ @prev_halt_envvar = ENV['halt_on_fail']
163
+ end
164
+ teardown do
165
+ Assert::Test.options.halt_on_fail @prev_halt_option
166
+ ENV['halt_on_fail'] = @prev_halt_envvar
167
+ end
168
+ end
169
+
170
+ class HaltOnFailTests < SaveRestoreHaltOnFailTests
171
+ setup do
172
+ ENV['halt_on_fail'] = 'true'
173
+ Assert::Test.options.halt_on_fail true
174
+ end
175
+ end
176
+
177
+ class HaltFailTests < HaltOnFailTests
178
+ desc "fail method"
179
+ setup do
180
+ @fail_msg = "something failed"
181
+ begin
182
+ @context.fail @fail_msg
183
+ rescue Exception => @exception
184
+ end
185
+ @result = Assert::Result::Fail.new(Factory.test("something"), @exception)
138
186
  end
139
187
  subject{ @result }
140
188
 
141
- should "create a fail result" do
142
- assert_kind_of Assert::Result::Fail, subject
189
+ should "raise a test failure exception when called" do
190
+ assert_kind_of Assert::Result::TestFailure, @exception
191
+ end
192
+ should "raise the exception with the message passed to it" do
193
+ assert_equal @fail_msg, @exception.message
143
194
  end
144
195
  should "set the message passed to it on the result" do
145
- assert_equal @flunk_msg, subject.message
196
+ assert_equal @fail_msg, subject.message
146
197
  end
147
198
 
148
199
  end
149
200
 
150
201
 
151
202
 
203
+
152
204
  class AssertTest < BasicTest
153
205
  desc "assert method"
154
206
  setup do
File without changes
File without changes
@@ -15,14 +15,33 @@ TEST_ASSERT_SUITE = Assert::Suite.new
15
15
  # factory by default. This will ensure any contexts you define in your tests will not be shoved
16
16
  # onto the the suite running the tests.
17
17
  class TestContext < Assert::Context
18
- def self.inherited(klass)
19
- TEST_ASSERT_SUITE << klass
18
+ def self.method_added(meth)
19
+ if meth.to_s =~ Assert::Suite::TEST_METHOD_REGEX
20
+ ci = Assert::Suite::ContextInfo.new(self, Assert.suite.current_caller_info)
21
+ TEST_ASSERT_SUITE.tests << Assert::Test.new(meth.to_s, ci, meth)
22
+ end
23
+ end
24
+ end
25
+
26
+ # force tests to run without halting on fail (needed for tests to run)
27
+ # anywhere we test halt on fail behavior, we take care of it in the specific context
28
+ class Assert::Context
29
+ def setup
30
+ ENV['halt_on_fail'] = 'false'
31
+ Assert::Test.options.halt_on_fail false
20
32
  end
21
33
  end
22
34
 
23
35
  module Factory
24
36
  class << self
25
37
 
38
+ def context_info_called_from
39
+ "/path/to_file.rb:1234"
40
+ end
41
+
42
+ def context_info(context_class)
43
+ Assert::Suite::ContextInfo.new(context_class, context_info_called_from)
44
+ end
26
45
  # Generates an anonymous class inherited from whatever you pass or TextContext by default. This
27
46
  # provides a common interface for all context classes to be generated in the tests.
28
47
  def context_class(inherit_from = nil, &block)
@@ -40,15 +59,15 @@ module Factory
40
59
  # if you need a no-op test.
41
60
  def test(*args, &block)
42
61
  name = (args[0] || "a test").to_s
43
- context_class = args[1] || self.context_class
62
+ context_info = args[1] || self.context_info(self.context_class)
44
63
  test_block = (block || args[2] || ::Proc.new{})
45
64
 
46
- Assert::Test.new(name, context_class, &test_block)
65
+ Assert::Test.new(name, context_info, &test_block)
47
66
  end
48
67
 
49
68
  # Common interface for generating a new skip result
50
69
  def skip_result(name, exception)
51
- Assert::Result::Skip.new(name, exception)
70
+ Assert::Result::Skip.new(Factory.test(name), exception)
52
71
  end
53
72
 
54
73
  end
@@ -0,0 +1,45 @@
1
+ require 'assert'
2
+
3
+ require 'assert/rake_tasks/irb'
4
+
5
+ module Assert::RakeTasks
6
+
7
+ class IrbTests < Assert::Context
8
+ desc "the irb task handler"
9
+ setup do
10
+ @root_path = :test
11
+ @handler = Assert::RakeTasks::Irb.new(@root_path)
12
+ end
13
+ subject { @handler }
14
+
15
+ should have_class_method :task_name, :file_name
16
+ should have_instance_methods :file_path, :helper_exists?, :description, :cmd
17
+
18
+ should "know its rake task name" do
19
+ assert_equal :irb, subject.class.task_name
20
+ end
21
+
22
+ should "know the irb helper file name" do
23
+ assert_equal "irb.rb", subject.class.file_name
24
+ end
25
+
26
+ should "know the irb helper file path" do
27
+ assert_equal File.join(@root_path.to_s, subject.class.file_name), subject.file_path
28
+ end
29
+
30
+ should "know if the irb helper exists" do
31
+ # this is true b/c assert has a test/helper.rb file defined
32
+ assert_equal true, subject.helper_exists?
33
+ end
34
+
35
+ should "know the description of the irb task" do
36
+ assert_equal "Open irb preloaded with #{subject.file_path}", subject.description
37
+ end
38
+
39
+ should "know the shell command to run the irb task" do
40
+ assert_equal "irb -rubygems -r ./#{subject.file_path}", subject.cmd
41
+ end
42
+
43
+ end
44
+
45
+ end