shared_should 0.8.2 → 0.8.3
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/VERSION +1 -1
- data/lib/shared_should/shared_context.rb +176 -0
- data/lib/shared_should/shared_proxy.rb +130 -0
- data/lib/shared_should/test_class_helper.rb +58 -0
- data/lib/shared_should/test_unit_hooks.rb +50 -0
- data/lib/shared_should.rb +6 -404
- data/shared_should.gemspec +12 -8
- metadata +15 -13
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.8.
|
1
|
+
0.8.3
|
@@ -0,0 +1,176 @@
|
|
1
|
+
module SharedShould::SharedContext
|
2
|
+
# class methods for Test::Unit::TestCase
|
3
|
+
def self.extended(klass)
|
4
|
+
class << klass
|
5
|
+
# these methods need to be aliased for both the test class and the should context
|
6
|
+
alias_method :context_without_shared_proxies_executing, :context
|
7
|
+
alias_method :should_without_param_support, :should
|
8
|
+
alias_method :setup_without_param_support, :setup
|
9
|
+
end
|
10
|
+
|
11
|
+
klass.extend(SharedContextMethods)
|
12
|
+
end
|
13
|
+
|
14
|
+
# instance methods for Shoulda::Context
|
15
|
+
def self.included(klass)
|
16
|
+
klass.class_eval do
|
17
|
+
# these methods need to be aliased for both the test class and the should context
|
18
|
+
alias :context_without_shared_proxies_executing :context
|
19
|
+
alias :should_without_param_support :should
|
20
|
+
alias :setup_without_param_support :setup
|
21
|
+
|
22
|
+
# remove any methods we are going to define with our included module
|
23
|
+
SharedContextMethods.instance_methods.each do |method_name|
|
24
|
+
remove_method method_name if method_defined? method_name
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
klass.send(:include, SharedContextMethods)
|
29
|
+
end
|
30
|
+
|
31
|
+
module SharedContextMethods
|
32
|
+
def shared_proxies
|
33
|
+
@shared_proxies ||= []
|
34
|
+
end
|
35
|
+
|
36
|
+
def use_should(shared_name)
|
37
|
+
return add_shared_proxy.use_should(shared_name)
|
38
|
+
end
|
39
|
+
|
40
|
+
def use_context(shared_name)
|
41
|
+
return add_shared_proxy.use_context(shared_name)
|
42
|
+
end
|
43
|
+
|
44
|
+
def use_setup(shared_name)
|
45
|
+
return add_shared_proxy.use_setup(shared_name)
|
46
|
+
end
|
47
|
+
|
48
|
+
def setup(name = nil, &block)
|
49
|
+
return add_shared_proxy.setup(name, &block)
|
50
|
+
end
|
51
|
+
|
52
|
+
def context(name = nil, &block)
|
53
|
+
if block
|
54
|
+
shared_proxies_executing_block = Proc.new do
|
55
|
+
block.bind(self).call
|
56
|
+
|
57
|
+
shared_proxies.each do |shared_proxy|
|
58
|
+
shared_proxy.share_execute
|
59
|
+
end
|
60
|
+
end
|
61
|
+
shared_proxies_executing_block.bind(eval("self", block.binding))
|
62
|
+
context_without_shared_proxies_executing(name, &shared_proxies_executing_block)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def should(name = nil, options = {}, &block)
|
67
|
+
if block.nil?
|
68
|
+
should_without_param_support(name, options)
|
69
|
+
else
|
70
|
+
should_without_param_support(name, options) do
|
71
|
+
call_block_with_shared_value(block)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def share_context(shared_context_name, &shared_context_block)
|
77
|
+
wrapping_shared_context_block = Proc.new do
|
78
|
+
context share_description do
|
79
|
+
merge_block(&shared_context_block)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
Test::Unit::TestCase.shared_context_block_owner(shared_context_for_block(shared_context_block)).shared_context_blocks[shared_context_name] = wrapping_shared_context_block
|
84
|
+
end
|
85
|
+
|
86
|
+
def share_should(shared_should_name, &shared_should_block)
|
87
|
+
shared_context_block = Proc.new do
|
88
|
+
should share_description do
|
89
|
+
call_block_with_shared_value(shared_should_block)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
Test::Unit::TestCase.shared_context_block_owner(shared_context_for_block(shared_should_block)).shared_should_blocks[shared_should_name] = shared_context_block
|
94
|
+
end
|
95
|
+
|
96
|
+
def share_setup(shared_name, &setup_block)
|
97
|
+
current_context = eval('self', setup_block.binding)
|
98
|
+
Test::Unit::TestCase.shared_context_block_owner(current_context).shared_setup_blocks[shared_name] = setup_block
|
99
|
+
end
|
100
|
+
|
101
|
+
def shared_context_blocks
|
102
|
+
@shared_context_blocks ||= {}
|
103
|
+
end
|
104
|
+
|
105
|
+
def shared_should_blocks
|
106
|
+
@shared_should_blocks ||= {}
|
107
|
+
end
|
108
|
+
|
109
|
+
def shared_setup_blocks
|
110
|
+
@shared_setup_blocks ||= {}
|
111
|
+
end
|
112
|
+
|
113
|
+
def find_shared_block(share_type, shared_name)
|
114
|
+
current_context = self
|
115
|
+
while current_context.kind_of?(Shoulda::Context) || current_context < Test::Unit::TestCase do
|
116
|
+
if shared_block = Test::Unit::TestCase.shared_context_block_owner(current_context).send("shared_#{share_type}_blocks")[shared_name]
|
117
|
+
return shared_block
|
118
|
+
end
|
119
|
+
raise "Unable to find share_#{share_type}('#{shared_name}')" if current_context.kind_of?(Class)
|
120
|
+
break unless current_context.kind_of?(Shoulda::Context)
|
121
|
+
current_context = current_context.parent
|
122
|
+
end
|
123
|
+
raise "Unable to find share_#{share_type}('#{shared_name}')"
|
124
|
+
end
|
125
|
+
|
126
|
+
private
|
127
|
+
|
128
|
+
def add_shared_proxy
|
129
|
+
(shared_proxies << SharedShould::SharedProxy.new(self)).last
|
130
|
+
end
|
131
|
+
|
132
|
+
def shared_context_for_block(shared_block)
|
133
|
+
eval("self", shared_block.binding)
|
134
|
+
end
|
135
|
+
|
136
|
+
def merge_shared_context(shared_context_block, caller_context, name, initialization_block)
|
137
|
+
name = '' if name.nil?
|
138
|
+
|
139
|
+
caller_context.context name do
|
140
|
+
setup do
|
141
|
+
setup_shared_value(initialization_block)
|
142
|
+
end
|
143
|
+
|
144
|
+
merge_block(&shared_context_block)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def do_shared_setup(shared_setup_name, destination_context, &shared_setup_block)
|
149
|
+
do_shared_helper(shared_setup_name, destination_context, :setup, :merge_shared_setup, &shared_setup_block)
|
150
|
+
end
|
151
|
+
|
152
|
+
def merge_shared_setup(shared_setup_block, caller_context, name, setup_block)
|
153
|
+
# note: the binding for the block of the TestCase's setup method is not an instance of the TestCase - its the TestCase class.
|
154
|
+
# Handle the TestCase class by chaining it to the setup method.
|
155
|
+
if caller_context == self
|
156
|
+
@@shared_setup_alias_index = 0 unless defined?(@@shared_setup_alias_index)
|
157
|
+
@@shared_setup_alias_index += 1
|
158
|
+
with_method = :"setup_with_shared_setup_#{@@shared_setup_alias_index}"
|
159
|
+
without_method = :"setup_without_shared_setup_#{@@shared_setup_alias_index}"
|
160
|
+
caller_context.send(:alias_method, without_method, :setup)
|
161
|
+
caller_context.send(:define_method, with_method) do
|
162
|
+
send(without_method)
|
163
|
+
setup_shared_value(setup_block)
|
164
|
+
shared_setup_block.bind(self).call
|
165
|
+
end
|
166
|
+
caller_context.send(:alias_method, :setup, with_method)
|
167
|
+
else
|
168
|
+
caller_context.setup do
|
169
|
+
setup_shared_value(setup_block)
|
170
|
+
shared_setup_block.bind(self).call
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
176
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
class SharedShould::SharedProxy
|
2
|
+
attr_accessor :source_context, :setup_block_configs, :test_type, :test_block, :test_description, :current_action
|
3
|
+
|
4
|
+
def initialize(source_context)
|
5
|
+
self.setup_block_configs = []
|
6
|
+
self.source_context = source_context
|
7
|
+
end
|
8
|
+
|
9
|
+
def setup(description = nil, &initialization_block)
|
10
|
+
add_setup_block(:setup, description, &initialization_block)
|
11
|
+
end
|
12
|
+
|
13
|
+
def use_setup(share_name)
|
14
|
+
add_setup_block(:use_setup, share_name, &source_context.find_shared_block(:setup, share_name))
|
15
|
+
end
|
16
|
+
|
17
|
+
# deprecated
|
18
|
+
def with_setup(share_name)
|
19
|
+
return use_setup(share_name)
|
20
|
+
end
|
21
|
+
|
22
|
+
# deprecated
|
23
|
+
def with(share_name = nil, &initialization_block)
|
24
|
+
return setup(share_name ? "with #{share_name}" : nil, &initialization_block)
|
25
|
+
end
|
26
|
+
|
27
|
+
# deprecated
|
28
|
+
def when(share_name = nil, &initialization_block)
|
29
|
+
return setup(share_name ? "when #{share_name}" : nil, &initialization_block)
|
30
|
+
end
|
31
|
+
|
32
|
+
def given(description = nil, &initialization_block)
|
33
|
+
valid_share_types = [:use_setup, :use_should, :use_context]
|
34
|
+
@failed = true and raise ArgumentError, "'given' can only appear after #{valid_share_types.join(', ')}" unless valid_share_types.include?(current_action)
|
35
|
+
|
36
|
+
add_setup_block(:given, description ? "given #{description}" : nil, &initialization_block)
|
37
|
+
end
|
38
|
+
|
39
|
+
def should(description = nil, options = {}, &should_block)
|
40
|
+
shared_context_block = Proc.new do
|
41
|
+
should share_description do
|
42
|
+
call_block_with_shared_value(should_block)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
add_test_block(:should, description, &shared_context_block)
|
46
|
+
end
|
47
|
+
|
48
|
+
def use_should(share_name)
|
49
|
+
add_test_block(:use_should, share_name, &source_context.find_shared_block(:should, share_name))
|
50
|
+
end
|
51
|
+
|
52
|
+
def context(description = nil, &context_block)
|
53
|
+
shared_context_block = Proc.new do
|
54
|
+
context share_description do
|
55
|
+
merge_block(&context_block)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
add_test_block(:context, description, &shared_context_block)
|
59
|
+
end
|
60
|
+
|
61
|
+
def use_context(share_name)
|
62
|
+
add_test_block(:use_context, share_name, &source_context.find_shared_block(:context, share_name))
|
63
|
+
end
|
64
|
+
|
65
|
+
def share_execute
|
66
|
+
return if @failed
|
67
|
+
|
68
|
+
shared_proxy = self
|
69
|
+
if test_type == :should || test_type == :context || test_type == :use_should || test_type == :use_context
|
70
|
+
# create a new context for setups and should/context
|
71
|
+
source_context.context setup_block_configs_description do
|
72
|
+
setup_without_param_support do
|
73
|
+
shared_proxy.setup_block_configs.each do |config|
|
74
|
+
call_block_config(config)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# share_description called when creating test names
|
79
|
+
self.instance_variable_set("@share_description", shared_proxy.send(:test_description))
|
80
|
+
def self.share_description; @share_description; end
|
81
|
+
merge_block(&shared_proxy.test_block)
|
82
|
+
end
|
83
|
+
else
|
84
|
+
# call setups directly in this context
|
85
|
+
source_context.setup_without_param_support do
|
86
|
+
shared_proxy.setup_block_configs.each do |config|
|
87
|
+
call_block_config(config)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def setup_block_configs_description
|
96
|
+
@setup_block_configs_description
|
97
|
+
end
|
98
|
+
|
99
|
+
def add_test_block(test_type, description, &test_block)
|
100
|
+
@failed = true and raise ArgumentError, 'Only a single should or context can be chained' if self.test_type
|
101
|
+
|
102
|
+
self.test_type = test_type
|
103
|
+
self.current_action = test_type
|
104
|
+
self.test_description = description
|
105
|
+
self.test_block = test_block
|
106
|
+
return self
|
107
|
+
end
|
108
|
+
|
109
|
+
def add_setup_block(action, description, &block)
|
110
|
+
if test_type
|
111
|
+
#@failed = true and raise ArgumentError, "'#{action}' may not be applied" unless action == :given
|
112
|
+
# add final given description to test description
|
113
|
+
self.test_description = "#{test_description} #{description}" if description
|
114
|
+
description = nil
|
115
|
+
end
|
116
|
+
|
117
|
+
setup_block_config = {:block => block, :action => action, :description => description}
|
118
|
+
if action == :given and (current_action == :setup || current_action == :use_setup)
|
119
|
+
setup_block_configs.insert(-2, setup_block_config)
|
120
|
+
else
|
121
|
+
setup_block_configs << setup_block_config
|
122
|
+
end
|
123
|
+
if description
|
124
|
+
@setup_block_configs_description = "#{@setup_block_configs_description}#{' ' if @setup_block_configs_description}#{description}"
|
125
|
+
end
|
126
|
+
|
127
|
+
self.current_action = action
|
128
|
+
return self
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module SharedShould::TestClassHelper
|
2
|
+
def self.included(base_test_class)
|
3
|
+
base_test_class.class_eval do
|
4
|
+
attr_accessor :shared_value
|
5
|
+
@@shared_proxies_executed = {}
|
6
|
+
@@setup_blocks = {}
|
7
|
+
|
8
|
+
def self.execute_class_shared_proxies
|
9
|
+
if @@shared_proxies_executed[self].nil?
|
10
|
+
shared_proxies.each do |shared_proxy|
|
11
|
+
shared_proxy.share_execute
|
12
|
+
end
|
13
|
+
@@shared_proxies_executed[self] = true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.shared_context_block_owner(context_or_test_class)
|
18
|
+
return context_or_test_class.kind_of?(Shoulda::Context) ? context_or_test_class : Test::Unit::TestCase
|
19
|
+
end
|
20
|
+
|
21
|
+
def execute_class_shared_setups_if_not_executed
|
22
|
+
if !@shared_setups_executed
|
23
|
+
@shared_setups_executed = true
|
24
|
+
(@@setup_blocks[self.class] || []).each do |setup_block|
|
25
|
+
setup_block.bind(self).call
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.setup(&setup_block)
|
31
|
+
@@setup_blocks[self] = [] unless @@setup_blocks[self]
|
32
|
+
@@setup_blocks[self] << setup_block
|
33
|
+
end
|
34
|
+
|
35
|
+
def setup_shared_value(initialization_block)
|
36
|
+
self.shared_value = initialization_block.nil? ? nil : initialization_block.bind(self).call
|
37
|
+
end
|
38
|
+
|
39
|
+
def call_block_with_shared_value(test_block)
|
40
|
+
return nil unless test_block
|
41
|
+
execute_class_shared_setups_if_not_executed
|
42
|
+
if test_block.arity == 1
|
43
|
+
# check arity of 1 before checking if value is an array. If one parameter, never treat the shared_value as variable args
|
44
|
+
test_block.bind(self).call(self.shared_value)
|
45
|
+
elsif self.shared_value.class == Array && test_block.arity == self.shared_value.length
|
46
|
+
test_block.bind(self).call(*self.shared_value)
|
47
|
+
else
|
48
|
+
test_block.bind(self).call()
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def call_block_config(block_config)
|
53
|
+
ret_val = call_block_with_shared_value(block_config[:block])
|
54
|
+
self.shared_value = ret_val if block_config[:action] == :given
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# Ruby 1.9 with MiniTest
|
2
|
+
if defined?(MiniTest::Unit::TestCase)
|
3
|
+
class MiniTest::Unit::TestCase
|
4
|
+
class << self
|
5
|
+
# these methods need to be aliased for both the test class and the should context
|
6
|
+
alias_method :test_methods_without_shared_should_execute, :test_methods
|
7
|
+
end
|
8
|
+
|
9
|
+
class_eval do
|
10
|
+
include SharedShould::TestClassHelper
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.test_methods
|
14
|
+
# assuming 'test_methods' is called before executing any tests - may be a poor assumption. Find something better?
|
15
|
+
execute_class_shared_proxies
|
16
|
+
|
17
|
+
test_methods_without_shared_should_execute
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Ruby 1.8 without MiniTest
|
23
|
+
if defined?(Test::Unit::TestCase.suite)
|
24
|
+
class Test::Unit::TestCase
|
25
|
+
class << self
|
26
|
+
# these methods need to be aliased for both the test class and the should context
|
27
|
+
alias_method :suite_without_shared_should_execute, :suite
|
28
|
+
end
|
29
|
+
|
30
|
+
class_eval do
|
31
|
+
include SharedShould::TestClassHelper
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.suite
|
35
|
+
# assuming 'suite' is called before executing any tests - may be a poor assumption. Find something better?
|
36
|
+
execute_class_shared_proxies
|
37
|
+
|
38
|
+
suite_without_shared_should_execute
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
class Test::Unit::TestCase
|
45
|
+
extend SharedShould::SharedContext
|
46
|
+
end
|
47
|
+
|
48
|
+
class Shoulda::Context
|
49
|
+
include SharedShould::SharedContext
|
50
|
+
end
|
data/lib/shared_should.rb
CHANGED
@@ -1,407 +1,9 @@
|
|
1
|
+
$: << File.expand_path(File.join(File.dirname(__FILE__), 'shared_should'))
|
1
2
|
require 'shoulda'
|
2
3
|
|
3
|
-
|
4
|
-
if defined?(MiniTest::Unit::TestCase)
|
5
|
-
class MiniTest::Unit::TestCase
|
6
|
-
class << self
|
7
|
-
# these methods need to be aliased for both the test class and the should context
|
8
|
-
alias_method :test_suites_without_shared_should_execute, :test_suites
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.test_suites
|
12
|
-
Test::Unit::TestCase.execute_class_shared_proxies
|
13
|
-
|
14
|
-
test_suites_without_shared_should_execute
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
4
|
+
module SharedShould; end
|
18
5
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
# these methods need to be aliased for both the test class and the should context
|
24
|
-
alias_method :suite_without_shared_should_execute, :suite
|
25
|
-
end
|
26
|
-
|
27
|
-
def self.suite
|
28
|
-
# assuming 'suite' is called before executing any tests - may be a poor assumption. Find something better?
|
29
|
-
execute_class_shared_proxies
|
30
|
-
|
31
|
-
suite_without_shared_should_execute
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
|
37
|
-
class Test::Unit::TestCase
|
38
|
-
attr_accessor :shared_value
|
39
|
-
@@shared_proxies_executed = {}
|
40
|
-
@@setup_blocks = {}
|
41
|
-
|
42
|
-
def self.execute_class_shared_proxies
|
43
|
-
unless @@shared_proxies_executed[self]
|
44
|
-
shared_proxies.each do |shared_proxy|
|
45
|
-
shared_proxy.share_execute
|
46
|
-
end
|
47
|
-
@@shared_proxies_executed[self] = true
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def self.shared_context_block_owner(context_or_test_class)
|
52
|
-
return context_or_test_class.kind_of?(Shoulda::Context) ? context_or_test_class : Test::Unit::TestCase
|
53
|
-
end
|
54
|
-
|
55
|
-
def execute_class_shared_setups_if_not_executed
|
56
|
-
if !@shared_setups_executed
|
57
|
-
@shared_setups_executed = true
|
58
|
-
(@@setup_blocks[self.class] || []).each do |setup_block|
|
59
|
-
setup_block.bind(self).call
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def self.setup(&setup_block)
|
65
|
-
@@setup_blocks[self] = [] unless @@setup_blocks[self]
|
66
|
-
@@setup_blocks[self] << setup_block
|
67
|
-
end
|
68
|
-
|
69
|
-
def setup_shared_value(initialization_block)
|
70
|
-
self.shared_value = initialization_block.nil? ? nil : initialization_block.bind(self).call
|
71
|
-
end
|
72
|
-
|
73
|
-
def call_block_with_shared_value(test_block)
|
74
|
-
return nil unless test_block
|
75
|
-
execute_class_shared_setups_if_not_executed
|
76
|
-
if test_block.arity == 1
|
77
|
-
# check arity of 1 before checking if value is an array. If one parameter, never treat the shared_value as variable args
|
78
|
-
test_block.bind(self).call(self.shared_value)
|
79
|
-
elsif self.shared_value.class == Array && test_block.arity == self.shared_value.length
|
80
|
-
test_block.bind(self).call(*self.shared_value)
|
81
|
-
else
|
82
|
-
test_block.bind(self).call()
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
def call_block_config(block_config)
|
87
|
-
ret_val = call_block_with_shared_value(block_config[:block])
|
88
|
-
self.shared_value = ret_val if block_config[:action] == :given
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
module Shoulda::SharedContext
|
93
|
-
# class methods for Test::Unit::TestCase
|
94
|
-
def self.extended(klass)
|
95
|
-
class << klass
|
96
|
-
# these methods need to be aliased for both the test class and the should context
|
97
|
-
alias_method :context_without_shared_proxies_executing, :context
|
98
|
-
alias_method :should_without_param_support, :should
|
99
|
-
alias_method :setup_without_param_support, :setup
|
100
|
-
end
|
101
|
-
|
102
|
-
klass.extend(SharedContextMethods)
|
103
|
-
end
|
104
|
-
|
105
|
-
# instance methods for Shoulda::Context
|
106
|
-
def self.included(klass)
|
107
|
-
klass.class_eval do
|
108
|
-
# these methods need to be aliased for both the test class and the should context
|
109
|
-
alias :context_without_shared_proxies_executing :context
|
110
|
-
alias :should_without_param_support :should
|
111
|
-
alias :setup_without_param_support :setup
|
112
|
-
|
113
|
-
# remove any methods we are going to define with our included module
|
114
|
-
SharedContextMethods.instance_methods.each do |method_name|
|
115
|
-
remove_method method_name if method_defined? method_name
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
klass.send(:include, SharedContextMethods)
|
120
|
-
end
|
121
|
-
|
122
|
-
module SharedContextMethods
|
123
|
-
def shared_proxies
|
124
|
-
@shared_proxies ||= []
|
125
|
-
end
|
126
|
-
|
127
|
-
def use_should(shared_name)
|
128
|
-
return add_shared_proxy.use_should(shared_name)
|
129
|
-
end
|
130
|
-
|
131
|
-
def use_context(shared_name)
|
132
|
-
return add_shared_proxy.use_context(shared_name)
|
133
|
-
end
|
134
|
-
|
135
|
-
def use_setup(shared_name)
|
136
|
-
return add_shared_proxy.use_setup(shared_name)
|
137
|
-
end
|
138
|
-
|
139
|
-
def setup(name = nil, &block)
|
140
|
-
return add_shared_proxy.setup(name, &block)
|
141
|
-
end
|
142
|
-
|
143
|
-
def context(name = nil, &block)
|
144
|
-
if block
|
145
|
-
shared_proxies_executing_block = Proc.new do
|
146
|
-
block.bind(self).call
|
147
|
-
|
148
|
-
shared_proxies.each do |shared_proxy|
|
149
|
-
shared_proxy.share_execute
|
150
|
-
end
|
151
|
-
end
|
152
|
-
shared_proxies_executing_block.bind(eval("self", block.binding))
|
153
|
-
context_without_shared_proxies_executing(name, &shared_proxies_executing_block)
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
def should(name = nil, options = {}, &block)
|
158
|
-
if block.nil?
|
159
|
-
should_without_param_support(name, options)
|
160
|
-
else
|
161
|
-
should_without_param_support(name, options) do
|
162
|
-
call_block_with_shared_value(block)
|
163
|
-
end
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
def share_context(shared_context_name, &shared_context_block)
|
168
|
-
wrapping_shared_context_block = Proc.new do
|
169
|
-
context share_description do
|
170
|
-
merge_block(&shared_context_block)
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
|
-
Test::Unit::TestCase.shared_context_block_owner(shared_context_for_block(shared_context_block)).shared_context_blocks[shared_context_name] = wrapping_shared_context_block
|
175
|
-
end
|
176
|
-
|
177
|
-
def share_should(shared_should_name, &shared_should_block)
|
178
|
-
shared_context_block = Proc.new do
|
179
|
-
should share_description do
|
180
|
-
call_block_with_shared_value(shared_should_block)
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
Test::Unit::TestCase.shared_context_block_owner(shared_context_for_block(shared_should_block)).shared_should_blocks[shared_should_name] = shared_context_block
|
185
|
-
end
|
186
|
-
|
187
|
-
def share_setup(shared_name, &setup_block)
|
188
|
-
current_context = eval('self', setup_block.binding)
|
189
|
-
Test::Unit::TestCase.shared_context_block_owner(current_context).shared_setup_blocks[shared_name] = setup_block
|
190
|
-
end
|
191
|
-
|
192
|
-
def shared_context_blocks
|
193
|
-
@shared_context_blocks ||= {}
|
194
|
-
end
|
195
|
-
|
196
|
-
def shared_should_blocks
|
197
|
-
@shared_should_blocks ||= {}
|
198
|
-
end
|
199
|
-
|
200
|
-
def shared_setup_blocks
|
201
|
-
@shared_setup_blocks ||= {}
|
202
|
-
end
|
203
|
-
|
204
|
-
def find_shared_block(share_type, shared_name)
|
205
|
-
current_context = self
|
206
|
-
while current_context.kind_of?(Shoulda::Context) || current_context < Test::Unit::TestCase do
|
207
|
-
if shared_block = Test::Unit::TestCase.shared_context_block_owner(current_context).send("shared_#{share_type}_blocks")[shared_name]
|
208
|
-
return shared_block
|
209
|
-
end
|
210
|
-
raise "Unable to find share_#{share_type}('#{shared_name}')" if current_context.kind_of?(Class)
|
211
|
-
break unless current_context.kind_of?(Shoulda::Context)
|
212
|
-
current_context = current_context.parent
|
213
|
-
end
|
214
|
-
raise "Unable to find share_#{share_type}('#{shared_name}')"
|
215
|
-
end
|
216
|
-
|
217
|
-
private
|
218
|
-
|
219
|
-
def add_shared_proxy
|
220
|
-
(shared_proxies << Shoulda::SharedProxy.new(self)).last
|
221
|
-
end
|
222
|
-
|
223
|
-
def shared_context_for_block(shared_block)
|
224
|
-
eval("self", shared_block.binding)
|
225
|
-
end
|
226
|
-
|
227
|
-
def merge_shared_context(shared_context_block, caller_context, name, initialization_block)
|
228
|
-
name = '' if name.nil?
|
229
|
-
|
230
|
-
caller_context.context name do
|
231
|
-
setup do
|
232
|
-
setup_shared_value(initialization_block)
|
233
|
-
end
|
234
|
-
|
235
|
-
merge_block(&shared_context_block)
|
236
|
-
end
|
237
|
-
end
|
238
|
-
|
239
|
-
def do_shared_setup(shared_setup_name, destination_context, &shared_setup_block)
|
240
|
-
do_shared_helper(shared_setup_name, destination_context, :setup, :merge_shared_setup, &shared_setup_block)
|
241
|
-
end
|
242
|
-
|
243
|
-
def merge_shared_setup(shared_setup_block, caller_context, name, setup_block)
|
244
|
-
# note: the binding for the block of the TestCase's setup method is not an instance of the TestCase - its the TestCase class.
|
245
|
-
# Handle the TestCase class by chaining it to the setup method.
|
246
|
-
if caller_context == self
|
247
|
-
@@shared_setup_alias_index = 0 unless defined?(@@shared_setup_alias_index)
|
248
|
-
@@shared_setup_alias_index += 1
|
249
|
-
with_method = :"setup_with_shared_setup_#{@@shared_setup_alias_index}"
|
250
|
-
without_method = :"setup_without_shared_setup_#{@@shared_setup_alias_index}"
|
251
|
-
caller_context.send(:alias_method, without_method, :setup)
|
252
|
-
caller_context.send(:define_method, with_method) do
|
253
|
-
send(without_method)
|
254
|
-
setup_shared_value(setup_block)
|
255
|
-
shared_setup_block.bind(self).call
|
256
|
-
end
|
257
|
-
caller_context.send(:alias_method, :setup, with_method)
|
258
|
-
else
|
259
|
-
caller_context.setup do
|
260
|
-
setup_shared_value(setup_block)
|
261
|
-
shared_setup_block.bind(self).call
|
262
|
-
end
|
263
|
-
end
|
264
|
-
end
|
265
|
-
|
266
|
-
end
|
267
|
-
end
|
268
|
-
|
269
|
-
class Shoulda::Context
|
270
|
-
include Shoulda::SharedContext
|
271
|
-
end
|
272
|
-
|
273
|
-
class Test::Unit::TestCase
|
274
|
-
extend Shoulda::SharedContext
|
275
|
-
end
|
276
|
-
|
277
|
-
|
278
|
-
class Shoulda::SharedProxy
|
279
|
-
attr_accessor :source_context, :setup_block_configs, :test_type, :test_block, :test_description, :current_action
|
280
|
-
|
281
|
-
def initialize(source_context)
|
282
|
-
self.setup_block_configs = []
|
283
|
-
self.source_context = source_context
|
284
|
-
end
|
285
|
-
|
286
|
-
def setup(description = nil, &initialization_block)
|
287
|
-
add_setup_block(:setup, description, &initialization_block)
|
288
|
-
end
|
289
|
-
|
290
|
-
def use_setup(share_name)
|
291
|
-
add_setup_block(:use_setup, share_name, &source_context.find_shared_block(:setup, share_name))
|
292
|
-
end
|
293
|
-
|
294
|
-
# deprecated
|
295
|
-
def with_setup(share_name)
|
296
|
-
return use_setup(share_name)
|
297
|
-
end
|
298
|
-
|
299
|
-
# deprecated
|
300
|
-
def with(share_name = nil, &initialization_block)
|
301
|
-
return setup(share_name ? "with #{share_name}" : nil, &initialization_block)
|
302
|
-
end
|
303
|
-
|
304
|
-
# deprecated
|
305
|
-
def when(share_name = nil, &initialization_block)
|
306
|
-
return setup(share_name ? "when #{share_name}" : nil, &initialization_block)
|
307
|
-
end
|
308
|
-
|
309
|
-
def given(description = nil, &initialization_block)
|
310
|
-
valid_share_types = [:use_setup, :use_should, :use_context]
|
311
|
-
@failed = true and raise ArgumentError, "'given' can only appear after #{valid_share_types.join(', ')}" unless valid_share_types.include?(current_action)
|
312
|
-
|
313
|
-
add_setup_block(:given, description ? "given #{description}" : nil, &initialization_block)
|
314
|
-
end
|
315
|
-
|
316
|
-
def should(description = nil, options = {}, &should_block)
|
317
|
-
shared_context_block = Proc.new do
|
318
|
-
should share_description do
|
319
|
-
call_block_with_shared_value(should_block)
|
320
|
-
end
|
321
|
-
end
|
322
|
-
add_test_block(:should, description, &shared_context_block)
|
323
|
-
end
|
324
|
-
|
325
|
-
def use_should(share_name)
|
326
|
-
add_test_block(:use_should, share_name, &source_context.find_shared_block(:should, share_name))
|
327
|
-
end
|
328
|
-
|
329
|
-
def context(description = nil, &context_block)
|
330
|
-
shared_context_block = Proc.new do
|
331
|
-
context share_description do
|
332
|
-
merge_block(&context_block)
|
333
|
-
end
|
334
|
-
end
|
335
|
-
add_test_block(:context, description, &shared_context_block)
|
336
|
-
end
|
337
|
-
|
338
|
-
def use_context(share_name)
|
339
|
-
add_test_block(:use_context, share_name, &source_context.find_shared_block(:context, share_name))
|
340
|
-
end
|
341
|
-
|
342
|
-
def share_execute
|
343
|
-
return if @failed
|
344
|
-
|
345
|
-
shared_proxy = self
|
346
|
-
if test_type == :should || test_type == :context || test_type == :use_should || test_type == :use_context
|
347
|
-
# create a new context for setups and should/context
|
348
|
-
source_context.context setup_block_configs_description do
|
349
|
-
setup_without_param_support do
|
350
|
-
shared_proxy.setup_block_configs.each do |config|
|
351
|
-
call_block_config(config)
|
352
|
-
end
|
353
|
-
end
|
354
|
-
|
355
|
-
# share_description called when creating test names
|
356
|
-
self.instance_variable_set("@share_description", shared_proxy.send(:test_description))
|
357
|
-
def self.share_description; @share_description; end
|
358
|
-
merge_block(&shared_proxy.test_block)
|
359
|
-
end
|
360
|
-
else
|
361
|
-
# call setups directly in this context
|
362
|
-
source_context.setup_without_param_support do
|
363
|
-
shared_proxy.setup_block_configs.each do |config|
|
364
|
-
call_block_config(config)
|
365
|
-
end
|
366
|
-
end
|
367
|
-
end
|
368
|
-
end
|
369
|
-
|
370
|
-
private
|
371
|
-
|
372
|
-
def setup_block_configs_description
|
373
|
-
@setup_block_configs_description
|
374
|
-
end
|
375
|
-
|
376
|
-
def add_test_block(test_type, description, &test_block)
|
377
|
-
@failed = true and raise ArgumentError, 'Only a single should or context can be chained' if self.test_type
|
378
|
-
|
379
|
-
self.test_type = test_type
|
380
|
-
self.current_action = test_type
|
381
|
-
self.test_description = description
|
382
|
-
self.test_block = test_block
|
383
|
-
return self
|
384
|
-
end
|
385
|
-
|
386
|
-
def add_setup_block(action, description, &block)
|
387
|
-
if test_type
|
388
|
-
#@failed = true and raise ArgumentError, "'#{action}' may not be applied" unless action == :given
|
389
|
-
# add final given description to test description
|
390
|
-
self.test_description = "#{test_description} #{description}" if description
|
391
|
-
description = nil
|
392
|
-
end
|
393
|
-
|
394
|
-
setup_block_config = {:block => block, :action => action, :description => description}
|
395
|
-
if action == :given and (current_action == :setup || current_action == :use_setup)
|
396
|
-
setup_block_configs.insert(-2, setup_block_config)
|
397
|
-
else
|
398
|
-
setup_block_configs << setup_block_config
|
399
|
-
end
|
400
|
-
if description
|
401
|
-
@setup_block_configs_description = "#{@setup_block_configs_description}#{' ' if @setup_block_configs_description}#{description}"
|
402
|
-
end
|
403
|
-
|
404
|
-
self.current_action = action
|
405
|
-
return self
|
406
|
-
end
|
407
|
-
end
|
6
|
+
require 'test_class_helper'
|
7
|
+
require 'shared_context'
|
8
|
+
require 'shared_proxy'
|
9
|
+
require 'test_unit_hooks'
|
data/shared_should.gemspec
CHANGED
@@ -4,14 +4,14 @@
|
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
|
-
s.name =
|
8
|
-
s.version = "0.8.
|
7
|
+
s.name = "shared_should"
|
8
|
+
s.version = "0.8.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Michael Pearce"]
|
12
|
-
s.date =
|
13
|
-
s.description =
|
14
|
-
s.email =
|
12
|
+
s.date = "2012-01-06"
|
13
|
+
s.description = "Share and reuse shoulds, contexts, and setup in Shoulda."
|
14
|
+
s.email = "michael.pearce@bookrenter.com"
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE.txt",
|
17
17
|
"README.md"
|
@@ -25,16 +25,20 @@ Gem::Specification.new do |s|
|
|
25
25
|
"Rakefile",
|
26
26
|
"VERSION",
|
27
27
|
"lib/shared_should.rb",
|
28
|
+
"lib/shared_should/shared_context.rb",
|
29
|
+
"lib/shared_should/shared_proxy.rb",
|
30
|
+
"lib/shared_should/test_class_helper.rb",
|
31
|
+
"lib/shared_should/test_unit_hooks.rb",
|
28
32
|
"shared_should.gemspec",
|
29
33
|
"test/helper.rb",
|
30
34
|
"test/test_shared_should.rb",
|
31
35
|
"test/test_shared_should_helper.rb"
|
32
36
|
]
|
33
|
-
s.homepage =
|
37
|
+
s.homepage = "http://github.com/michaelgpearce/shared_should"
|
34
38
|
s.licenses = ["MIT"]
|
35
39
|
s.require_paths = ["lib"]
|
36
|
-
s.rubygems_version =
|
37
|
-
s.summary =
|
40
|
+
s.rubygems_version = "1.8.10"
|
41
|
+
s.summary = "Share and reuse shoulds, contexts, and setup in Shoulda."
|
38
42
|
s.test_files = [
|
39
43
|
"test/helper.rb",
|
40
44
|
"test/test_shared_should.rb",
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shared_should
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 57
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 8
|
9
|
-
-
|
10
|
-
version: 0.8.
|
9
|
+
- 3
|
10
|
+
version: 0.8.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Michael Pearce
|
@@ -15,8 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
19
|
-
default_executable:
|
18
|
+
date: 2012-01-06 00:00:00 Z
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
22
21
|
version_requirements: &id001 !ruby/object:Gem::Requirement
|
@@ -28,10 +27,10 @@ dependencies:
|
|
28
27
|
segments:
|
29
28
|
- 0
|
30
29
|
version: "0"
|
30
|
+
name: shoulda
|
31
31
|
prerelease: false
|
32
32
|
type: :development
|
33
33
|
requirement: *id001
|
34
|
-
name: shoulda
|
35
34
|
- !ruby/object:Gem::Dependency
|
36
35
|
version_requirements: &id002 !ruby/object:Gem::Requirement
|
37
36
|
none: false
|
@@ -44,10 +43,10 @@ dependencies:
|
|
44
43
|
- 0
|
45
44
|
- 0
|
46
45
|
version: 1.0.0
|
46
|
+
name: bundler
|
47
47
|
prerelease: false
|
48
48
|
type: :development
|
49
49
|
requirement: *id002
|
50
|
-
name: bundler
|
51
50
|
- !ruby/object:Gem::Dependency
|
52
51
|
version_requirements: &id003 !ruby/object:Gem::Requirement
|
53
52
|
none: false
|
@@ -60,10 +59,10 @@ dependencies:
|
|
60
59
|
- 5
|
61
60
|
- 2
|
62
61
|
version: 1.5.2
|
62
|
+
name: jeweler
|
63
63
|
prerelease: false
|
64
64
|
type: :development
|
65
65
|
requirement: *id003
|
66
|
-
name: jeweler
|
67
66
|
- !ruby/object:Gem::Dependency
|
68
67
|
version_requirements: &id004 !ruby/object:Gem::Requirement
|
69
68
|
none: false
|
@@ -74,10 +73,10 @@ dependencies:
|
|
74
73
|
segments:
|
75
74
|
- 0
|
76
75
|
version: "0"
|
76
|
+
name: rcov
|
77
77
|
prerelease: false
|
78
78
|
type: :development
|
79
79
|
requirement: *id004
|
80
|
-
name: rcov
|
81
80
|
- !ruby/object:Gem::Dependency
|
82
81
|
version_requirements: &id005 !ruby/object:Gem::Requirement
|
83
82
|
none: false
|
@@ -88,10 +87,10 @@ dependencies:
|
|
88
87
|
segments:
|
89
88
|
- 0
|
90
89
|
version: "0"
|
90
|
+
name: shoulda
|
91
91
|
prerelease: false
|
92
92
|
type: :runtime
|
93
93
|
requirement: *id005
|
94
|
-
name: shoulda
|
95
94
|
- !ruby/object:Gem::Dependency
|
96
95
|
version_requirements: &id006 !ruby/object:Gem::Requirement
|
97
96
|
none: false
|
@@ -102,10 +101,10 @@ dependencies:
|
|
102
101
|
segments:
|
103
102
|
- 0
|
104
103
|
version: "0"
|
104
|
+
name: shoulda
|
105
105
|
prerelease: false
|
106
106
|
type: :development
|
107
107
|
requirement: *id006
|
108
|
-
name: shoulda
|
109
108
|
description: Share and reuse shoulds, contexts, and setup in Shoulda.
|
110
109
|
email: michael.pearce@bookrenter.com
|
111
110
|
executables: []
|
@@ -124,11 +123,14 @@ files:
|
|
124
123
|
- Rakefile
|
125
124
|
- VERSION
|
126
125
|
- lib/shared_should.rb
|
126
|
+
- lib/shared_should/shared_context.rb
|
127
|
+
- lib/shared_should/shared_proxy.rb
|
128
|
+
- lib/shared_should/test_class_helper.rb
|
129
|
+
- lib/shared_should/test_unit_hooks.rb
|
127
130
|
- shared_should.gemspec
|
128
131
|
- test/helper.rb
|
129
132
|
- test/test_shared_should.rb
|
130
133
|
- test/test_shared_should_helper.rb
|
131
|
-
has_rdoc: true
|
132
134
|
homepage: http://github.com/michaelgpearce/shared_should
|
133
135
|
licenses:
|
134
136
|
- MIT
|
@@ -158,7 +160,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
158
160
|
requirements: []
|
159
161
|
|
160
162
|
rubyforge_project:
|
161
|
-
rubygems_version: 1.
|
163
|
+
rubygems_version: 1.8.10
|
162
164
|
signing_key:
|
163
165
|
specification_version: 3
|
164
166
|
summary: Share and reuse shoulds, contexts, and setup in Shoulda.
|