assert 2.5.0 → 2.6.0

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/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