assert 0.1.0 → 0.2.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/Gemfile.lock +3 -1
- data/README.rdoc +6 -6
- data/Rakefile +2 -3
- data/assert.gemspec +1 -0
- data/lib/assert/assertions.rb +30 -30
- data/lib/assert/context.rb +71 -66
- data/lib/assert/macro.rb +14 -0
- data/lib/assert/macros/methods.rb +52 -0
- data/lib/assert/rake_tasks.rb +31 -13
- data/lib/assert/result.rb +12 -4
- data/lib/assert/result_set.rb +2 -2
- data/lib/assert/runner.rb +2 -6
- data/lib/assert/setup/autorun.rb +0 -1
- data/lib/assert/suite.rb +19 -15
- data/lib/assert/test.rb +6 -17
- data/lib/assert/version.rb +1 -1
- data/lib/assert/view/base.rb +1 -1
- data/lib/assert/view/terminal.rb +8 -30
- data/test/assertions/assert_block_test.rb +1 -1
- data/test/assertions/assert_empty_test.rb +43 -0
- data/test/assertions/assert_equal_test.rb +43 -0
- data/test/assertions/assert_includes_test.rb +44 -0
- data/test/assertions/assert_instance_of_test.rb +4 -4
- data/test/assertions/assert_kind_of_test.rb +3 -3
- data/test/assertions/assert_match_test.rb +43 -0
- data/test/assertions/assert_nil_test.rb +43 -0
- data/test/assertions/assert_not_block_test.rb +1 -1
- data/test/assertions/assert_not_empty_test.rb +43 -0
- data/test/assertions/assert_not_equal_test.rb +43 -0
- data/test/assertions/assert_not_included_test.rb +44 -0
- data/test/assertions/assert_not_instance_of_test.rb +4 -4
- data/test/assertions/assert_not_kind_of_test.rb +2 -2
- data/test/assertions/assert_not_match_test.rb +43 -0
- data/test/assertions/assert_not_nil_test.rb +43 -0
- data/test/assertions/assert_not_respond_to_test.rb +6 -6
- data/test/assertions/assert_not_same_test.rb +45 -0
- data/test/assertions/assert_respond_to_test.rb +6 -6
- data/test/assertions/assert_same_test.rb +45 -0
- data/test/assertions_test.rb +21 -298
- data/test/context/class_methods_test.rb +81 -112
- data/test/context_test.rb +35 -40
- data/test/helper.rb +5 -2
- data/test/irb.rb +2 -5
- data/test/macro_test.rb +99 -0
- data/test/options_test.rb +2 -2
- data/test/result_set_test.rb +47 -54
- data/test/result_test.rb +4 -17
- data/test/runner_test.rb +2 -10
- data/test/suite_test.rb +85 -13
- data/test/test/running_test.rb +19 -28
- data/test/test_test.rb +130 -128
- data/test/view_test.rb +3 -17
- metadata +50 -7
data/lib/assert/rake_tasks.rb
CHANGED
@@ -6,6 +6,26 @@ module Assert::RakeTasks
|
|
6
6
|
|
7
7
|
FILE_SUFFIX = "_test.rb"
|
8
8
|
|
9
|
+
# Setup the rake tasks for testing
|
10
|
+
# * add 'include Assert::RakeTasks' to your Rakefile
|
11
|
+
def self.included(receiver)
|
12
|
+
# get rid of rake warnings
|
13
|
+
if defined?(::Rake::DSL)
|
14
|
+
receiver.send :include, ::Rake::DSL
|
15
|
+
end
|
16
|
+
|
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))
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.for(test_namespace = :test)
|
22
|
+
self.irb_task(test_namespace.to_s)
|
23
|
+
self.to_tasks(test_namespace.to_s)
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
|
9
29
|
class TestTask < Rake::TaskLib
|
10
30
|
attr_accessor :name, :description, :test_files
|
11
31
|
|
@@ -46,11 +66,6 @@ module Assert::RakeTasks
|
|
46
66
|
end
|
47
67
|
|
48
68
|
class << self
|
49
|
-
def for(test_namespace = :test)
|
50
|
-
self.irb_task(test_namespace.to_s)
|
51
|
-
self.to_tasks(test_namespace.to_s)
|
52
|
-
end
|
53
|
-
|
54
69
|
def irb_task(path)
|
55
70
|
irb_file = File.join(path, "irb.rb")
|
56
71
|
if File.exist?(irb_file)
|
@@ -64,28 +79,31 @@ module Assert::RakeTasks
|
|
64
79
|
def to_tasks(path)
|
65
80
|
suite_name = File.basename(path)
|
66
81
|
|
67
|
-
# define a rake test task for all
|
82
|
+
# define a rake test task for all test files that have addional sub-folder tests
|
68
83
|
if !Dir.glob(File.join(path, "**/*#{FILE_SUFFIX}")).empty?
|
69
84
|
TestTask.new(suite_name.to_sym) do |t|
|
70
85
|
file_location = suite_name == path ? '' : " for #{File.join(path.split(File::SEPARATOR)[1..-1])}"
|
71
86
|
t.description = "Run all tests#{file_location}"
|
72
|
-
t.test_files = FileList["#{path}/**/*#{FILE_SUFFIX}"]
|
87
|
+
t.test_files = (File.exists?(p = (path+FILE_SUFFIX)) ? FileList[p] : []) + FileList["#{path}/**/*#{FILE_SUFFIX}"]
|
73
88
|
end.to_task
|
74
89
|
end
|
75
90
|
|
76
91
|
namespace suite_name.to_s do
|
77
|
-
# define rake test tasks for each top-level test file individually
|
78
92
|
Dir.glob(File.join(path, "*#{FILE_SUFFIX}")).each do |test_file|
|
79
93
|
test_name = File.basename(test_file, FILE_SUFFIX)
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
94
|
+
|
95
|
+
# define rake test task for all test files without sub-folder tests
|
96
|
+
if Dir.glob(File.join(path, test_name, "*#{FILE_SUFFIX}")).empty?
|
97
|
+
TestTask.new(test_name.to_sym) do |t|
|
98
|
+
t.description = "Run tests for #{[path.split(File::SEPARATOR), test_name].flatten[1..-1].join(':')}"
|
99
|
+
t.test_files = FileList[test_file]
|
100
|
+
end.to_task
|
101
|
+
end
|
84
102
|
end
|
85
103
|
|
86
104
|
# recursively define rake test tasks for each file
|
87
105
|
# in each top-level directory
|
88
|
-
Dir.glob(File.join(path, "
|
106
|
+
Dir.glob(File.join(path, "*")).each do |test_dir|
|
89
107
|
self.to_tasks(test_dir)
|
90
108
|
end
|
91
109
|
end
|
data/lib/assert/result.rb
CHANGED
@@ -39,6 +39,7 @@ module Assert::Result
|
|
39
39
|
|
40
40
|
# './lib' in project dir, or '/usr/local/blahblah' if installed
|
41
41
|
ASSERT_DIR = File.dirname(File.dirname(file))
|
42
|
+
MACROS_DIR = File.join(File.dirname(file), 'macros')
|
42
43
|
|
43
44
|
def initialize(value=nil)
|
44
45
|
super(value || ["No backtrace"])
|
@@ -52,15 +53,22 @@ module Assert::Result
|
|
52
53
|
new_bt = []
|
53
54
|
|
54
55
|
self.each do |line|
|
55
|
-
break if line
|
56
|
+
break if filter_out?(line)
|
56
57
|
new_bt << line
|
57
58
|
end
|
58
59
|
|
59
|
-
new_bt = self.reject { |line| line
|
60
|
+
new_bt = self.reject { |line| filter_out?(line) } if new_bt.empty?
|
60
61
|
new_bt = self.dup if new_bt.empty?
|
61
62
|
|
62
63
|
self.class.new(new_bt)
|
63
64
|
end
|
65
|
+
|
66
|
+
protected
|
67
|
+
|
68
|
+
def filter_out?(line)
|
69
|
+
line.rindex(ASSERT_DIR, 0) && !line.rindex(MACROS_DIR, 0)
|
70
|
+
end
|
71
|
+
|
64
72
|
end
|
65
73
|
|
66
74
|
|
@@ -89,11 +97,11 @@ module Assert::Result
|
|
89
97
|
def trace
|
90
98
|
self.backtrace.filtered.first.to_s
|
91
99
|
end
|
92
|
-
|
100
|
+
|
93
101
|
def ==(other)
|
94
102
|
self.class == other.class && self.message == other.message
|
95
103
|
end
|
96
|
-
|
104
|
+
|
97
105
|
def inspect
|
98
106
|
"#<#{self.class} @message=#{self.message.inspect}>"
|
99
107
|
end
|
data/lib/assert/result_set.rb
CHANGED
data/lib/assert/runner.rb
CHANGED
@@ -12,15 +12,11 @@ module Assert
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def run(*args)
|
15
|
-
@suite.
|
16
|
-
setup.call
|
17
|
-
end
|
15
|
+
@suite.setup
|
18
16
|
@view.render do
|
19
17
|
benchmark { run_suite }
|
20
18
|
end
|
21
|
-
@suite.
|
22
|
-
teardown.call
|
23
|
-
end
|
19
|
+
@suite.teardown
|
24
20
|
count(:failed) + count(:errored)
|
25
21
|
end
|
26
22
|
|
data/lib/assert/setup/autorun.rb
CHANGED
data/lib/assert/suite.rb
CHANGED
@@ -6,7 +6,7 @@ module Assert
|
|
6
6
|
# A suite is a set of tests to run. When a test class subclasses
|
7
7
|
# the Context class, that test class is pushed to the suite.
|
8
8
|
|
9
|
-
attr_accessor :start_time, :end_time
|
9
|
+
attr_accessor :start_time, :end_time
|
10
10
|
|
11
11
|
def run_time
|
12
12
|
(@end_time || 0) - (@start_time || 0)
|
@@ -70,28 +70,32 @@ module Assert
|
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
|
-
def setup_blocks
|
74
|
-
@setup_blocks ||= []
|
75
|
-
end
|
76
|
-
|
77
|
-
def teardown_blocks
|
78
|
-
@teardown_blocks ||= []
|
79
|
-
end
|
80
|
-
|
81
|
-
# TODO: tests!
|
82
73
|
def setup(&block)
|
83
|
-
|
84
|
-
|
74
|
+
if block_given?
|
75
|
+
self.setups << block
|
76
|
+
else
|
77
|
+
self.setups.each{|setup| setup.call}
|
78
|
+
end
|
85
79
|
end
|
86
80
|
|
87
|
-
# TODO: tests!
|
88
81
|
def teardown(&block)
|
89
|
-
|
90
|
-
|
82
|
+
if block_given?
|
83
|
+
self.teardowns << block
|
84
|
+
else
|
85
|
+
self.teardowns.reverse.each{|teardown| teardown.call}
|
86
|
+
end
|
91
87
|
end
|
92
88
|
|
93
89
|
protected
|
94
90
|
|
91
|
+
def setups
|
92
|
+
@setups ||= []
|
93
|
+
end
|
94
|
+
|
95
|
+
def teardowns
|
96
|
+
@teardowns ||= []
|
97
|
+
end
|
98
|
+
|
95
99
|
def local_public_test_methods(klass)
|
96
100
|
methods = klass.public_instance_methods
|
97
101
|
while (klass.superclass)
|
data/lib/assert/test.rb
CHANGED
@@ -19,9 +19,9 @@ module Assert
|
|
19
19
|
|
20
20
|
def run(view=nil)
|
21
21
|
@results.view = view
|
22
|
+
run_scope = @context_class.new(self)
|
22
23
|
begin
|
23
|
-
|
24
|
-
run_setup(run_scope)
|
24
|
+
@context_class.setup(run_scope)
|
25
25
|
if @code.kind_of?(::Proc)
|
26
26
|
run_scope.instance_eval(&@code)
|
27
27
|
elsif run_scope.respond_to?(@code.to_s)
|
@@ -33,7 +33,7 @@ module Assert
|
|
33
33
|
@results << Result::Error.new(self.name, err)
|
34
34
|
ensure
|
35
35
|
begin
|
36
|
-
|
36
|
+
@context_class.teardown(run_scope)
|
37
37
|
rescue Exception => teardown_err
|
38
38
|
@results << Result::Error.new(self.name, teardown_err)
|
39
39
|
end
|
@@ -42,18 +42,6 @@ module Assert
|
|
42
42
|
@results
|
43
43
|
end
|
44
44
|
|
45
|
-
def run_setup(scope)
|
46
|
-
@context_class.all_setup_blocks.each do |setup|
|
47
|
-
scope.instance_eval(&setup)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def run_teardown(scope)
|
52
|
-
@context_class.all_teardown_blocks.each do |teardown|
|
53
|
-
scope.instance_eval(&teardown)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
45
|
Assert::Result.types.each do |name, klass|
|
58
46
|
define_method "#{name}_results" do
|
59
47
|
@results.select{|r| r.kind_of?(klass) }
|
@@ -82,8 +70,9 @@ module Assert
|
|
82
70
|
protected
|
83
71
|
|
84
72
|
def name_from_context(name)
|
85
|
-
|
86
|
-
|
73
|
+
[ @context_class.description,
|
74
|
+
name.gsub(/^test:\s+should/, "should")
|
75
|
+
].compact.reject{|p| p.empty?}.join(" ")
|
87
76
|
end
|
88
77
|
|
89
78
|
end
|
data/lib/assert/version.rb
CHANGED
data/lib/assert/view/base.rb
CHANGED
data/lib/assert/view/terminal.rb
CHANGED
@@ -1,32 +1,12 @@
|
|
1
1
|
require 'assert/view/base'
|
2
2
|
require 'assert/result'
|
3
3
|
|
4
|
+
require 'ansi/code'
|
5
|
+
|
4
6
|
module Assert::View
|
5
7
|
|
6
8
|
class Terminal < Base
|
7
9
|
|
8
|
-
TERM_STYLES = {
|
9
|
-
:reset => 0,
|
10
|
-
:bold => 1,
|
11
|
-
:underline => 4,
|
12
|
-
:black => 30,
|
13
|
-
:red => 31,
|
14
|
-
:green => 32,
|
15
|
-
:yellow => 33,
|
16
|
-
:blue => 34,
|
17
|
-
:magenta => 35,
|
18
|
-
:cyan => 36,
|
19
|
-
:white => 37,
|
20
|
-
:bgblack => 40,
|
21
|
-
:bgred => 41,
|
22
|
-
:bggreen => 42,
|
23
|
-
:bgyellow => 43,
|
24
|
-
:bgblue => 44,
|
25
|
-
:bgmagenta => 45,
|
26
|
-
:bgcyan => 46,
|
27
|
-
:bgwhite => 47
|
28
|
-
}
|
29
|
-
|
30
10
|
options do
|
31
11
|
default_styled false
|
32
12
|
default_passed_abbrev '.'
|
@@ -42,7 +22,7 @@ module Assert::View
|
|
42
22
|
end
|
43
23
|
|
44
24
|
def render(*args, &block)
|
45
|
-
self.
|
25
|
+
self.io_puts(:load_stmt)
|
46
26
|
|
47
27
|
if count(:tests) > 0
|
48
28
|
block.call if block
|
@@ -52,7 +32,7 @@ module Assert::View
|
|
52
32
|
self.io_puts(:results_stmt)
|
53
33
|
end
|
54
34
|
|
55
|
-
def
|
35
|
+
def handle_runtime_result(result)
|
56
36
|
sym = result.to_sym
|
57
37
|
self.io_print(result_io_msg(self.options.send("#{sym}_abbrev"), sym))
|
58
38
|
end
|
@@ -61,7 +41,7 @@ module Assert::View
|
|
61
41
|
|
62
42
|
def load_stmt
|
63
43
|
tplur = (tcount = count(:tests)) == 1 ? "test": "tests"
|
64
|
-
"\nLoaded suite (#{tcount} #{tplur})
|
44
|
+
"\nLoaded suite (#{tcount} #{tplur})"
|
65
45
|
end
|
66
46
|
|
67
47
|
def detailed_results
|
@@ -116,16 +96,14 @@ module Assert::View
|
|
116
96
|
def io_msg(msg, opts={})
|
117
97
|
val = super
|
118
98
|
if !(style = term_style(*opts[:term_styles])).empty?
|
119
|
-
val = style + val +
|
99
|
+
val = style + val + ANSI.send(:reset)
|
120
100
|
else
|
121
101
|
val
|
122
102
|
end
|
123
103
|
end
|
124
104
|
|
125
|
-
def term_style(*
|
126
|
-
|
127
|
-
TERM_STYLES.include?(style) ? "\e[#{TERM_STYLES[style]}m" : nil
|
128
|
-
end.join('')
|
105
|
+
def term_style(*ansi_codes)
|
106
|
+
ansi_codes.collect{|code| ANSI.send(code) rescue nil}.compact.join('')
|
129
107
|
end
|
130
108
|
|
131
109
|
def show_result_details?(result)
|
@@ -25,7 +25,7 @@ class Assert::Assertions::AssertBlockTest < Assert::Context
|
|
25
25
|
class FailMessageTest < AssertBlockTest
|
26
26
|
desc "with a failed result"
|
27
27
|
setup do
|
28
|
-
@expected = [ "Expected block to return true value."
|
28
|
+
@expected = [@fail_desc, "Expected block to return true value."].join("\n")
|
29
29
|
@fail_message = @test.fail_results.first.message
|
30
30
|
end
|
31
31
|
subject{ @fail_message }
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'assert'
|
2
|
+
|
3
|
+
class Assert::Assertions::AssertEmptyTest < Assert::Context
|
4
|
+
desc "the assert_empty helper run in a test"
|
5
|
+
setup do
|
6
|
+
fail_desc = @fail_desc = "assert empty fail desc"
|
7
|
+
fail_args = @fail_args = [ [ 1 ], fail_desc ]
|
8
|
+
@test = Factory.test do
|
9
|
+
assert_empty([]) # pass
|
10
|
+
assert_empty(*fail_args) # fail
|
11
|
+
end
|
12
|
+
@test.run
|
13
|
+
end
|
14
|
+
subject{ @test }
|
15
|
+
|
16
|
+
should "have 2 total results" do
|
17
|
+
assert_equal 2, subject.result_count
|
18
|
+
end
|
19
|
+
should "have 1 pass result" do
|
20
|
+
assert_equal 1, subject.result_count(:pass)
|
21
|
+
end
|
22
|
+
should "have 1 fail result" do
|
23
|
+
assert_equal 1, subject.result_count(:fail)
|
24
|
+
end
|
25
|
+
|
26
|
+
class FailMessageTest < AssertEmptyTest
|
27
|
+
desc "with a failed result"
|
28
|
+
setup do
|
29
|
+
@expected = [
|
30
|
+
@fail_args[1],
|
31
|
+
"Expected #{@fail_args[0].inspect} to be empty."
|
32
|
+
].join("\n")
|
33
|
+
@fail_message = @test.fail_results.first.message
|
34
|
+
end
|
35
|
+
subject{ @fail_message }
|
36
|
+
|
37
|
+
should "have a fail message with an explanation of what failed and my fail description" do
|
38
|
+
assert_equal @expected, subject
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'assert'
|
2
|
+
|
3
|
+
class Assert::Assertions::AssertEqualTest < Assert::Context
|
4
|
+
desc "the assert_equal helper run in a test"
|
5
|
+
setup do
|
6
|
+
fail_desc = @fail_desc = "assert equal fail desc"
|
7
|
+
fail_args = @fail_args = [ 1, 2, fail_desc ]
|
8
|
+
@test = Factory.test do
|
9
|
+
assert_equal(1, 1) # pass
|
10
|
+
assert_equal(*fail_args) # fail
|
11
|
+
end
|
12
|
+
@test.run
|
13
|
+
end
|
14
|
+
subject{ @test }
|
15
|
+
|
16
|
+
should "have 2 total results" do
|
17
|
+
assert_equal 2, subject.result_count
|
18
|
+
end
|
19
|
+
should "have 1 pass result" do
|
20
|
+
assert_equal 1, subject.result_count(:pass)
|
21
|
+
end
|
22
|
+
should "have 1 fail result" do
|
23
|
+
assert_equal 1, subject.result_count(:fail)
|
24
|
+
end
|
25
|
+
|
26
|
+
class FailMessageTest < AssertEqualTest
|
27
|
+
desc "with a failed result"
|
28
|
+
setup do
|
29
|
+
@expected = [
|
30
|
+
@fail_args[2],
|
31
|
+
"Expected #{@fail_args[0]}, not #{@fail_args[1]}."
|
32
|
+
].join("\n")
|
33
|
+
@fail_message = @test.fail_results.first.message
|
34
|
+
end
|
35
|
+
subject{ @fail_message }
|
36
|
+
|
37
|
+
should "have a fail message with an explanation of what failed and my fail description" do
|
38
|
+
assert_equal @expected, subject
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|