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.
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