test-belt 0.2.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/.gitignore +2 -1
  2. data/Gemfile.lock +23 -0
  3. data/lib/test_belt/callbacks.rb +22 -0
  4. data/lib/test_belt/callbacks/case.rb +86 -0
  5. data/lib/test_belt/callbacks/suite.rb +106 -0
  6. data/lib/test_belt/callbacks/test.rb +58 -0
  7. data/lib/test_belt/context.rb +40 -0
  8. data/lib/test_belt/default_test.rb +18 -0
  9. data/lib/test_belt/helper.rb +24 -3
  10. data/lib/test_belt/matchers.rb +29 -0
  11. data/lib/test_belt/matchers/base.rb +21 -0
  12. data/lib/test_belt/matchers/have_accessors.rb +23 -0
  13. data/lib/test_belt/matchers/have_class_methods.rb +40 -0
  14. data/lib/test_belt/matchers/have_files.rb +38 -0
  15. data/lib/test_belt/matchers/have_instance_methods.rb +44 -0
  16. data/lib/test_belt/matchers/have_readers.rb +26 -0
  17. data/lib/test_belt/matchers/have_writers.rb +30 -0
  18. data/lib/test_belt/should.rb +76 -0
  19. data/lib/test_belt/skip.rb +41 -0
  20. data/lib/test_belt/subject.rb +47 -0
  21. data/lib/test_belt/version.rb +1 -1
  22. data/test/callbacks_test.rb +172 -0
  23. data/test/fixtures/{shoulda_macros/thing.rb → thing.rb} +0 -0
  24. data/test/helpers_test.rb +175 -0
  25. data/test/matchers_test.rb +135 -0
  26. data/test/rake_tasks_test.rb +8 -17
  27. metadata +33 -31
  28. data/lib/test_belt/shoulda_macros.rb +0 -9
  29. data/lib/test_belt/shoulda_macros/classes.rb +0 -105
  30. data/lib/test_belt/shoulda_macros/context.rb +0 -25
  31. data/lib/test_belt/shoulda_macros/files.rb +0 -49
  32. data/lib/test_belt/test_unit.rb +0 -8
  33. data/lib/test_belt/test_unit/context.rb +0 -71
  34. data/lib/test_belt/test_unit/runner.rb +0 -48
  35. data/lib/test_belt/test_unit/test_case.rb +0 -26
  36. data/test/shoulda_macros/classes_test.rb +0 -58
  37. data/test/shoulda_macros/context_test.rb +0 -28
  38. data/test/shoulda_macros/files_test.rb +0 -36
  39. data/test/test_unit/context_test.rb +0 -65
  40. data/test/test_unit/runner_test.rb +0 -31
  41. data/test/test_unit/test_case_test.rb +0 -30
data/.gitignore CHANGED
@@ -1,4 +1,5 @@
1
1
  /pkg/
2
2
  /doc/
3
3
  /coverage/
4
- *.log
4
+ *.log
5
+ .bundle
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
@@ -1,6 +1,27 @@
1
1
  require 'rubygems'
2
2
  require 'test/unit'
3
3
  require 'leftright'
4
- require 'shoulda'
5
- require 'test_belt/shoulda_macros'
6
- require 'test_belt/test_unit'
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