assert 0.7.3 → 0.8.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.
Files changed (40) hide show
  1. data/.gitignore +16 -4
  2. data/{CHANGELOG.rdoc → CHANGELOG.md} +14 -3
  3. data/LICENSE +22 -0
  4. data/README.md +261 -0
  5. data/Rakefile +1 -1
  6. data/assert.gemspec +2 -1
  7. data/lib/assert/assertions.rb +16 -0
  8. data/lib/assert/autorun.rb +11 -7
  9. data/lib/assert/macros/methods.rb +49 -3
  10. data/lib/assert/rake_tasks.rb +13 -7
  11. data/lib/assert/rake_tasks/irb.rb +1 -1
  12. data/lib/assert/rake_tasks/scope.rb +55 -28
  13. data/lib/assert/rake_tasks/test_task.rb +4 -1
  14. data/lib/assert/result.rb +7 -9
  15. data/lib/assert/result_set.rb +7 -4
  16. data/lib/assert/runner.rb +10 -10
  17. data/lib/assert/setup/helpers.rb +5 -3
  18. data/lib/assert/setup/runner.rb +2 -3
  19. data/lib/assert/setup/suite.rb +2 -5
  20. data/lib/assert/setup/view.rb +26 -3
  21. data/lib/assert/test.rb +56 -37
  22. data/lib/assert/version.rb +1 -1
  23. data/lib/assert/view/base.rb +75 -0
  24. data/lib/assert/view/default_view.rb +75 -0
  25. data/lib/assert/view/helpers/ansi_styles.rb +25 -0
  26. data/lib/assert/view/helpers/capture_output.rb +23 -0
  27. data/lib/assert/view/helpers/common.rb +154 -0
  28. data/test/assertions/assert_file_exists_test.rb +43 -0
  29. data/test/assertions/assert_not_file_exists_test.rb +43 -0
  30. data/test/assertions_test.rb +4 -1
  31. data/test/macro_test.rb +25 -0
  32. data/test/rake_tasks/irb_test.rb +2 -2
  33. data/test/rake_tasks/scope_test.rb +9 -9
  34. data/test/result_set_test.rb +13 -23
  35. data/test/runner_test.rb +1 -1
  36. data/test/test/{running_test.rb → running_tests.rb} +14 -14
  37. data/test/view/base_tests.rb +65 -0
  38. metadata +29 -18
  39. data/Gemfile.lock +0 -23
  40. data/README.rdoc +0 -183
@@ -9,18 +9,24 @@ require 'assert/rake_tasks/test_task'
9
9
 
10
10
  module Assert::RakeTasks
11
11
 
12
- FILE_SUFFIX = "_test.rb"
13
-
14
12
  # Setup the rake tasks for testing
15
13
  # * add 'include Assert::RakeTasks' to your Rakefile
16
14
  def self.included(receiver)
17
- # auto-build rake tasks for the ./test files (if defined in ./test)
18
- self.for('test') if File.exists?(File.expand_path('./test', Dir.pwd))
15
+ # auto-install rake tasks
16
+ self.install
17
+ end
18
+
19
+ def self.install
20
+ assert_test_root = ENV['ASSERT_TEST_ROOT'] || './test'
21
+
22
+ if File.exists?(assert_test_root)
23
+ self.irb_task(Assert::RakeTasks::Irb.new(assert_test_root))
24
+ self.to_tasks(Assert::RakeTasks::Scope.new(assert_test_root))
25
+ end
19
26
  end
20
27
 
21
- def self.for(test_root='test')
22
- self.irb_task(Assert::RakeTasks::Irb.new(test_root.to_s))
23
- self.to_tasks(Assert::RakeTasks::Scope.new(test_root.to_s))
28
+ def self.for(test_root_name)
29
+ warn "[DEPRECATED] `Assert::RakeTasts.for` has been deprecated. Use `Assert::RakeTasks.install` instead."
24
30
  end
25
31
 
26
32
  class << self
@@ -26,7 +26,7 @@ module Assert::RakeTasks
26
26
  end
27
27
 
28
28
  def cmd
29
- "irb -rubygems -r ./#{self.file_path}"
29
+ "irb -rubygems -r #{self.file_path}"
30
30
  end
31
31
 
32
32
  end
@@ -4,29 +4,25 @@ require 'assert/rake_tasks/test_task'
4
4
  module Assert::RakeTasks
5
5
  class Scope
6
6
 
7
- def self.test_file_suffix
8
- "_test.rb"
7
+ def self.test_file_suffixes
8
+ ['_test.rb', '_tests.rb']
9
9
  end
10
10
 
11
+ attr_reader :path, :nested_files, :path_file_list, :test_tasks, :scopes
12
+
11
13
  def initialize(path)
12
14
  @path = path
