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.
- data/.gitignore +16 -4
- data/{CHANGELOG.rdoc → CHANGELOG.md} +14 -3
- data/LICENSE +22 -0
- data/README.md +261 -0
- data/Rakefile +1 -1
- data/assert.gemspec +2 -1
- data/lib/assert/assertions.rb +16 -0
- data/lib/assert/autorun.rb +11 -7
- data/lib/assert/macros/methods.rb +49 -3
- data/lib/assert/rake_tasks.rb +13 -7
- data/lib/assert/rake_tasks/irb.rb +1 -1
- data/lib/assert/rake_tasks/scope.rb +55 -28
- data/lib/assert/rake_tasks/test_task.rb +4 -1
- data/lib/assert/result.rb +7 -9
- data/lib/assert/result_set.rb +7 -4
- data/lib/assert/runner.rb +10 -10
- data/lib/assert/setup/helpers.rb +5 -3
- data/lib/assert/setup/runner.rb +2 -3
- data/lib/assert/setup/suite.rb +2 -5
- data/lib/assert/setup/view.rb +26 -3
- data/lib/assert/test.rb +56 -37
- data/lib/assert/version.rb +1 -1
- data/lib/assert/view/base.rb +75 -0
- data/lib/assert/view/default_view.rb +75 -0
- data/lib/assert/view/helpers/ansi_styles.rb +25 -0
- data/lib/assert/view/helpers/capture_output.rb +23 -0
- data/lib/assert/view/helpers/common.rb +154 -0
- data/test/assertions/assert_file_exists_test.rb +43 -0
- data/test/assertions/assert_not_file_exists_test.rb +43 -0
- data/test/assertions_test.rb +4 -1
- data/test/macro_test.rb +25 -0
- data/test/rake_tasks/irb_test.rb +2 -2
- data/test/rake_tasks/scope_test.rb +9 -9
- data/test/result_set_test.rb +13 -23
- data/test/runner_test.rb +1 -1
- data/test/test/{running_test.rb → running_tests.rb} +14 -14
- data/test/view/base_tests.rb +65 -0
- metadata +29 -18
- data/Gemfile.lock +0 -23
- data/README.rdoc +0 -183
data/lib/assert/rake_tasks.rb
CHANGED
@@ -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-
|
18
|
-
self.
|
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(
|
22
|
-
|
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
|
@@ -4,29 +4,25 @@ require 'assert/rake_tasks/test_task'
|
|
4
4
|
module Assert::RakeTasks
|
5
5
|
class Scope
|
6
6
|
|
7
|
-
def self.
|
8
|
-
|
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
|
-
|
42
|
-
|
43
|
-
|
44
|
-
# get
|
45
|
-
|
46
|
-
|
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
|
-
|
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 =
|
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
|
-
|
59
|
-
|
60
|
-
|
61
|
-
# get
|
62
|
-
|
63
|
-
|
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
|
-
|
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:
|
data/lib/assert/result.rb
CHANGED
@@ -8,15 +8,13 @@ module Assert::Result
|
|
8
8
|
class Error < Base; end
|
9
9
|
class Skip < Base; end
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
data/lib/assert/result_set.rb
CHANGED
@@ -1,13 +1,16 @@
|
|
1
1
|
module Assert
|
2
2
|
class ResultSet < ::Array
|
3
3
|
|
4
|
-
attr_accessor :
|
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
|
-
|
9
|
-
@view.handle_runtime_result(result)
|
10
|
-
end
|
13
|
+
@callback.call(result) if @callback
|
11
14
|
end
|
12
15
|
|
13
16
|
end
|
data/lib/assert/runner.rb
CHANGED
@@ -9,19 +9,15 @@ module Assert
|
|
9
9
|
@view = view
|
10
10
|
end
|
11
11
|
|
12
|
-
def run
|
12
|
+
def run
|
13
|
+
@view.fire(:on_start)
|
13
14
|
@suite.setup
|
14
15
|
|
15
|
-
|
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
|
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
|
data/lib/assert/setup/helpers.rb
CHANGED
@@ -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
|
-
|
11
|
+
USER_TEST_DIR = './.assert'
|
12
|
+
USER_TEST_HELPER = 'options'
|
12
13
|
|
13
|
-
|
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
|
-
|
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
|
|
data/lib/assert/setup/runner.rb
CHANGED
@@ -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
|
-
|
11
|
-
def runner; self.options.runner; end
|
12
|
-
end
|
11
|
+
def self.runner; self.options.runner; end
|
13
12
|
|
14
13
|
end
|
data/lib/assert/setup/suite.rb
CHANGED
@@ -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
|
-
|
11
|
-
def suite
|
12
|
-
self.options.suite
|
13
|
-
end
|
14
|
-
end
|
11
|
+
def self.suite; self.options.suite; end
|
15
12
|
|
16
13
|
end
|
data/lib/assert/setup/view.rb
CHANGED
@@ -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
|
-
|
12
|
-
|
13
|
-
|
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
|
data/lib/assert/test.rb
CHANGED
@@ -34,44 +34,29 @@ module Assert
|
|
34
34
|
self.context_info.klass
|
35
35
|
end
|
36
36
|
|
37
|
-
def run(
|
38
|
-
|
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
|
-
|
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
|
-
|
43
|
-
|
44
|
-
|
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
|
-
|
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
|
106
|
-
|
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 =
|
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
|