assert 2.5.0 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/assert/cli.rb CHANGED
@@ -42,6 +42,9 @@ module Assert
42
42
  option 'pp_objects', 'pretty-print objects in fail messages', {
43
43
  :abbrev => 'p'
44
44
  }
45
+ option 'profile', 'output test profile info', {
46
+ :abbrev => 'e'
47
+ }
45
48
  # show loaded test files, cli err backtraces, etc
46
49
  option 'debug', 'run in debug mode'
47
50
  end
data/lib/assert/config.rb CHANGED
@@ -16,7 +16,8 @@ module Assert
16
16
  settings :view, :suite, :runner
17
17
  settings :test_dir, :test_helper, :test_file_suffixes, :runner_seed
18
18
  settings :changed_proc, :pp_proc, :use_diff_proc, :run_diff_proc
19
- settings :capture_output, :halt_on_fail, :changed_only, :pp_objects, :debug
19
+ settings :capture_output, :halt_on_fail, :changed_only, :pp_objects
20
+ settings :debug, :profile
20
21
 
21
22
  def initialize(settings = nil)
22
23
  @suite = Assert::Suite.new(self)
@@ -39,6 +40,7 @@ module Assert
39
40
  @changed_only = false
40
41
  @pp_objects = false
41
42
  @debug = false
43
+ @profile = false
42
44
 
43
45
  self.apply(settings || {})
44
46
  end
@@ -15,48 +15,26 @@ class Assert::Context
15
15
  alias_method :after_once, :teardown_once
16
16
  alias_method :shutdown, :teardown_once
17
17
 
18
- # Add a setup block to run before each test or run the list of teardown blocks in given scope
19
- def setup(scope_or_method_name = nil, &block)
20
- is_method = scope_or_method_name.kind_of?(String) || scope_or_method_name.kind_of?(Symbol)
21
- if block_given? || is_method
22
- # arg is a block or method that needs to be stored as a setup
23
- self.setups << (block || scope_or_method_name)
24
- elsif !is_method
25
- # arg is an instance of this class (the scope for a test),
26
- # run the setups for this context in the scope
27
- scope = scope_or_method_name
28
- # setup parent...
29
- self.superclass.setup(scope) if self.superclass.respond_to?(:setup)
30
- # ... before child
31
- self.setups.each do |setup|
32
- setup.kind_of?(::Proc) ? scope.instance_eval(&setup) : scope.send(setup)
33
- end
34
- end
18
+ def around(&block)
19
+ self.arounds << block
20
+ end
21
+
22
+ def setup(method_name = nil, &block)
23
+ self.setups << (block || method_name)
35
24
  end
36
25
  alias_method :before, :setup
37
26
 
38
- # Add a teardown block to run after each test or run the list of teardown blocks in given scope
39
- def teardown(scope_or_method_name = nil, &block)
40
- is_method = scope_or_method_name.kind_of?(String) || scope_or_method_name.kind_of?(Symbol)
41
- if block_given? || is_method
42
- # arg is a block or method that needs to be stored as a teardown
43
- self.teardowns << (block || scope_or_method_name)
44
- elsif !is_method
45
- # arg is an instance of this class (the scope for a test),
46
- # run the setups for this context in the scope
47
- scope = scope_or_method_name
48
- # teardown child...
49
- self.teardowns.each do |teardown|
50
- teardown.kind_of?(::Proc) ? scope.instance_eval(&teardown) : scope.send(teardown)
51
- end
52
- # ... before parent
53
- self.superclass.teardown(scope) if self.superclass.respond_to?(:teardown)
54
- end
27
+ def teardown(method_name = nil, &block)
28
+ self.teardowns << (block || method_name)
55
29
  end
56
30
  alias_method :after, :teardown
57
31
 
58
32
  protected
59
33
 
34
+ def arounds
35
+ @arounds ||= []
36
+ end
37
+
60
38
  def setups
61
39
  @setups ||= []
62
40
  end
@@ -65,6 +43,36 @@ class Assert::Context
65
43
  @teardowns ||= []