15
+
16
+ @nested_files = get_nested_files
17
+ @path_file_list = build_path_file_list
18
+ @test_tasks = build_test_tasks
19
+ @scopes = build_scopes
13
20
  end
14
21
 
15
22
  def namespace
16
23
  File.basename(@path).to_sym
17
24
  end
18
25
 
19
- # nested test files under the path
20
- def nested_files
21
- nested_files = Rake::FileList["#{@path}/**/*#{self.class.test_file_suffix}"]
22
- end
23
-
24
- # a list with the path test file "#{path}_test.rb" (if it exists)
25
- def path_file_list
26
- path_file_name = @path+self.class.test_file_suffix
27
- (File.exists?(path_file_name) ? Rake::FileList[path_file_name] : [])
28
- end
29
-
30
26
  # return a test task covering the scopes nested files plus path file
31
27
  # but only if there are nested files
32
28
  def to_test_task
@@ -37,32 +33,63 @@ module Assert::RakeTasks
37
33
  end
38
34
  end
39
35
 
36
+ protected
37
+
38
+ # nested test files under the path
39
+
40
+ def get_nested_files
41
+ self.class.test_file_suffixes.map do |suffix|
42
+ Rake::FileList["#{@path}/**/*#{suffix}"]
43
+ end.flatten
44
+ end
45
+
46
+ # a list with the path test file "#{path}_test.rb" (if it exists)
47
+
48
+ def build_path_file_list
49
+ self.class.test_file_suffixes.map do |suffix|
50
+ path_file_name = "#{@path}#{suffix}"
51
+ File.exists?(path_file_name) ? Rake::FileList[path_file_name] : []
52
+ end.flatten
53
+ end
54
+
40
55
  # a collection of test tasks for every standalone child test file
41
- def test_tasks
42
- # get immediate child test files
43
- Dir.glob("#{@path}/*#{self.class.test_file_suffix}").collect do |f|
44
- # get just the path name for each file
45
- File.join(File.dirname(f), File.basename(f, self.class.test_file_suffix))
46
- end.reject do |p|
56
+
57
+ def build_test_tasks
58
+ self.class.test_file_suffixes.map do |suffix|
59
+ # get immediate child test files
60
+ Dir.glob("#{@path}/*#{suffix}").collect do |f|
61
+ # get just the path name for each file
62
+ File.join(File.dirname(f), File.basename(f, suffix))
63
+ end
64
+ end.flatten.reject do |p|
47
65
  # reject any that have deeply nested test files
48
- !Dir.glob("#{p}/**/*#{self.class.test_file_suffix}").empty?
66
+ self.class.test_file_suffixes.inject(false) do |result, suffix|
67
+ result || !Dir.glob("#{p}/**/*#{suffix}").empty?
68
+ end
49
69
  end.collect do |p|
50
70
  # build a test task for the standalone test file of the path
51
71
  TestTask.new(p) do |tt|
52
- tt.files = Rake::FileList[p+self.class.test_file_suffix]
72
+ tt.files = self.class.test_file_suffixes.map do |suffix|
73
+ (File.exists?("#{p}#{suffix}") ? Rake::FileList["#{p}#{suffix}"] : [])
74
+ end.flatten
53
75
  end
54
76
  end
55
77
  end
56
78
 
57
79
  # a collection of scopes for every child test dir or test dir/file combo
58
- def scopes
59
- # get immediate child paths
60
- Dir.glob("#{@path}/*").collect do |p|
61
- # get just the path name for each dir/file and uniq it
62
- File.join(File.dirname(p), File.basename(p, self.class.test_file_suffix))
63
- end.uniq.select do |p|
80
+
81
+ def build_scopes
82
+ self.class.test_file_suffixes.map do |suffix|
83
+ # get immediate child paths
84
+ Dir.glob("#{@path}/*").collect do |p|
85
+ # get just the path name for each dir/file and uniq it
86
+ File.join(File.dirname(p), File.basename(p, suffix))
87
+ end
88
+ end.flatten.uniq.select do |p|
64
89
  # select any that have deeply nested test files
65
- !Dir.glob("#{p}/**/*#{self.class.test_file_suffix}").empty?
90
+ self.class.test_file_suffixes.inject(false) do |result, suffix|
91
+ result || !Dir.glob("#{p}/**/*#{suffix}").empty?
92
+ end
66
93
  end.collect do |p|
67
94
  # build a scope for each path
68
95
  self.class.new(p)
@@ -26,7 +26,10 @@ module Assert::RakeTasks
26
26
  end
27
27
 
28
28
  def name
29
- File.basename(@path, Scope.test_file_suffix).to_sym
29
+ # File.basename(@path, Scope.test_file_suffix).to_sym
30
+ @name ||= File.basename(@path).tap do |bname|
31
+ Scope.test_file_suffixes.each { |suffix| bname.gsub(suffix, '') }
32
+ end.to_sym
30
33
  end
