test-belt 0.2.1 → 1.0.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 +2 -1
- data/Gemfile.lock +23 -0
- data/lib/test_belt/callbacks.rb +22 -0
- data/lib/test_belt/callbacks/case.rb +86 -0
- data/lib/test_belt/callbacks/suite.rb +106 -0
- data/lib/test_belt/callbacks/test.rb +58 -0
- data/lib/test_belt/context.rb +40 -0
- data/lib/test_belt/default_test.rb +18 -0
- data/lib/test_belt/helper.rb +24 -3
- data/lib/test_belt/matchers.rb +29 -0
- data/lib/test_belt/matchers/base.rb +21 -0
- data/lib/test_belt/matchers/have_accessors.rb +23 -0
- data/lib/test_belt/matchers/have_class_methods.rb +40 -0
- data/lib/test_belt/matchers/have_files.rb +38 -0
- data/lib/test_belt/matchers/have_instance_methods.rb +44 -0
- data/lib/test_belt/matchers/have_readers.rb +26 -0
- data/lib/test_belt/matchers/have_writers.rb +30 -0
- data/lib/test_belt/should.rb +76 -0
- data/lib/test_belt/skip.rb +41 -0
- data/lib/test_belt/subject.rb +47 -0
- data/lib/test_belt/version.rb +1 -1
- data/test/callbacks_test.rb +172 -0
- data/test/fixtures/{shoulda_macros/thing.rb → thing.rb} +0 -0
- data/test/helpers_test.rb +175 -0
- data/test/matchers_test.rb +135 -0
- data/test/rake_tasks_test.rb +8 -17
- metadata +33 -31
- data/lib/test_belt/shoulda_macros.rb +0 -9
- data/lib/test_belt/shoulda_macros/classes.rb +0 -105
- data/lib/test_belt/shoulda_macros/context.rb +0 -25
- data/lib/test_belt/shoulda_macros/files.rb +0 -49
- data/lib/test_belt/test_unit.rb +0 -8
- data/lib/test_belt/test_unit/context.rb +0 -71
- data/lib/test_belt/test_unit/runner.rb +0 -48
- data/lib/test_belt/test_unit/test_case.rb +0 -26
- data/test/shoulda_macros/classes_test.rb +0 -58
- data/test/shoulda_macros/context_test.rb +0 -28
- data/test/shoulda_macros/files_test.rb +0 -36
- data/test/test_unit/context_test.rb +0 -65
- data/test/test_unit/runner_test.rb +0 -31
- data/test/test_unit/test_case_test.rb +0 -30
data/.gitignore
CHANGED
data/Gemfile.lock
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
test-belt (1.0.0)
|
5
|
+
kelredd-useful (~> 0.4.0)
|
6
|
+
leftright (~> 0.9.0)
|
7
|
+
shoulda (~> 2.11)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: http://rubygems.org/
|
11
|
+
specs:
|
12
|
+
json (1.5.1)
|
13
|
+
kelredd-useful (0.4.1)
|
14
|
+
json
|
15
|
+
leftright (0.9.1)
|
16
|
+
shoulda (2.11.3)
|
17
|
+
|
18
|
+
PLATFORMS
|
19
|
+
ruby
|
20
|
+
|
21
|
+
DEPENDENCIES
|
22
|
+
bundler (~> 1.0)
|
23
|
+
test-belt!
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'test_belt/callbacks/test'
|
2
|
+
require 'test_belt/callbacks/case'
|
3
|
+
require 'test_belt/callbacks/suite'
|
4
|
+
|
5
|
+
module TestBelt::Callbacks
|
6
|
+
|
7
|
+
# Test Belt adds callbacks for test cases, test case classes, and overall
|
8
|
+
# test suites. Use these callbacks to help setup/teardown your tests. All
|
9
|
+
# callbacks inherit to subclasses and are run in inheritance order. So, a
|
10
|
+
# superclass's callbacks run before and subclass callbacks. Test
|
11
|
+
# callbacks are run in the scope of the test case. Other callbacks are run
|
12
|
+
# outside the test case scope.
|
13
|
+
|
14
|
+
def self.included(receiving_test_class)
|
15
|
+
if receiving_test_class.ancestors.include?(::Test::Unit::TestCase)
|
16
|
+
receiving_test_class.send(:include, Test)
|
17
|
+
receiving_test_class.send(:include, Case)
|
18
|
+
receiving_test_class.send(:include, Suite)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module TestBelt::Callbacks
|
2
|
+
module Case
|
3
|
+
|
4
|
+
# Like their before/after brothers above, the _once callbacks run
|
5
|
+
# before/after tests respectively. The difference is that they only run
|
6
|
+
# once for the entire case. The before/setup callback will run before the
|
7
|
+
# first test for the class while the after/teardown callback will run after
|
8
|
+
# the last test for the class.
|
9
|
+
|
10
|
+
# Usage:
|
11
|
+
# class SomeTest < Test::Unit::TestCase
|
12
|
+
# include TestBelt::Callbacks::Case
|
13
|
+
#
|
14
|
+
# before_once {
|
15
|
+
# # anything here runs before the first test for this class
|
16
|
+
# }
|
17
|
+
# after_once {
|
18
|
+
# # anything here runs after the last test for this class
|
19
|
+
# }
|
20
|
+
#
|
21
|
+
# should 'do stuff' do
|
22
|
+
# assert true
|
23
|
+
# end
|
24
|
+
# end
|
25
|
+
|
26
|
+
|
27
|
+
def self.included(receiver)
|
28
|
+
receiver.send(:extend, ClassMethods)
|
29
|
+
end
|
30
|
+
|
31
|
+
module ClassMethods
|
32
|
+
def setup_once(&block)
|
33
|
+
raise ArgumentError, "please provide a setup block" unless block_given?
|
34
|
+
@_testbelt_once_setups ||= []
|
35
|
+
@_testbelt_once_setups << block
|
36
|
+
end
|
37
|
+
alias_method :before_once, :setup_once
|
38
|
+
|
39
|
+
def _testbelt_once_setups
|
40
|
+
((begin; superclass._testbelt_once_setups; rescue NoMethodError; []; end) || []) +
|
41
|
+
(@_testbelt_once_setups || [])
|
42
|
+
end
|
43
|
+
|
44
|
+
def teardown_once(&block)
|
45
|
+
raise ArgumentError, "please provide a teardown block" unless block_given?
|
46
|
+
@_testbelt_once_teardowns ||= []
|
47
|
+
@_testbelt_once_teardowns << block
|
48
|
+
end
|
49
|
+
alias_method :after_once, :teardown_once
|
50
|
+
|
51
|
+
def _testbelt_once_teardowns
|
52
|
+
((begin; superclass._testbelt_once_teardowns; rescue NoMethodError; []; end) || []) +
|
53
|
+
(@_testbelt_once_teardowns || [])
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
module Test::Unit
|
61
|
+
class TestSuite
|
62
|
+
# override the TestSuite with TestCase callbacks
|
63
|
+
alias_method :run_without_testbelt_callbacks, :run
|
64
|
+
|
65
|
+
def run(*args, &block) # :nodoc:
|
66
|
+
if( !tests.empty? &&
|
67
|
+
(testclass = tests.first).kind_of?(::Test::Unit::TestCase) &&
|
68
|
+
testclass.class.ancestors.include?(::TestBelt::Callbacks::Case)
|
69
|
+
)
|
70
|
+
tests.first.class._testbelt_once_setups.each do |callback|
|
71
|
+
callback.call
|
72
|
+
end
|
73
|
+
end
|
74
|
+
run_without_testbelt_callbacks *args, &block
|
75
|
+
if( !tests.empty? &&
|
76
|
+
(testclass = tests.first).kind_of?(::Test::Unit::TestCase) &&
|
77
|
+
testclass.class.ancestors.include?(::TestBelt::Callbacks::Case)
|
78
|
+
)
|
79
|
+
tests.first.class._testbelt_once_teardowns.reverse.each do |callback|
|
80
|
+
callback.call
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
module TestBelt::Callbacks
|
2
|
+
module Suite
|
3
|
+
|
4
|
+
# Again, similar to the before/after callbacks above, the started/finished
|
5
|
+
# callbacks run before/after tests respectively. The difference is that
|
6
|
+
# these callbacks run only once for the entire suite of tests (across all
|
7
|
+
# test cases). The suite_started/on_suite_started callbacks run before the
|
8
|
+
# first test run in the suite of tests. The suite_finished/on_suite_finished
|
9
|
+
# callbacks run after the last test run in the suite of tests.
|
10
|
+
|
11
|
+
# Usage:
|
12
|
+
# class SomeTest < Test::Unit::TestCase
|
13
|
+
# include TestBelt::Callbacks::Suite
|
14
|
+
#
|
15
|
+
# suite_started {
|
16
|
+
# # anything here runs before the first test for the suite of tests
|
17
|
+
# }
|
18
|
+
# suite_finished {
|
19
|
+
# # anything here runs after the last test for the suite of tests
|
20
|
+
# }
|
21
|
+
#
|
22
|
+
# should 'do stuff' do
|
23
|
+
# assert true
|
24
|
+
# end
|
25
|
+
# end
|
26
|
+
|
27
|
+
|
28
|
+
def self.included(receiver)
|
29
|
+
if !::Test::Unit::TestCase.respond_to?(:suite_started)
|
30
|
+
::Test::Unit::TestCase.send(:extend, ClassMethods)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
module ClassMethods
|
35
|
+
def suite_started(&block)
|
36
|
+
raise ArgumentError, "please provide a started block" unless block_given?
|
37
|
+
::Test::Unit::TestCase._testbelt_started_callbacks ||= []
|
38
|
+
::Test::Unit::TestCase._testbelt_started_callbacks << block
|
39
|
+
end
|
40
|
+
alias_method :on_suite_started, :suite_started
|
41
|
+
|
42
|
+
def _testbelt_started_callbacks
|
43
|
+
@_testbelt_started_callbacks ||= []
|
44
|
+
end
|
45
|
+
|
46
|
+
def suite_finished(&block)
|
47
|
+
raise ArgumentError, "please provide a finished block" unless block_given?
|
48
|
+
::Test::Unit::TestCase._testbelt_finished_callbacks ||= []
|
49
|
+
::Test::Unit::TestCase._testbelt_finished_callbacks << block
|
50
|
+
end
|
51
|
+
alias_method :on_suite_finished, :suite_finished
|
52
|
+
|
53
|
+
def _testbelt_finished_callbacks
|
54
|
+
@_testbelt_finished_callbacks ||= []
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
require 'test/unit/ui/console/testrunner'
|
62
|
+
|
63
|
+
module TestBelt::Callbacks
|
64
|
+
|
65
|
+
if defined? ::LeftRight::Runner
|
66
|
+
class Runner < ::LeftRight::Runner; end
|
67
|
+
else
|
68
|
+
class Runner < ::Test::Unit::UI::Console::TestRunner; end
|
69
|
+
end
|
70
|
+
|
71
|
+
class Runner
|
72
|
+
def started(*args)
|
73
|
+
super
|
74
|
+
if ::Test::Unit::TestCase.respond_to?(:suite_started)
|
75
|
+
::Test::Unit::TestCase._testbelt_started_callbacks.each do |callback|
|
76
|
+
callback.call
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def finished(*args)
|
82
|
+
if ::Test::Unit::TestCase.respond_to?(:suite_finished)
|
83
|
+
::Test::Unit::TestCase._testbelt_finished_callbacks.reverse.each do |callback|
|
84
|
+
callback.call
|
85
|
+
end
|
86
|
+
end
|
87
|
+
super
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
module Test::Unit
|
94
|
+
|
95
|
+
# override the AutoRunner's runner to use TestBelt's
|
96
|
+
# with callback for suite started/finished
|
97
|
+
class AutoRunner
|
98
|
+
alias_method :initialize_without_testbelt_runner, :initialize
|
99
|
+
|
100
|
+
def initialize(*args)
|
101
|
+
initialize_without_testbelt_runner *args
|
102
|
+
@runner = lambda { |r| ::TestBelt::Callbacks::Runner }
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module TestBelt::Callbacks
|
2
|
+
module Test
|
3
|
+
|
4
|
+
# Test before/setup callbacks run before each test in the test case class.
|
5
|
+
# The after/teardown callbacks run after each test in the test case class.
|
6
|
+
# Each pair does identical logic - they are just an alias of each other so
|
7
|
+
# use what reads better to you.
|
8
|
+
|
9
|
+
# Usage:
|
10
|
+
# <pre>
|
11
|
+
# class SomeTest < Test::Unit::TestCase
|
12
|
+
# include TestBelt::Callbacks::Test
|
13
|
+
#
|
14
|
+
# before {
|
15
|
+
# # anything here runs before each test
|
16
|
+
# }
|
17
|
+
# after {
|
18
|
+
# # anything here runs after each test
|
19
|
+
# }
|
20
|
+
#
|
21
|
+
# should 'do stuff' do
|
22
|
+
# assert true
|
23
|
+
# end
|
24
|
+
# end
|
25
|
+
# </pre>
|
26
|
+
|
27
|
+
def self.included(receiver)
|
28
|
+
receiver.send(:extend, ClassMethods)
|
29
|
+
end
|
30
|
+
|
31
|
+
module ClassMethods
|
32
|
+
def setup(&block)
|
33
|
+
raise ArgumentError, "please provide a setup block" unless block_given?
|
34
|
+
@_testbelt_setups ||= []
|
35
|
+
@_testbelt_setups << block
|
36
|
+
end
|
37
|
+
alias_method :before, :setup
|
38
|
+
|
39
|
+
def _testbelt_setups
|
40
|
+
((begin; superclass._testbelt_setups; rescue NoMethodError; []; end) || []) +
|
41
|
+
(@_testbelt_setups || [])
|
42
|
+
end
|
43
|
+
|
44
|
+
def teardown(&block)
|
45
|
+
raise ArgumentError, "please provide a teardown block" unless block_given?
|
46
|
+
@_testbelt_teardowns ||= []
|
47
|
+
@_testbelt_teardowns << block
|
48
|
+
end
|
49
|
+
alias_method :after, :teardown
|
50
|
+
|
51
|
+
def _testbelt_teardowns
|
52
|
+
((begin; superclass._testbelt_teardowns; rescue NoMethodError; []; end) || []) +
|
53
|
+
(@_testbelt_teardowns || [])
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module TestBelt
|
2
|
+
module Context
|
3
|
+
|
4
|
+
# This provides a 'context' method on a TestCase. Use this method
|
5
|
+
# to describe the context the TestCase is running in. This may be
|
6
|
+
# a description of the subject or whatever you want. The context
|
7
|
+
# value will be added to the test name of any tests defined using
|
8
|
+
# the 'should' method provided by should.rb. Context descriptions
|
9
|
+
# are nested as TestCases are sub-classed.
|
10
|
+
|
11
|
+
# Usage:
|
12
|
+
# class SomeTest < Test::Unit::TestCase
|
13
|
+
# include TestBelt::Context
|
14
|
+
# end
|
15
|
+
|
16
|
+
def self.included(receiver)
|
17
|
+
receiver.send(:extend, ClassMethods)
|
18
|
+
receiver.send(:include, InstanceMethods)
|
19
|
+
end
|
20
|
+
|
21
|
+
module ClassMethods
|
22
|
+
def context(desc)
|
23
|
+
raise ArgumentError, "no context description provided" if desc.nil?
|
24
|
+
@_testbelt_contexts = [desc]
|
25
|
+
end
|
26
|
+
|
27
|
+
def _testbelt_contexts
|
28
|
+
((begin; superclass._testbelt_contexts; rescue NoMethodError; []; end) || []) +
|
29
|
+
(@_testbelt_contexts || [])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
module InstanceMethods
|
34
|
+
def context
|
35
|
+
self.class._testbelt_contexts.join(' ')
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module TestBelt
|
2
|
+
module DefaultTest
|
3
|
+
|
4
|
+
# This overrides the TestCase default_test behavior. When running
|
5
|
+
# a TestCase, the 'default_test' method is called if no 'test_*'
|
6
|
+
# methods are defined. The standard method always flunks saying
|
7
|
+
# 'no tests defined' or whatever. This overrides the standard
|
8
|
+
# method so it won't flunk and you can inherit TestCases freely.
|
9
|
+
|
10
|
+
# Usage:
|
11
|
+
# class SomeTest < Test::Unit::TestCase
|
12
|
+
# include TestBelt::DefaultTest
|
13
|
+
# end
|
14
|
+
|
15
|
+
def default_test; end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
data/lib/test_belt/helper.rb
CHANGED
@@ -1,6 +1,27 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'test/unit'
|
3
3
|
require 'leftright'
|
4
|
-
|
5
|
-
require 'test_belt/
|
6
|
-
require 'test_belt/
|
4
|
+
|
5
|
+
require 'test_belt/default_test'
|
6
|
+
require 'test_belt/should'
|
7
|
+
require 'test_belt/context'
|
8
|
+
require 'test_belt/subject'
|
9
|
+
require 'test_belt/skip'
|
10
|
+
require 'test_belt/callbacks'
|
11
|
+
require 'test_belt/matchers'
|
12
|
+
|
13
|
+
module TestBelt
|
14
|
+
|
15
|
+
def self.included(receiving_test_class)
|
16
|
+
if receiving_test_class.ancestors.include?(::Test::Unit::TestCase)
|
17
|
+
receiving_test_class.send(:include, DefaultTest)
|
18
|
+
receiving_test_class.send(:extend, Should)
|
19
|
+
receiving_test_class.send(:include, Context)
|
20
|
+
receiving_test_class.send(:include, Subject)
|
21
|
+
receiving_test_class.send(:include, Skip)
|
22
|
+
receiving_test_class.send(:include, Callbacks)
|
23
|
+
receiving_test_class.send(:include, Matchers)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'test_belt/matchers/base'
|
2
|
+
require 'test_belt/matchers/have_instance_methods'
|
3
|
+
require 'test_belt/matchers/have_class_methods'
|
4
|
+
require 'test_belt/matchers/have_readers'
|
5
|
+
require 'test_belt/matchers/have_writers'
|
6
|
+
require 'test_belt/matchers/have_accessors'
|
7
|
+
require 'test_belt/matchers/have_files'
|
8
|
+
|
9
|
+
module TestBelt::Matchers
|
10
|
+
|
11
|
+
# Test Belt provides matchers to test common scenarios. Use these matchers
|
12
|
+
# in combination with the 'should' method to run common test cases.
|
13
|
+
|
14
|
+
def self.included(receiving_test_class)
|
15
|
+
if receiving_test_class.ancestors.include?(::Test::Unit::TestCase)
|
16
|
+
receiving_test_class.send(:include, HaveInstanceMethods)
|
17
|
+
receiving_test_class.send(:include, HaveClassMethods)
|
18
|
+
receiving_test_class.send(:include, HaveReaders)
|
19
|
+
receiving_test_class.send(:include, HaveWriters)
|
20
|
+
receiving_test_class.send(:include, HaveAccessors)
|
21
|
+
receiving_test_class.send(:include, HaveFiles)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def assert_matcher(matcher)
|
26
|
+
assert_block(matcher.fail_message) { matcher.matches?(subject) }
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module TestBelt::Matchers
|
2
|
+
|
3
|
+
# Test Belt provides matchers to test common scenarios. Use these matchers
|
4
|
+
# in combination with the 'should' method to run common test cases. All
|
5
|
+
# matchers should subclass this base class.
|
6
|
+
|
7
|
+
class Base
|
8
|
+
def desc
|
9
|
+
raise NotImplementedError, "no description provided for the matcher"
|
10
|
+
end
|
11
|
+
|
12
|
+
def matches?(*args)
|
13
|
+
raise NotImplementedError, "no matches? test logic provided for the matcher"
|
14
|
+
end
|
15
|
+
|
16
|
+
def fail_message
|
17
|
+
raise NotImplementedError, "no fail message provided for the matcher"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|