66
44
  end
67
45
 
46
+ def run_arounds(scope, &run_block)
47
+ context_block = self.arounds.compact.reverse.inject(run_block) do |run_b, around_b|
48
+ Proc.new{ scope.instance_exec(run_b, &around_b) }
49
+ end
50
+
51
+ if self.superclass.respond_to?(:run_arounds)
52
+ self.superclass.run_arounds(scope, &context_block)
53
+ else
54
+ context_block.call
55
+ end
56
+ end
57
+
58
+ def run_setups(scope)
59
+ # setup the parent...
60
+ self.superclass.run_setups(scope) if self.superclass.respond_to?(:run_setups)
61
+ # ... before you setup the child
62
+ self.setups.compact.each do |setup|
63
+ setup.kind_of?(::Proc) ? scope.instance_eval(&setup) : scope.send(setup)
64
+ end
65
+ end
66
+
67
+ def run_teardowns(scope)
68
+ # teardown the child...
69
+ self.teardowns.compact.each do |teardown|
70
+ teardown.kind_of?(::Proc) ? scope.instance_eval(&teardown) : scope.send(teardown)
71
+ end
72
+ # ... before the parent
73
+ self.superclass.run_teardowns(scope) if self.superclass.respond_to?(:run_teardowns)
74
+ end
75
+
68
76
  end
69
77
 
70
78
  end
data/lib/assert/suite.rb CHANGED
@@ -23,11 +23,11 @@ module Assert
23
23
  end
24
24
 
25
25
  def test_rate
26
- get_rate(self.tests.size, self.run_time.to_f)
26
+ get_rate(self.tests.size, self.run_time)
27
27
  end
28
28
 
29
29
  def result_rate
30
- get_rate(self.results.size, self.run_time.to_f)
30
+ get_rate(self.results.size, self.run_time)
31
31
  end
32
32
 
33
33
  alias_method :ordered_tests, :tests
data/lib/assert/test.rb CHANGED
@@ -8,7 +8,7 @@ module Assert
8
8
  # a test runs, it should have some assertions which are its results.
9
9
 
10
10
  attr_reader :name, :context_info, :config, :code
11
- attr_accessor :results, :output
11
+ attr_accessor :results, :output, :run_time
12
12
 
13
13
  def initialize(name, suite_ci, config, opts = nil, &block)
14
14
  @context_info = suite_ci
@@ -19,6 +19,8 @@ module Assert
19
19
 
20
20
  @results = Result::Set.new
21
21
  @output = ""
22
+ @run_time = 0
23
+ @result_rate = 0
22
24
  end
23
25
 
24
26
  def context_class
@@ -26,36 +28,15 @@ module Assert
26
28
  end
27
29
 
28
30
  def run(&result_callback)
29
- # setup the a new test run
30
31
  @results = Result::Set.new(result_callback)
31
- run_scope = self.context_class.new(self, self.config)
32
32
 
33
- # run the test, capturing its output
34
- begin
35
- run_test_setup(run_scope)
36
- run_test_code(run_scope)
37
- rescue Result::TestFailure => err
38
- @results << Result::Fail.new(self, err)
39
- rescue Result::TestSkipped => err
40
- @results << Result::Skip.new(self, err)
41
- rescue SignalException => err
42
- raise(err)
43
- rescue Exception => err
44
- @results << Result::Error.new(self, err)
45
- ensure
46
- begin
47
- run_test_teardown(run_scope)
48
- rescue Result::TestFailure => err
49
- @results << Result::Fail.new(self, err)
50
- rescue Result::TestSkipped => err
51
- @results << Result::Skip.new(self, err)
52
- rescue SignalException => err
53
- raise(err)
54
- rescue Exception => teardown_err
55
- @results << Result::Error.new(self, teardown_err)
56
- end
33
+ scope = self.context_class.new(self, self.config)
34
+ start_time = Time.now
35
+ capture_output do
36
+ self.context_class.send('run_arounds', scope){ run_test_main(scope) }
57
37
  end
