assert 1.1.0 → 2.0.0.rc.1

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.
Files changed (49) hide show
  1. data/.assert.rb +3 -0
  2. data/README.md +182 -108
  3. data/Rakefile +0 -3
  4. data/bin/assert +1 -1
  5. data/lib/assert.rb +75 -4
  6. data/lib/assert/assert_runner.rb +76 -0
  7. data/lib/assert/cli.rb +25 -46
  8. data/lib/assert/context.rb +3 -3
  9. data/lib/assert/result.rb +65 -55
  10. data/lib/assert/runner.rb +19 -38
  11. data/lib/assert/suite.rb +0 -7
  12. data/lib/assert/test.rb +4 -16
  13. data/lib/assert/version.rb +1 -1
  14. data/lib/assert/view.rb +23 -0
  15. data/lib/assert/view/base.rb +10 -19
  16. data/lib/assert/view/default_view.rb +16 -11
  17. data/lib/assert/view/helpers/ansi_styles.rb +1 -1
  18. data/lib/assert/view/helpers/common.rb +37 -16
  19. data/test/assert_test.rb +29 -14
  20. data/test/context/class_methods_test.rb +2 -2
  21. data/test/context_test.rb +28 -50
  22. data/test/helper.rb +4 -2
  23. data/test/runner_test.rb +5 -4
  24. data/test/suite_test.rb +1 -1
  25. data/test/test_test.rb +8 -15
  26. data/test/view/base_tests.rb +20 -37
  27. metadata +17 -39
  28. data/lib/assert/autorun.rb +0 -37
  29. data/lib/assert/options.rb +0 -43
  30. data/lib/assert/rake_tasks.rb +0 -75
  31. data/lib/assert/rake_tasks/irb.rb +0 -33
  32. data/lib/assert/rake_tasks/scope.rb +0 -100
  33. data/lib/assert/rake_tasks/test_task.rb +0 -66
  34. data/lib/assert/result_set.rb +0 -17
  35. data/lib/assert/setup.rb +0 -3
  36. data/lib/assert/setup/all.rb +0 -5
  37. data/lib/assert/setup/helpers.rb +0 -72
  38. data/lib/assert/setup/options.rb +0 -6
  39. data/lib/assert/setup/runner.rb +0 -13
  40. data/lib/assert/setup/suite.rb +0 -13
  41. data/lib/assert/setup/view.rb +0 -39
  42. data/lib/assert/view/helpers/capture_output.rb +0 -23
  43. data/test/default_view_test.rb +0 -16
  44. data/test/irb.rb +0 -5
  45. data/test/options_test.rb +0 -40
  46. data/test/rake_tasks/irb_test.rb +0 -45
  47. data/test/rake_tasks/scope_test.rb +0 -63
  48. data/test/rake_tasks/test_task_test.rb +0 -80
  49. data/test/result_set_test.rb +0 -72
@@ -0,0 +1,76 @@
1
+ module Assert
2
+
3
+ class AssertRunner
4
+ TEST_FILE_SUFFIXES = ['_tests.rb', '_test.rb']
5
+ USER_SETTINGS_FILE = ".assert/init.rb"
6
+ LOCAL_SETTINGS_FILE = ".assert.rb"
7
+
8
+ def initialize(test_paths, test_options)
9
+ require 'assert' # inits config singleton with the default settings
10
+
11
+ apply_user_settings
12
+ apply_local_settings
13
+ apply_option_settings(test_options)
14
+ apply_env_settings
15
+
16
+ files = test_files(test_paths.empty? ? Assert.config.test_dir : test_paths)
17
+ Assert.init(files, {
18
+ :test_dir_path => path_of(Assert.config.test_dir, files.first)
19
+ })
20
+ end
21
+
22
+ def run
23
+ Assert.runner.run(Assert.suite, Assert.view)
24
+ end
25
+
26
+ protected
27
+
28
+ def apply_user_settings
29
+ safe_require("#{ENV['HOME']}/#{USER_SETTINGS_FILE}") if ENV['HOME']
30
+ end
31
+
32
+ def apply_local_settings
33
+ safe_require(ENV['ASSERT_LOCALFILE'] || path_of(LOCAL_SETTINGS_FILE, Dir.pwd))
34
+ end
35
+
36
+ def apply_option_settings(options)
37
+ Assert.config.apply(options)
38
+ end
39
+
40
+ def apply_env_settings
41
+ Assert.configure do |c|
42
+ c.runner_seed ENV['ASSERT_RUNNER_SEED'].to_i if ENV['ASSERT_RUNNER_SEED']
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ def test_files(test_paths)
49
+ test_paths.inject(Set.new) do |paths, path|
50
+ paths += Dir.glob("#{path}*") + Dir.glob("#{path}*/**/*")
51
+ end.select{ |p| is_test_file?(p) }.sort
52
+ end
53
+
54
+ def is_test_file?(path)
55
+ TEST_FILE_SUFFIXES.inject(false) do |result, suffix|
56
+ result || path =~ /#{suffix}$/
57
+ end
58
+ end
59
+
60
+ def safe_require(settings_file)
61
+ require settings_file if File.exists?(settings_file)
62
+ end
63
+
64
+ # this method inspects a test path and finds the test dir path.
65
+
66
+ def path_of(segment, a_path)
67
+ full_path = File.expand_path(a_path || '.', Dir.pwd)
68
+ seg_pos = full_path.index(segment_regex(segment))
69
+ File.join(seg_pos && (seg_pos > 0) ? full_path[0..(seg_pos-1)] : full_path, segment)
70
+ end
71
+
72
+ def segment_regex(seg); /^#{seg}$|^#{seg}\/|\/#{seg}\/|\/#{seg}$/; end
73
+
74
+ end
75
+
76
+ end
@@ -1,4 +1,5 @@
1
1
  require 'set'