31
34
 
32
35
  def file_list # :nodoc:
@@ -8,15 +8,13 @@ module Assert::Result
8
8
  class Error < Base; end
9
9
  class Skip < Base; end
10
10
 
11
- class << self
12
- def types
13
- { :pass => Pass,
14
- :fail => Fail,
15
- :ignore => Ignore,
16
- :skip => Skip,
17
- :error => Error
18
- }
19
- end
11
+ def self.types
12
+ { :pass => Pass,
13
+ :fail => Fail,
14
+ :ignore => Ignore,
15
+ :skip => Skip,
16
+ :error => Error
17
+ }
20
18
  end
21
19
 
22
20
  class Backtrace < ::Array
@@ -1,13 +1,16 @@
1
1
  module Assert
2
2
  class ResultSet < ::Array
3
3
 
4
- attr_accessor :view
4
+ attr_accessor :callback
5
+
6
+ def initialize(callback=nil)
7
+ @callback = callback
8
+ super()
9
+ end
5
10
 
6
11
  def <<(result)
7
12
  super
8
- if @view && @view.respond_to?(:handle_runtime_result)
9
- @view.handle_runtime_result(result)
10
- end
13
+ @callback.call(result) if @callback
11
14
  end
12
15
 
13
16
  end
@@ -9,19 +9,15 @@ module Assert
9
9
  @view = view
10
10
  end
11
11
 
12
- def run(render=true)
12
+ def run
13
+ @view.fire(:on_start)
13
14
  @suite.setup
14
15
 
15
- if render
16
- # render the view, passing it a callback block to run the test suite
17
- @view.render do
18
- benchmark { run_suite }
19
- end
20
- else
21
- benchmark { run_suite }
22
- end
16
+ benchmark { run_suite }
23
17
 
24
18
  @suite.teardown
19
+ @view.fire(:on_finish)
20
+
25
21
  count(:failed) + count(:errored)
26
22
  end
27
23
 
@@ -48,7 +44,11 @@ module Assert
48
44
 
49
45
  def run_suite
50
46
  # TODO: parallel running
51
- tests_to_run.each {|test| test.run(@view)}
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
52
52
  end
53
53
 
54
54
  end
@@ -8,9 +8,10 @@ module Assert
8
8
  # the user-specific helper file will always be required in after the
9
9
  # package-specific one
10
10
 
11
- class << self
11
+ USER_TEST_DIR = './.assert'
12
+ USER_TEST_HELPER = 'options'
12
13
 
13
- USER_TEST_HELPER = "./.assert/options"
14
+ class << self
14
15
 
15
16
  # assume the test dir path is ./test and look for helpers in ./test/helper.rb
16
17
  def package_test_dir
@@ -34,7 +35,8 @@ module Assert
34
35
 
35
36
  def require_user_test_helper
36
37
  if ENV['HOME']
37
- safe_require File.expand_path(USER_TEST_HELPER, ENV['HOME'])
38
+ helper_path = File.join(USER_TEST_DIR, USER_TEST_HELPER)
39
+ safe_require File.expand_path(helper_path, ENV['HOME'])
38
40
  end
39
41
  end
40
42
 
@@ -2,13 +2,12 @@ require 'assert/options'
2
2
  require 'assert/runner'
3
3
 
4
4
  module Assert
5
+
5
6
  # Setup the default global runner for running tests
6
7
  options do
7
8
  default_runner Runner
8
9
  end
9
10
 
10
- class << self
11
- def runner; self.options.runner; end
12
- end
11
+ def self.runner; self.options.runner; end
13
12
 
14
13
  end
@@ -2,15 +2,12 @@ require 'assert/context'
2
2
  require 'assert/suite'
3
3
 
4
4
  module Assert
5
+
5
6
  # Setup the default global suite for collecting tests as contexts are defined
6
7
  options do
7
8
  default_suite Suite.new
8
9
  end
9
10
 
10
- class << self
11
- def suite
12
- self.options.suite
13
- end
14
- end
11
+ def self.suite; self.options.suite; end
15
12
 
16
13
  end
@@ -1,3 +1,4 @@
1
+ require 'assert/setup/helpers'
1
2
  require 'assert/view/default_view'
2
3
 
3
4
  module Assert
@@ -8,9 +9,31 @@ module Assert
8
9
  default_view View::DefaultView.new($stdout)
9
10
  end
10
11
 