58
- # return the results of the test run
38
+ @run_time = Time.now - start_time
39
+
59
40
  @results
60
41
  end
61
42
 
@@ -73,6 +54,10 @@ module Assert
73
54
  end
74
55
  end
75
56
 
57
+ def result_rate
58
+ get_rate(self.result_count, self.run_time)
59
+ end
60
+
76
61
  def <=>(other_test)
77
62
  self.name <=> other_test.name
78
63
  end
@@ -86,34 +71,55 @@ module Assert
86
71
 
87
72
  protected
88
73
 
74
+ def run_test_main(scope)
75
+ begin
76
+ run_test_setup(scope)
77
+ run_test_code(scope)
78
+ rescue Result::TestFailure => err
79
+ @results << Result::Fail.new(self, err)
80
+ rescue Result::TestSkipped => err
81
+ @results << Result::Skip.new(self, err)
82
+ rescue SignalException => err
83
+ raise(err)
84
+ rescue Exception => err
85
+ @results << Result::Error.new(self, err)
86
+ ensure
87
+ begin
88
+ run_test_teardown(scope)
89
+ rescue Result::TestFailure => err
90
+ @results << Result::Fail.new(self, err)
91
+ rescue Result::TestSkipped => err
92
+ @results << Result::Skip.new(self, err)
93
+ rescue SignalException => err
94
+ raise(err)
95
+ rescue Exception => teardown_err
96
+ @results << Result::Error.new(self, teardown_err)
97
+ end
98
+ end
99
+ end
100
+
89
101
  def run_test_setup(scope)
90
- capture_output do
91
- # run any assert style 'setup do' setups
92
- self.context_class.setup(scope)
102
+ # run any assert style 'setup do' setups
103
+ self.context_class.send('run_setups', scope)
93
104
 
94
- # run any classic test/unit style 'def setup' setups
95
- scope.setup if scope.respond_to?(:setup)
96
- end
105
+ # run any classic test/unit style 'def setup' setups
106
+ scope.setup if scope.respond_to?(:setup)
97
107
  end
98
108
 
99
109
  def run_test_code(scope)
100
- capture_output do
101
- if @code.kind_of?(::Proc)
102
- scope.instance_eval(&@code)
103
- elsif scope.respond_to?(@code.to_s)
104
- scope.send(@code.to_s)
105
- end
110
+ if @code.kind_of?(::Proc)
111
+ scope.instance_eval(&@code)
112
+ elsif scope.respond_to?(@code.to_s)
113
+ scope.send(@code.to_s)
106
114
  end
107
115
  end
108
116
 
109
117
  def run_test_teardown(scope)
110
- capture_output do
111
- # run any classic test/unit style 'def teardown' teardowns
112
- scope.teardown if scope.respond_to?(:teardown)
118
+ # run any classic test/unit style 'def teardown' teardowns
119
+ scope.teardown if scope.respond_to?(:teardown)
113
120
 
114
- # run any assert style 'teardown do' teardowns
115
- self.context_class.teardown(scope)
116
- end
121
+ # run any assert style 'teardown do' teardowns
122
+ self.context_class.send('run_teardowns', scope)
117
123
  end
118
124
 
119
125
  def capture_output(&block)
@@ -137,5 +143,11 @@ module Assert
137
143
  ].compact.reject{|p| p.empty?}.join(" ")
138
144
  end
139
145
 
146
+ private
147
+
148
+ def get_rate(count, time)
149
+ time == 0 ? 0.0 : (count.to_f / time.to_f)
150
+ end
151
+
140
152
  end
141
153
  end
@@ -1,3 +1,3 @@
1
1
  module Assert
2
- VERSION = "2.5.0"
2
+ VERSION = "2.6.0"
3
3
  end
@@ -61,6 +61,17 @@ module Assert::View
61
61
  end
62
62
  end
63
63
 