2
+ require 'assert/assert_runner'
2
3
  require 'assert/version'
3
4
 
4
5
  module Assert
@@ -10,75 +11,53 @@ module Assert
10
11
  end
11
12
 
12
13
  def initialize
13
- @cli = CLIRB.new
14
+ @cli = CLIRB.new do
15
+ option 'runner_seed', 'Use a given seed to run tests', {
16
+ :abbrev => 's', :value => Fixnum
17
+ }
18
+ option 'show_output', 'show stdout output (do not capture)', {
19
+ :abbrev => 'o'
20
+ }
21
+ option 'halt_on_fail', 'halt a test when it fails', {
22
+ :abbrev => 't'
23
+ }
24
+ # show loaded test files, cli err backtraces, etc
25
+ option 'debug', 'run in debug mode'
26
+ end
14
27
  end
15
28
 
16
29
  def run(*args)
30
+ # default debug_mode to the env var
31
+ debug_mode = ENV['ASSERT_DEBUG'] == 'true'
17
32
  begin
18
- @cli.parse!(*args)
19
- tests = @cli.args
20
- tests = ['test'] if tests.empty?
21
- Assert::CLIRunner.new(*tests).run
33
+ # parse manually in the case that parsing fails before the debug arg
34
+ debug_mode ||= args.include?('-d') || args.include?('--debug')
35
+ @cli.parse!(args)
36
+ Assert::AssertRunner.new(@cli.args, @cli.opts).run
22
37
  rescue CLIRB::HelpExit
23
38
  puts help
24
39
  rescue CLIRB::VersionExit
25
40
  puts Assert::VERSION
26
41
  rescue CLIRB::Error => exception
27
- puts "#{exception.message}\n"
28
- puts help
42
+ puts "#{exception.message}\n\n"
43
+ puts debug_mode ? exception.backtrace.join("\n") : help
29
44
  exit(1)
30
45
  rescue Exception => exception
31
46
  puts "#{exception.class}: #{exception.message}"
32
- puts exception.backtrace.join("\n") if ENV['DEBUG']
47
+ puts exception.backtrace.join("\n") if debug_mode
33
48
  exit(1)
34
49
  end
35
-
36
- # Don't call `exit(0)`. The test suite runs as the by an `at_exit`
37
- # callback. Calling `exit(0)` bypasses that callback.
50
+ exit(0)
38
51
  end
39
52
 
40
53
  def help
41
- "Usage: assert [TESTS] [options]\n\n"\
54
+ "Usage: assert [options] [TESTS]\n\n"\
42
55
  "Options:"\
43
56
  "#{@cli}"
44
57
  end
45
58
 
46
59
  end
47
60
 
48
- class CLIRunner
49
- TEST_FILE_SUFFIXES = ['_tests.rb', '_test.rb']
50
-
51
- attr_reader :test_files
52
-
53
- def initialize(*args)
54
- options, test_paths = [
55
- args.last.kind_of?(::Hash) ? args.pop : {},
56
- args
57
- ]
58
-
59
- @test_files = file_paths(test_paths).select{ |f| test_file?(f) }
60
- end
61
-
62
- def run
63
- @test_files.each{ |file| require file }
64
- require 'assert' if @test_files.empty? # show empty test output
65
- end
66
-
67
- private
68
-
69
- def file_paths(test_paths)
70
- test_paths.inject(Set.new) do |paths, path|
71
- paths += Dir.glob("#{path}*") + Dir.glob("#{path}*/**/*")
72
- end
73
- end
74
-
75
- def test_file?(path)
76
- TEST_FILE_SUFFIXES.inject(false) do |result, suffix|
77
- result || path =~ /#{suffix}$/
78
- end
79
- end
80
- end
81
-
82
61
  class CLIRB # Version 1.0.0, https://github.com/redding/cli.rb