11
- # setup the global Assert.view method
12
- class << self
13
- def view; self.options.view; end
12
+ def self.view; self.options.view; end
13
+
14
+ module View
15
+
16
+ # this method is used to bring in custom user-specific views
17
+ # require views by passing either a full path to the view ruby file
18
+ # or passing the name of a view installed in ~/.assert/views
19
+
20
+ def self.require_user_view(view)
21
+ user_test_root = File.expand_path(Assert::Helpers::USER_TEST_DIR, ENV['HOME'])
22
+ views_file = File.join(user_test_root, 'views', view, 'lib', view)
23
+
24
+ if File.exists?(view) || File.exists?(view+'.rb')
25
+ require view
26
+ elsif ENV['HOME'] && File.exists?(views_file+'.rb')
27
+ require views_file
28
+ else
29
+ msg = "[WARN] Can't find or require #{view.inspect} view."
30
+ if !view.match(/\A\//)
31
+ msg << " Did you install it in `~/.assert/views`?"
32
+ end
33
+ warn msg
34
+ end
35
+ end
36
+
14
37
  end
15
38
 
16
39
  end
@@ -34,44 +34,29 @@ module Assert
34
34
  self.context_info.klass
35
35
  end
36
36
 
37
- def run(view=nil)
38
- @results.view = view
37
+ def run(&result_callback)
38
+ # setup the a new test run
39
+ @results = ResultSet.new(result_callback)
39
40
  run_scope = self.context_class.new(self)
40
- capture_output(StringIO.new(@output, "w+")) do
41
+
42
+ # run the test, capturing its output
43
+ begin
44
+ run_test_setup(run_scope)
45
+ run_test_code(run_scope)
46
+ rescue Result::TestFailure => err
47
+ @results << Result::Fail.new(self, err)
48
+ rescue Result::TestSkipped => err
49
+ @results << Result::Skip.new(self, err)
50
+ rescue Exception => err
51
+ @results << Result::Error.new(self, err)
52
+ ensure
41
53
  begin
42
- # run any assert style 'setup do' setups
43
- self.context_class.setup(run_scope)
44
- # run any classic test/unit style 'def setup' setups
45
- if run_scope.respond_to?(:setup)
46
- run_scope.setup
47
- end
48
-
49
- # run the actual test code
50
- if @code.kind_of?(::Proc)
51
- run_scope.instance_eval(&@code)
52
- elsif run_scope.respond_to?(@code.to_s)
53
- run_scope.send(@code.to_s)
54
- end
55
- rescue Result::TestFailure => err
56
- @results << Result::Fail.new(self, err)
57
- rescue Result::TestSkipped => err
58
- @results << Result::Skip.new(self, err)
59
- rescue Exception => err
60
- @results << Result::Error.new(self, err)
61
- ensure
62
- begin
63
- # run any classic test/unit style 'def teardown' teardowns
64
- if run_scope.respond_to?(:teardown)
65
- run_scope.teardown
66
- end
67
- # run any assert style 'teardown do' teardowns
68
- self.context_class.teardown(run_scope)
69
- rescue Exception => teardown_err
70
- @results << Result::Error.new(self, teardown_err)
71
- end
54
+ run_test_teardown(run_scope)
55
+ rescue Exception => teardown_err
56
+ @results << Result::Error.new(self, teardown_err)
72
57
  end
73
58
  end
74
- @results.view = nil
59
+ # return the results of the test run
75
60
  @results
76
61
  end
77
62
 
@@ -102,10 +87,40 @@ module Assert
102
87
 
103
88
  protected
104
89
 
105
- def capture_output(io, &block)
106
- if self.class.options.capture_output && io
90
+ def run_test_setup(scope)
91
+ capture_output do
92
+ # run any assert style 'setup do' setups
93
+ self.context_class.setup(scope)
94
+
95
+ # run any classic test/unit style 'def setup' setups
96
+ scope.setup if scope.respond_to?(:setup)
97
+ end
98
+ end
99
+
100
+ def run_test_code(scope)
101
+ capture_output do
102
+ if @code.kind_of?(::Proc)
103
+ scope.instance_eval(&@code)
104
+ elsif scope.respond_to?(@code.to_s)
105
+ scope.send(@code.to_s)
106
+ end
107
+ end
108
+ end
109
+
110
+ def run_test_teardown(scope)
111
+ capture_output do
112
+ # run any classic test/unit style 'def teardown' teardowns
113
+ scope.teardown if scope.respond_to?(:teardown)
114
+
115
+ # run any assert style 'teardown do' teardowns
116
+ self.context_class.teardown(scope)
117
+ end
118
+ end
119
+
120
+ def capture_output(&block)
121
+ if self.class.options.capture_output
107
122
  orig_stdout = $stdout.clone
108
- $stdout = io
123
+ $stdout = capture_io
109
124
  block.call
110
125
  $stdout = orig_stdout
111
126
  else
@@ -113,6 +128,10 @@ module Assert
113
128
  end
114
129
  end
115
130
 
131
+ def capture_io
132
+ StringIO.new(@output, "a+")
133
+ end
134
+
116
135
  def name_from_context(name)
117
136
  [ self.context_class.description,
118
137
  name