64
+ # show profile output
65
+ if show_test_profile_info?
66
+ ordered_profile_tests.each do |test|
67
+ puts "#{test_run_time(test)} seconds,"\
68
+ " #{test.result_count} results,"\
69
+ " #{test_result_rate(test)} results/s --"\
70
+ " #{test.context_class}: #{test.name.inspect}"
71
+ end
72
+ puts
73
+ end
74
+
64
75
  # style the summaries of each result set
65
76
  styled_results_sentence = results_summary_sentence do |summary, sym|
66
77
  ansi_styled_msg(summary, result_ansi_styles(sym))
@@ -37,6 +37,16 @@ module Assert::View::Helpers
37
37
  format % self.suite.result_rate
38
38
  end
39
39
 
40
+ # get the formatted run time for an idividual test
41
+ def test_run_time(test, format = '%.6f')
42
+ format % test.run_time
43
+ end
44
+
45
+ # get the formatted result rate for an individual test
46
+ def test_result_rate(test, format = '%.6f')
47
+ format % test.result_rate
48
+ end
49
+
40
50
  # get a uniq list of contexts for the test suite
41
51
  def suite_contexts
42
52
  @suite_contexts ||= self.suite.tests.inject([]) do |contexts, test|
@@ -59,6 +69,14 @@ module Assert::View::Helpers
59
69
  self.suite_files.sort{|a,b| a.to_s <=> b.to_s}
60
70
  end
61
71
 
72
+ def ordered_profile_tests
73
+ suite.ordered_tests.sort{ |a, b| a.run_time <=> b.run_time }
74
+ end
75
+
76
+ def show_test_profile_info?
77
+ !!config.profile
78
+ end
79
+
62
80
  # get all the result details for a set of tests
63
81
  def result_details_for(tests, result_order=:normal)
64
82
  test_index = 0
@@ -262,8 +262,8 @@ class RunningSystemTests < Assert::Context
262
262
 
263
263
  end
264
264
 
265
- class WithSetupTests < RunningSystemTests
266
- desc "has assertions that depend on setups"
265
+ class WithSetupsTests < RunningSystemTests
266
+ desc "has tests that depend on setups"
267
267
  setup do
268
268
  assert_style_msg = @asm = "set by assert style setup"
269
269
  testunit_style_msg = @tusm = "set by test/unit style setup"
@@ -307,8 +307,8 @@ class RunningSystemTests < Assert::Context
307
307
 
308
308
  end
309
309
 
310
- class WithTeardownTests < RunningSystemTests
311
- desc "has assertions with teardowns"
310
+ class WithTeardownsTests < RunningSystemTests
311
+ desc "has tests that depend on teardowns"
312
312
  setup do
313
313
  assert_style_msg = @asm = "set by assert style teardown"
314
314
  testunit_style_msg = @tusm = "set by test/unit style teardown"
@@ -351,4 +351,54 @@ class RunningSystemTests < Assert::Context
351
351
 
352
352
  end
353
353
 
354
+ class WithAroundsTests < RunningSystemTests
355
+ desc "has arounds (in addition to setups/teardowns)"
356
+ setup do
357
+ @parent_class = Factory.modes_off_context_class do
358
+ around do |block|
359
+ @__running_test__.output += "p-around start, "
360
+ block.call
361
+ @__running_test__.output += "p-around end."
362
+ end
363
+ setup{ @__running_test__.output += "p-setup, " }
364
+ teardown{ @__running_test__.output += "p-teardown, " }
365
+ end
366
+
367
+ @context_class = Factory.modes_off_context_class(@parent_class) do
368
+ attr_accessor :out_status
369
+
370
+ setup{ @__running_test__.output += "c-setup1, " }
371
+ around do |block|
372
+ @__running_test__.output += "c-around1 start, "
373
+ block.call
374
+ @__running_test__.output += "c-around1 end, "
375
+ end
376
+ teardown{ @__running_test__.output += "c-teardown1, " }
377
+ setup{ @__running_test__.output += "c-setup2, " }
378
+ around do |block|
379
+ @__running_test__.output += "c-around2 start, "
380
+ block.call
381
+ @__running_test__.output += "c-around2 end, "
382
+ end
383
+ teardown{ @__running_test__.output += "c-teardown2, " }
384
+ end
385
+
386
+
387
+ @test = Factory.test("something amazing", Factory.context_info(@context_class)) do
388
+ @__running_test__.output += "TEST, "
389
+ end
390
+ @test.run
391
+ end
392
+
393
+ should "run the arounds outside of the setups/teardowns/test" do
394
+ exp = "p-around start, c-around1 start, c-around2 start, "\
395
+ "p-setup, c-setup1, c-setup2, "\
396
+ "TEST, "\
397
+ "c-teardown1, c-teardown2, p-teardown, "\
398
+ "c-around2 end, c-around1 end, p-around end."
399
+ assert_equal exp, subject.output
400
+ end
401
+
402
+ end
403
+
354
404
  end
