spec-unit 0.1.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,66 @@
1
+ module SpecUnit
2
+ module AssertHelper
3
+ def self.assert_helper(base)
4
+ base.module_eval do
5
+ class << self
6
+ for meth in methods
7
+ undef_method(meth) if meth.to_s =~ /^assert_/ || meth.to_s =~ /^assert$/
8
+ end
9
+
10
+ alias_method :spec_unit_method_missing, :method_missing
11
+ def method_missing(sym, *args, &block)
12
+ if sym.to_s =~ /^assert_/
13
+ self.send(:define_method, :"test_#{args[0]}") do
14
+ if block
15
+ send(sym, *(instance_eval(&block)))
16
+ else
17
+ send(sym)
18
+ end
19
+ end
20
+ else
21
+ spec_unit_method_missing sym, *args, &block
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ def self.included(base)
29
+ assert_helper(base)
30
+ end
31
+ end
32
+ end
33
+
34
+ module SpecUnit
35
+ module ContextHelper
36
+ def self.assert_helper(base)
37
+ base.module_eval do
38
+ class << self
39
+ for meth in methods
40
+ undef_method(meth) if meth.to_s =~ /^assert_/ || meth.to_s =~ /^assert$/
41
+ end
42
+
43
+ alias_method :spec_unit_method_missing, :method_missing
44
+ def method_missing(sym, *args, &block)
45
+ if sym.to_s =~ /^assert_/
46
+ self.send(:define_method, :"test_#{args[0]}") do
47
+ if block
48
+ send(sym, *(instance_eval(&block)))
49
+ else
50
+ send(sym)
51
+ end
52
+ end
53
+ else
54
+ spec_unit_method_missing sym, *args, &block
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ class Test::Unit::TestCase
64
+ include SpecUnit::AssertHelper
65
+ end
66
+
@@ -0,0 +1,68 @@
1
+ module SpecUnit
2
+ module ContextHelper
3
+ def self.included(base)
4
+ base.extend(ClassMethods)
5
+ assert_helper(base) if self.respond_to?(:assert_helper)
6
+ end
7
+
8
+ module ClassMethods
9
+ def context(name, &block)
10
+ self.send :include, new_context(name, &block)
11
+ end
12
+
13
+ def new_context(name, &block)
14
+ context_module = new_context_module
15
+
16
+ context_module.module_eval(&block)
17
+ context_module.convert_specifications_to_tests(name.gsub(' ', '_'))
18
+ context_module
19
+ end
20
+
21
+ def new_context_module
22
+ Module.new do
23
+ include ContextHelper
24
+
25
+ def self.convert_specifications_to_tests(name)
26
+ teardown, setup = unbound_teardown, unbound_setup
27
+ specifications = self.instance_methods.select {|m| m.to_s =~ /^specify_/ || m.to_s =~ /^test_/}
28
+
29
+ specifications.each do |spec|
30
+ spec_method = unbound_method(spec)
31
+ spec_name = spec.to_s.split(/^\w+?_/)[1]
32
+
33
+ define_method("test_#{name}_#{spec_name}".to_sym) do
34
+ setup.bind(self).call if setup
35
+ spec_method.bind(self).call
36
+ teardown.bind(self).call if teardown
37
+ end
38
+ end
39
+ end
40
+
41
+ def self.unbound_setup
42
+ unbound_method(:setup)
43
+ end
44
+
45
+ def self.unbound_teardown
46
+ unbound_method(:teardown)
47
+ end
48
+
49
+ def self.unbound_method(meth)
50
+ if self.instance_methods.include? meth.to_s
51
+ unbound_meth = instance_method(meth)
52
+ remove_method(meth) rescue module_where_defined(meth).module_eval { remove_method meth }
53
+ end
54
+ unbound_meth
55
+ end
56
+
57
+ def self.module_where_defined(meth)
58
+ included_modules.detect { |mod| mod.method_defined?(meth) }
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ class Test::Unit::TestCase
67
+ include SpecUnit::ContextHelper
68
+ end
@@ -0,0 +1,181 @@
1
+ # Provide object.should testing functionality.
2
+
3
+ module SpecUnit
4
+ class ShouldHelper
5
+ include Test::Unit::Assertions
6
+
7
+ def initialize(object, sym, *args, &block)
8
+ $spec_unit_test.send(:add_assertion)
9
+ @object = object
10
+ @not = !!(sym.to_s =~ /^should_not/)
11
+ sym = sym.to_s.sub(/_not/, '').to_sym if @not
12
+ self.send(sym, *args, &block)
13
+ end
14
+
15
+ def not_wrapper
16
+ @not ? !yield : yield
17
+ end
18
+
19
+ def should_with_predicate(meth, *args)
20
+ assert( not_wrapper { @object.send(meth.to_sym, *args) })
21
+ end
22
+
23
+ def should_with_method
24
+ self
25
+ end
26
+
27
+ %w( == < <= > >= ).each do |meth|
28
+ meth = meth.to_sym
29
+ self.send(:define_method, meth) do |another_object|
30
+ assert( not_wrapper { @object.send(meth, another_object) })
31
+ end
32
+ end
33
+
34
+ def should_be(another_object = nil)
35
+ if another_object.nil?
36
+ should_with_method
37
+ else
38
+ if @not
39
+ assert_not_same another_object, @object
40
+ else
41
+ assert_same another_object, @object
42
+ end
43
+ end
44
+ end
45
+
46
+ def should_be_a_kind_of(klass)
47
+ if @not
48
+ assert_block { !@object.kind_of?(klass) }
49
+ else
50
+ assert_kind_of klass, @object
51
+ end
52
+ end
53
+
54
+ def should_be_an_instance_of(klass)
55
+ if @not
56
+ assert_block { !@object.instance_of?(klass) }
57
+ else
58
+ assert_instance_of klass, @object
59
+ end
60
+ end
61
+
62
+ def should_be_close(another_object, delta)
63
+ if @not
64
+ assert_block { (another_object - delta > @object) || (another_object + delta < @object) }
65
+ else
66
+ assert_in_delta another_object, @object, delta
67
+ end
68
+ end
69
+
70
+ def should_equal(another_object)
71
+ if @not
72
+ assert_not_equal another_object, @object
73
+ else
74
+ assert_equal another_object, @object
75
+ end
76
+ end
77
+
78
+ def should_have(count)
79
+ if @not
80
+ assert_not_equal count, @object.size
81
+ else
82
+ assert_equal count, @object.size
83
+ end
84
+ end
85
+
86
+ def should_have_at_least(count)
87
+ assert( not_wrapper { @object.size >= count } )
88
+ end
89
+
90
+ def should_have_at_most(count)
91
+ assert( not_wrapper { @object.size <= count } )
92
+ end
93
+
94
+ def should_include(another_object)
95
+ assert( not_wrapper { @object.include?(another_object) } )
96
+ end
97
+
98
+ def should_raise(error=Exception)
99
+ assert_block do
100
+ not_wrapper do
101
+ begin
102
+ @object.call && false
103
+ rescue error
104
+ true
105
+ rescue Exception
106
+ false
107
+ end
108
+ end
109
+ end
110
+ end
111
+
112
+ def should_respond_to(method)
113
+ if @not
114
+ assert_block { !@object.respond_to?(method) }
115
+ else
116
+ assert_respond_to @object, method
117
+ end
118
+ end
119
+
120
+ def should_satisfy(&block)
121
+ assert( not_wrapper { block.call(@object) } )
122
+ end
123
+
124
+ def should_throw(symbol=nil)
125
+ if @not
126
+ assert_block do
127
+ begin
128
+ caught = true
129
+ if symbol
130
+ catch(symbol) do
131
+ @object.call
132
+ caught = false
133
+ end
134
+ else
135
+ @object.call
136
+ caught = false
137
+ end
138
+ rescue NameError, ThreadError => error
139
+ if UncaughtThrow[error.class] !~ error.message
140
+ raise error
141
+ end
142
+ caught = symbol.nil? ? true : false
143
+ end
144
+ !caught
145
+ end
146
+ else
147
+ assert_throws(symbol, &@object)
148
+ end
149
+ end
150
+
151
+ def method_missing(sym, *args)
152
+ if sym.to_s =~ /^should_be_/ || sym.to_s =~ /^should_have_/ || sym.to_s =~ /^should_/
153
+ should_with_predicate($', *args)
154
+ else
155
+ self
156
+ end
157
+ end
158
+ end
159
+ end
160
+
161
+ class Test::Unit::TestCase
162
+ alias_method :old_run, :run
163
+ def run(*args, &block)
164
+ $spec_unit_test = self
165
+ old_run(*args, &block)
166
+ end
167
+ end
168
+
169
+ Object.module_eval do
170
+ include Test::Unit::Assertions
171
+
172
+ alias_method :old_method_missing, :method_missing
173
+ def method_missing(sym, *args, &block)
174
+ if sym.to_s =~ /should/
175
+ SpecUnit::ShouldHelper.new(self, sym, *args, &block)
176
+ else
177
+ old_method_missing(sym, *args, &block)
178
+ end
179
+ end
180
+ end
181
+
data/lib/spec-unit.rb CHANGED
@@ -1,61 +1,3 @@
1
- module SpecUnit
2
- def self.included(base)
3
- base.extend(ClassMethods)
4
- end
5
-
6
- module ClassMethods
7
- def context(name, &block)
8
- self.send :include, new_context(name, &block)
9
- end
10
-
11
- def new_context(name, &block)
12
- context_module = new_context_module
13
-
14
- context_module.module_eval(&block)
15
- context_module.convert_specifications_to_tests(name.gsub(' ', '_'))
16
- context_module
17
- end
18
-
19
- def new_context_module
20
- Module.new do
21
- include SpecUnit
22
-
23
- def self.convert_specifications_to_tests(name)
24
- teardown, setup = unbound_teardown, unbound_setup
25
- specifications = self.instance_methods.select {|m| m.to_s =~ /^specify_/ || m.to_s =~ /^test_/}
26
-
27
- specifications.each do |spec|
28
- spec_method = unbound_method(spec)
29
- spec_name = spec.to_s.split(/^\w+?_/)[1]
30
-
31
- define_method("test_#{name}_#{spec_name}".to_sym) do
32
- setup.bind(self).call if setup
33
- spec_method.bind(self).call
34
- teardown.bind(self).call if teardown
35
- end
36
- end
37
- end
38
-
39
- def self.unbound_setup
40
- unbound_method(:setup)
41
- end
42
-
43
- def self.unbound_teardown
44
- unbound_method(:teardown)
45
- end
46
-
47
- def self.unbound_method(meth)
48
- if self.instance_methods.include? meth.to_s
49
- unbound_meth = instance_method(meth)
50
- remove_method(meth) rescue module_where_defined(meth).module_eval { remove_method meth }
51
- end
52
- unbound_meth
53
- end
54
-
55
- def self.module_where_defined(meth)
56
- included_modules.detect { |mod| mod.method_defined?(meth) }
57
- end
58
- end
59
- end
60
- end
61
- end
1
+ require 'spec-unit/context_helper'
2
+ require 'spec-unit/should_helper'
3
+ require 'spec-unit/assert_helper'
data/test/helper.rb ADDED
@@ -0,0 +1,55 @@
1
+ $: << File.dirname(__FILE__) + '/../lib'
2
+
3
+ require 'test/unit'
4
+
5
+ class Test::Unit::TestCase
6
+ def assert_has_one_assertion(test)
7
+ assert_nothing_raised { @test_class.new(test.to_sym) }
8
+ assert_has_x_assertions(1, test)
9
+ end
10
+
11
+ def assert_has_x_assertions(number_of_assertions, test)
12
+ @result = Test::Unit::TestResult.new
13
+ @test_suite = @test_class.suite
14
+ @test_suite.run(@result) {|m, n|}
15
+ assert_equal number_of_assertions, @result.assertion_count
16
+ end
17
+
18
+ def assert_test_passes(test)
19
+ assert_test :passes, test
20
+ end
21
+
22
+ def assert_test_passes_with_setup(test, &block)
23
+ define_setup(&block) if block
24
+ assert_test_passes test
25
+ end
26
+
27
+ def assert_test_fails(test)
28
+ assert_test :fails, test
29
+ end
30
+
31
+ def assert_test_fails_with_setup(test, &block)
32
+ define_setup(&block) if block
33
+ assert_test_fails test
34
+ end
35
+
36
+ def assert_test(result, test)
37
+ @result = Test::Unit::TestResult.new
38
+ assert_nothing_raised { @object = @test_class.new(test.to_sym) }
39
+ @object.run(@result) {|m,n|}
40
+ assert_not_equal 0, @result.assertion_count
41
+ case result
42
+ when :passes
43
+ assert @result.passed?
44
+ when :fails
45
+ assert_equal 1, @result.failure_count
46
+ else
47
+ raise "'#{result}' is not a valid test condition."
48
+ end
49
+ end
50
+
51
+ def define_setup &block
52
+ @test_class.send :define_method, :setup, block
53
+ end
54
+
55
+ end
@@ -0,0 +1,147 @@
1
+ $: << File.dirname(__FILE__)
2
+
3
+ require 'helper'
4
+ require 'spec-unit/context_helper'
5
+ require 'spec-unit/should_helper'
6
+ require 'spec-unit/assert_helper'
7
+
8
+ class TestAssertHelper < Test::Unit::TestCase
9
+ def setup
10
+ @test_class = Class.new(Test::Unit::TestCase)
11
+ end
12
+
13
+ context 'assert_equal' do
14
+ def setup
15
+ @test_class.module_eval { assert_equal(:objects_are_equal) {[ @object, @another_object ]}}
16
+ end
17
+
18
+ def test_is_wrapped
19
+ assert_has_one_assertion(:test_objects_are_equal)
20
+ end
21
+
22
+ def test_passes
23
+ assert_test_passes_with_setup(:test_objects_are_equal) { @object, @another_object = 'this', 'this' }
24
+ end
25
+
26
+ def test_fails
27
+ assert_test_fails_with_setup(:test_objects_are_equal) { @object, @another_object = 'this', 'that' }
28
+ end
29
+ end
30
+
31
+ context 'assert_not_equal' do
32
+ def setup
33
+ @test_class.module_eval { assert_not_equal(:objects_are_not_equal) { next @object, @another_object }}
34
+ end
35
+
36
+ def test_is_wrapped
37
+ assert_has_one_assertion(:test_objects_are_not_equal)
38
+ end
39
+
40
+ def test_passes
41
+ assert_test_passes_with_setup(:test_objects_are_not_equal) { @object, @another_object = 'this', 'that' }
42
+ end
43
+
44
+ def test_fails
45
+ assert_test_fails_with_setup(:test_objects_are_not_equal) { @object, @another_object = 'this', 'this' }
46
+ end
47
+ end
48
+
49
+ context 'assert_equal in a context' do
50
+ def setup
51
+ @test_class.module_eval do
52
+ context 'in a context' do
53
+ assert_equal(:objects_are_equal) { next @object, @another_object }
54
+ end
55
+ end
56
+ end
57
+
58
+ def test_is_wrapped
59
+ assert_has_one_assertion(:test_in_a_context_objects_are_equal)
60
+ end
61
+
62
+ def test_passes
63
+ assert_test_passes_with_setup(:test_in_a_context_objects_are_equal) { @object, @another_object = 'this', 'this' }
64
+ end
65
+
66
+ def test_fails
67
+ assert_test_fails_with_setup(:test_in_a_context_objects_are_equal) { @object, @another_object = 'this', 'that' }
68
+ end
69
+ end
70
+
71
+ context 'a custom assertion' do
72
+ def setup
73
+ @test_class.module_eval do
74
+ def assert_my_own_things(object); object.should_equal 1; end
75
+ assert_my_own_things(:custom_assertion) { next @object }
76
+ end
77
+ end
78
+
79
+ def test_is_wrapped
80
+ assert_has_one_assertion(:test_custom_assertion)
81
+ end
82
+
83
+ def test_passes
84
+ assert_test_passes_with_setup(:test_custom_assertion) { @object = 1 }
85
+ end
86
+
87
+ def test_fails
88
+ assert_test_fails_with_setup(:test_custom_assertion) { @object = 2 }
89
+ end
90
+ end
91
+
92
+ context 'a custom assertion that takes no parameters' do
93
+ def setup
94
+ @test_class.module_eval do
95
+ def assert_custom; @object.should_equal 1; end
96
+ assert_custom(:custom)
97
+ end
98
+ end
99
+
100
+ def test_is_wrapped
101
+ assert_has_one_assertion(:test_custom)
102
+ end
103
+
104
+ def test_passes
105
+ assert_test_passes_with_setup(:test_custom) { @object = 1 }
106
+ end
107
+
108
+ def test_fails
109
+ assert_test_fails_with_setup(:test_custom) { @object = 2 }
110
+ end
111
+ end
112
+
113
+ context 'a custom assertion in a context that takes no parameters' do
114
+ def setup
115
+ @test_class.module_eval do
116
+ def assert_custom; @object.should_equal 1; end
117
+ context('a context') { assert_custom(:custom) }
118
+ end
119
+ end
120
+
121
+ def test_is_wrapped
122
+ assert_has_one_assertion(:test_a_context_custom)
123
+ end
124
+
125
+ def test_passes
126
+ assert_test_passes_with_setup(:test_a_context_custom) { @object = 1 }
127
+ end
128
+
129
+ def test_fails
130
+ assert_test_fails_with_setup(:test_a_context_custom) { @object = 2 }
131
+ end
132
+ end
133
+
134
+ context 'some_other_method' do
135
+ def test_throws_name_error
136
+ assert_raise(NameError) { @test_class.module_eval { some_other_method } }
137
+ end
138
+
139
+ def test_throws_name_error_in_context
140
+ assert_raise(NameError) do
141
+ @test_class.module_eval do
142
+ context('a context') { some_other_method }
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end