83
62
  Error = Class.new(RuntimeError);
84
63
  HelpExit = Class.new(RuntimeError); VersionExit = Class.new(RuntimeError)
@@ -204,11 +204,11 @@ module Assert
204
204
  end
205
205
 
206
206
  # adds a Fail result to the end of the test's results
207
- # does not break test execution
207
+ # break test execution if Assert.config.halt_on_fail
208
208
  def fail(fail_msg=nil)
209
209
  message = (fail_message(fail_msg) { }).call
210
- if Assert::Test.halt_on_fail?
211
- raise(Result::TestFailure, message)
210
+ if Assert.config.halt_on_fail
211
+ raise Result::TestFailure, message
212
212
  else
213
213
  capture_result do |test, backtrace|
214
214
  Assert::Result::Fail.new(test, message, backtrace)
@@ -17,59 +17,6 @@ module Assert::Result
17
17
  }
18
18
  end
19
19
 
20
- class Backtrace < ::Array
21
- # ripped from minitest...
22
-
23
- file = File.expand_path __FILE__
24
- # if RUBY_VERSION =~ /^1\.9/ then # bt's expanded, but __FILE__ isn't :(
25
- # File.expand_path __FILE__
26
- # elsif __FILE__ =~ /^[^\.]/ then # assume both relative
27
- # require 'pathname'
28
- # pwd = Pathname.new Dir.pwd
29
- # pn = Pathname.new File.expand_path(__FILE__)
30
- # relpath = pn.relative_path_from(pwd) rescue pn
31
- # pn = File.join ".", relpath unless pn.relative?
32
- # pn.to_s
33
- # else # assume both are expanded
34
- # __FILE__
35
- # end
36
-
37
- # './lib' in project dir, or '/usr/local/blahblah' if installed
38
- ASSERT_DIR = File.dirname(File.dirname(file))
39
-
40
- def initialize(value=nil)
41
- super(value || ["No backtrace"])
42
- end
43
-
44
- def to_s
45
- self.join("\n")
46
- end
47
-
48
- def filtered
49
- new_bt = []
50
-
51
- self.each do |line|
52
- break if filter_out?(line)
53
- new_bt << line
54
- end
55
-
56
- new_bt = self.reject { |line| filter_out?(line) } if new_bt.empty?
57
- new_bt = self.dup if new_bt.empty?
58
-
59
- self.class.new(new_bt)
60
- end
61
-
62
- protected
63
-
64
- def filter_out?(line)
65
- line.rindex(ASSERT_DIR, 0)
66
- end
67
-
68
- end
69
-
70
-
71
- # Result classes...
72
-
73
20
  class Base
74
21
 
75
22
  attr_reader :test, :message, :backtrace
@@ -138,8 +85,7 @@ module Assert::Result
138
85
  end
139
86
 
140
87
  # raised by the 'fail' context helper to break test execution
141
- # (if Test.halt_on_fail?)
142
- class TestFailure < RuntimeError; end
88
+ TestFailure = Class.new(RuntimeError)
143
89
 
144
90
  class Fail < Base
145
91
 
@@ -213,6 +159,70 @@ module Assert::Result
213
159
  def trace
214
160
  self.backtrace.to_s
215
161
  end
162
+
163
+ end
164
+
165
+ # Utility Classes
166
+
167
+ class Set < ::Array
168
+ attr_accessor :callback
169
+
170
+ def initialize(callback=nil)
171
+ @callback = callback
172
+ super()
173
+ end
174
+
175
+ def <<(result)
176
+ super
177
+ @callback.call(result) if @callback
178
+ end
179
+ end
180
+
181
+ class Backtrace < ::Array
182
+ def initialize(value=nil)
183
+ super(value || ["No backtrace"])
184
+ end
185
+
186
+ def to_s; self.join("\n"); end
187
+
188
+ def filtered
189
+ new_bt = []
190
+
191
+ self.each do |line|
192
+ break if filter_out?(line)
193
+ new_bt << line
194
+ end
195
+
196
+ new_bt = self.reject { |line| filter_out?(line) } if new_bt.empty?
197
+ new_bt = self.dup if new_bt.empty?
198
+
199
+ self.class.new(new_bt)
200
+ end
201
+
202
+ protected
203
+
204
+ # filter a line out if it's an assert lib line
205
+
206
+ def filter_out?(line)
207
+ # from minitest (for reference)...
208
+ # file = File.expand_path __FILE__
209
+ # if RUBY_VERSION =~ /^1\.9/ then # bt's expanded, but __FILE__ isn't :(
210
+ # File.expand_path __FILE__
211
+ # elsif __FILE__ =~ /^[^\.]/ then # assume both relative
212
+ # require 'pathname'
213
+ # pwd = Pathname.new Dir.pwd
214
+ # pn = Pathname.new File.expand_path(__FILE__)
215
+ # relpath = pn.relative_path_from(pwd) rescue pn
216
+ # pn = File.join ".", relpath unless pn.relative?
217
+ # pn.to_s
218
+ # else # assume both are expanded
219
+ # __FILE__
220
+ # end
221
+
222
+ # './lib' in project dir, or '/usr/local/blahblah' if installed
223
+ assert_lib_path = File.expand_path('../..', __FILE__)
224
+ line.rindex(assert_lib_path, 0)
225
+ end
216
226
  end