@@ -13,7 +13,8 @@ class Assert::Config
13
13
  should have_imeths :suite, :view, :runner
14
14
  should have_imeths :test_dir, :test_helper, :test_file_suffixes, :runner_seed
15
15
  should have_imeths :changed_proc, :pp_proc, :use_diff_proc, :run_diff_proc
16
- should have_imeths :capture_output, :halt_on_fail, :changed_only, :pp_objects, :debug
16
+ should have_imeths :capture_output, :halt_on_fail, :changed_only, :pp_objects
17
+ should have_imeths :debug, :profile
17
18
  should have_imeths :apply
18
19
 
19
20
  should "default the view, suite, and runner" do
@@ -42,6 +43,7 @@ class Assert::Config
42
43
  assert_not subject.changed_only
43
44
  assert_not subject.pp_objects
44
45
  assert_not subject.debug
46
+ assert_not subject.profile
45
47
  end
46
48
 
47
49
  should "apply settings given from a hash" do
@@ -91,13 +91,57 @@ module Assert::Context::SetupDSL
91
91
  end
92
92
 
93
93
  should "run it's parent and it's own blocks in the correct order" do
94
- subject.setup(obj = @test_status_class.new)
94
+ subject.send('run_setups', obj = @test_status_class.new)
95
95
  assert_equal "the setup has been run with something", obj.setup_status
96
96
 
97
- subject.teardown(obj = @test_status_class.new)
97
+ subject.send('run_teardowns', obj = @test_status_class.new)
98
98
  assert_equal "with something has been run the teardown", obj.teardown_status
99
99
  end
100
100
 
101
101
  end
102
102
 
103
+ class AroundMethodTests < UnitTests
104
+ desc "with multiple `around` calls"
105
+ setup do
106
+ @parent_class = Factory.modes_off_context_class do
107
+ around do |block|
108
+ self.out_status ||= ''
109
+ self.out_status += "p-around start, "
110
+ block.call
111
+ self.out_status += "p-around end."
112
+ end
113
+ end
114
+
115
+ @context_class = Factory.modes_off_context_class(@parent_class) do
116
+ around do |block|
117
+ self.out_status += "c-around1 start, "
118
+ block.call
119
+ self.out_status += "c-around1 end, "
120
+ end
121
+ around do |block|
122
+ self.out_status += "c-around2 start, "
123
+ block.call
124
+ self.out_status += "c-around2 end, "
125
+ end
126
+ end
127
+
128
+ @test_status_class = Class.new do
129
+ attr_accessor :out_status
130
+ end
131
+ end
132
+
133
+ should "run it's parent and it's own blocks in the correct order" do
134
+ obj = @test_status_class.new
135
+ subject.send('run_arounds', obj) do
136
+ obj.instance_eval{ self.out_status += 'TEST, ' }
137
+ end
138
+
139
+ exp = "p-around start, c-around1 start, c-around2 start, "\
140
+ "TEST, "\
141
+ "c-around2 end, c-around1 end, p-around end."
142
+ assert_equal exp, obj.out_status
143
+ end
144
+
145
+ end
146
+
103
147
  end
@@ -19,8 +19,9 @@ class Assert::Context
19
19
  should have_cmeths :description, :desc, :describe, :subject, :suite
20
20
  should have_cmeths :setup_once, :before_once, :startup
21
21
  should have_cmeths :teardown_once, :after_once, :shutdown
22
- should have_cmeths :setup, :before, :setups
23
- should have_cmeths :teardown, :after, :teardowns
22
+ should have_cmeths :setup, :before, :setups, :run_setups
23
+ should have_cmeths :teardown, :after, :teardowns, :run_teardowns
24
+ should have_cmeths :around, :arounds, :run_arounds
24
25
  should have_cmeths :test, :test_eventually, :test_skip
25
26
  should have_cmeths :should, :should_eventually, :should_skip
26
27
 
@@ -25,7 +25,7 @@ class Assert::Suite
25
25
  assert_equal(exp, act)
26
26
  end
27
27
 
28
- should "have a zero run time, test rate and result by default" do
28
+ should "have a zero run time, test rate and result rate by default" do
29
29
  assert_equal 0, subject.run_time
30
30
  assert_equal 0, subject.test_rate
31
31
  assert_equal 0, subject.result_rate
@@ -16,8 +16,8 @@ class Assert::Test
16
16
  subject{ @test }
17
17
 
18
18
  should have_readers :name, :context_info, :config, :code
19
- should have_accessors :results, :output
20
- should have_imeths :run, :result_count, :context_class
19
+ should have_accessors :results, :output, :run_time
20
+ should have_imeths :run, :result_count, :result_rate, :context_class
21
21
  should have_imeths *Assert::Result.types.keys.collect{ |k| "#{k}_results" }
22
22
 
23
23
  should "build its name from the context description" do
@@ -47,6 +47,17 @@ class Assert::Test
47
47
  assert_equal 0, subject.result_count
48
48
  end
49
49
 
50
+ should "have a zero run time and result rate by default" do
51
+ assert_equal 0, subject.run_time
52
+ assert_equal 0, subject.result_rate
53
+ end
54
+
55
+ should "have a non-zero run time and result rate after it is run" do
56
+ subject.run
57
+ assert_not_equal 0, subject.run_time
58
+ assert_not_equal 0, subject.result_rate
59
+ end
60
+
50
61
  should "have a custom inspect that only shows limited attributes" do
51
62
  attrs_string = [:name, :context_info, :results].collect do |method|
52
63
  "@#{method}=#{subject.send(method).inspect}"
@@ -22,9 +22,11 @@ class Assert::View::Base
22
22
  # common methods
23
23
  should have_imeths :runner_seed, :count, :tests?, :all_pass?
24
24
  should have_imeths :run_time, :test_rate, :result_rate
25
+ should have_imeths :test_run_time, :test_result_rate
25
26
  should have_imeths :suite_contexts, :ordered_suite_contexts
26
27
  should have_imeths :suite_files, :ordered_suite_files
27
- should have_imeths :result_details_for, :show_result_details?
28
+ should have_imeths :ordered_profile_tests, :show_test_profile_info?
29
+ should have_imeths :result_details_for, :matched_result_details_for, :show_result_details?
28
30
  should have_imeths :ocurring_result_types, :result_summary_msg
29
31
  should have_imeths :all_pass_result_summary_msg, :results_summary_sentence
30
32
  should have_imeths :test_count_statement, :result_count_statement
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: assert
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 2
8
- - 5
8
+ - 6
9
9
  - 0
10
- version: 2.5.0
10
+ version: 2.6.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Kelly Redding
@@ -16,11 +16,11 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2014-01-02 00:00:00 Z
19
+ date: 2014-01-08 00:00:00 Z
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
- name: ansi
23
22
  prerelease: false
23
+ type: :runtime
24
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
25
  none: false
26
26
  requirements:
@@ -31,8 +31,8 @@ dependencies:
31
31
  - 1
32
32
  - 3
33
33
  version: "1.3"
34
- type: :runtime
35
34
  version_requirements: *id001
35
+ name: ansi
36
36
  description: Test::Unit style testing framework, just better than Test::Unit.
37
37
  email:
38
38
  - kelly@kellyredding.com