217
227
 
218
228
  end
@@ -1,54 +1,35 @@
1
1
  module Assert
2
+
2
3
  class Runner
3
4
 
4
- # a Runner runs a suite of tests.
5
+ # Runner runs a suite of tests.
5
6
 
6
- def initialize(suite, view)
7
+ def run(suite, view)
7
8
  raise ArgumentError if !suite.kind_of?(Suite)
8
- @suite = suite
9
- @view = view
10
- end
11
9
 
12
- def run
13
- @view.fire(:on_start)
14
- @suite.setup
10
+ view.fire(:on_start)
11
+ suite.setup
15
12
 
16
- benchmark { run_suite }
17
-
18
- @suite.teardown
19
- @view.fire(:on_finish)
13
+ suite.start_time = Time.now
14
+ # TODO: parallel running
15
+ tests_to_run(suite).each do |test|
16
+ view.fire(:before_test, test)
17
+ test.run{ |result| view.fire(:on_result, result) }
18
+ view.fire(:after_test, test)
19
+ end
20
+ suite.end_time = Time.now
20
21
 
21
- count(:failed) + count(:errored)
22
- end
22
+ suite.teardown
23
+ view.fire(:on_finish)
23
24
 
24
- def count(type)
25
- @suite.count(type)
25
+ suite.count(:failed) + suite.count(:errored)
26
26
  end
27
27
 
28
28
  protected
29
29
 
30
- def tests_to_run
31
- # order tests randomly
32
- tests = @suite.tests
33
- srand @suite.runner_seed
34
- tests.sort.sort_by { rand tests.size }
35
- end
36
-
37
- private
38
-
39
- def benchmark
40
- @suite.start_time = Time.now
41
- yield if block_given?
42
- @suite.end_time = Time.now
43
- end
44
-
45
- def run_suite
46
- # TODO: parallel running
47
- tests_to_run.each do |test|
48
- @view.fire(:before_test, test)
49
- test.run {|result| @view.fire(:on_result, result)}
50
- @view.fire(:after_test, test)
51
- end
30
+ def tests_to_run(suite)
31
+ srand Assert.config.runner_seed # TODO: secure random??
32
+ suite.tests.sort.sort_by { rand suite.tests.size }
52
33
  end
53
34
 
54
35
  end
@@ -36,13 +36,6 @@ module Assert
36
36
  @end_time - @start_time
37
37
  end
38
38
 
39
- def runner_seed
40
- @run_seed ||= (ENV["runner_seed"] || begin
41
- srand
42
- srand % 0xFFFF
43
- end).to_i
44
- end
45
-
46
39
  alias_method :ordered_tests, :tests
47
40
 
48
41
  def results
@@ -1,20 +1,8 @@
1
- require 'assert/result'
2
- require 'assert/result_set'
3
- require 'assert/options'
4
-
5
1
  require 'stringio'
2
+ require 'assert/result'
6
3
 
7
4
  module Assert
8
5
  class Test
9
- include Assert::Options
10
- options do
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
17
- end
18
6
 
19
7
  # a Test is some code/method to run in the scope of a Context. After a
20
8
  # a test runs, it should have some assertions which are its results.
@@ -26,7 +14,7 @@ module Assert
26
14
  @context_info = suite_context_info
27
15
  @name = name_from_context(name)
28
16
  @code = (code || block)
29
- @results = ResultSet.new
17
+ @results = Result::Set.new
30
18
  @output = ""
31
19
  end
32
20
 
@@ -36,7 +24,7 @@ module Assert
36
24
 
37
25
  def run(&result_callback)
38
26
  # setup the a new test run
39
- @results = ResultSet.new(result_callback)
27
+ @results = Result::Set.new(result_callback)
40
28
  run_scope = self.context_class.new(self)
41
29
 
42
30
  # run the test, capturing its output
@@ -118,7 +106,7 @@ module Assert
118
106
  end
119
107
 
120
108
  def capture_output(&block)
121
- if self.class.options.capture_output
109
+ if Assert.config.show_output == false
122
110
  orig_stdout = $stdout.clone
123
111
  $stdout = capture_io
124
112
  block.call