jeremymcanally-context 0.0.3 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/config/hoe.rb +1 -1
- data/config/requirements.rb +1 -1
- data/context.gemspec +1 -1
- data/lib/context/context.rb +9 -1
- data/lib/context/core_ext/string.rb +6 -1
- data/lib/context/lifecycle.rb +52 -5
- data/lib/context/shared_behavior.rb +22 -2
- data/lib/context/suite.rb +33 -14
- data/lib/context/test.rb +1 -1
- data/lib/context/version.rb +1 -1
- data/test/test_lifecycle.rb +122 -9
- metadata +1 -1
data/config/hoe.rb
CHANGED
@@ -56,7 +56,7 @@ $hoe = Hoe.new(GEM_NAME, VERS) do |p|
|
|
56
56
|
p.summary = DESCRIPTION
|
57
57
|
p.url = HOMEPATH
|
58
58
|
p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
|
59
|
-
p.test_globs = ["test
|
59
|
+
p.test_globs = ["test/test_*.rb"]
|
60
60
|
p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] #An array of file patterns to delete on clean.
|
61
61
|
|
62
62
|
# == Optional
|
data/config/requirements.rb
CHANGED
data/context.gemspec
CHANGED
data/lib/context/context.rb
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
class Test::Unit::TestCase
|
2
2
|
class << self
|
3
|
+
# Test::Unit uses ObjectSpace to figure out what Test::Unit:TestCase instances are running
|
4
|
+
# Contexts are not named and therefore sometimes get garbage collected.
|
5
|
+
# Think of #context_list as the shelter for nameless contexts
|
6
|
+
attr_accessor :context_list
|
7
|
+
|
3
8
|
def context_name #:nodoc:
|
4
9
|
@context_name ||= ""
|
5
10
|
if superclass.respond_to?(:context_name)
|
@@ -41,9 +46,12 @@ class Test::Unit::TestCase
|
|
41
46
|
def context(name, &block)
|
42
47
|
cls = Class.new(self)
|
43
48
|
cls.context_name = name
|
44
|
-
puts "Creating context #{cls.context_name}"
|
49
|
+
# puts "Creating context #{cls.context_name}"
|
45
50
|
cls.class_eval(&block)
|
51
|
+
(self.context_list ||= []) << cls
|
46
52
|
|
53
|
+
# TODO: Find a better way to uniquely identify classes
|
54
|
+
const_set("Test#{name.to_class_name}#{cls.object_id}", cls)
|
47
55
|
cls
|
48
56
|
end
|
49
57
|
|
@@ -1,11 +1,16 @@
|
|
1
1
|
class String
|
2
2
|
# Replaces spaces and tabs with _ so we can use the string as a method name
|
3
3
|
def to_method_name
|
4
|
-
self.downcase.gsub(
|
4
|
+
self.downcase.gsub(/[\s:']+/,'_')
|
5
5
|
end
|
6
6
|
|
7
7
|
# Borrowed from +camelize+ in ActiveSupport
|
8
8
|
def to_module_name
|
9
9
|
self.to_method_name.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
|
10
10
|
end
|
11
|
+
|
12
|
+
# Borrowed from +camelize+ in ActiveSupport
|
13
|
+
def to_class_name
|
14
|
+
self.to_method_name.gsub(/\/(.?)/) { "#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
|
15
|
+
end
|
11
16
|
end
|
data/lib/context/lifecycle.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
class Test::Unit::TestCase
|
2
|
-
# TODO: Chained lifecycle methods
|
3
2
|
class << self
|
3
|
+
attr_accessor :before_each_callbacks, :before_all_callbacks, :after_each_callbacks, :after_all_callbacks
|
4
|
+
|
4
5
|
# Add logic to run before the tests (i.e., a +setup+ method)
|
5
6
|
#
|
6
7
|
# before do
|
7
8
|
# @user = User.first
|
8
9
|
# end
|
9
10
|
#
|
10
|
-
def before(&block)
|
11
|
-
|
11
|
+
def before(period = :each, &block)
|
12
|
+
send("before_#{period}_callbacks") << block
|
12
13
|
end
|
13
14
|
|
14
15
|
# Add logic to run after the tests (i.e., a +teardown+ method)
|
@@ -17,8 +18,54 @@ class Test::Unit::TestCase
|
|
17
18
|
# User.delete_all
|
18
19
|
# end
|
19
20
|
#
|
20
|
-
def after(&block)
|
21
|
-
|
21
|
+
def after(period = :each, &block)
|
22
|
+
send("after_#{period}_callbacks") << block
|
23
|
+
end
|
24
|
+
|
25
|
+
def gather_callbacks(callback_type, period)
|
26
|
+
callbacks = superclass.respond_to?(:gather_callbacks) ? superclass.gather_callbacks(callback_type, period) : []
|
27
|
+
callbacks.push(*send("#{callback_type}_#{period}_callbacks"))
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
self.before_all_callbacks = []
|
32
|
+
self.before_each_callbacks = []
|
33
|
+
self.after_each_callbacks = []
|
34
|
+
self.after_all_callbacks = []
|
35
|
+
|
36
|
+
def self.inherited(child)
|
37
|
+
super
|
38
|
+
child.before_all_callbacks = []
|
39
|
+
child.before_each_callbacks = []
|
40
|
+
child.after_each_callbacks = []
|
41
|
+
child.after_all_callbacks = []
|
42
|
+
|
43
|
+
child.class_eval do
|
44
|
+
def setup
|
45
|
+
run_each_callbacks :before
|
46
|
+
end
|
47
|
+
|
48
|
+
def teardown
|
49
|
+
run_each_callbacks :after
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def run_each_callbacks(callback_type)
|
55
|
+
self.class.gather_callbacks(callback_type, :each).each { |c| instance_eval(&c) }
|
56
|
+
end
|
57
|
+
|
58
|
+
def run_all_callbacks(callback_type)
|
59
|
+
previous_ivars = instance_variables
|
60
|
+
self.class.gather_callbacks(callback_type, :all).each { |c| instance_eval(&c) }
|
61
|
+
(instance_variables - previous_ivars).inject({}) do |hash, ivar|
|
62
|
+
hash.update ivar => instance_variable_get(ivar)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def set_values_from_callbacks(values)
|
67
|
+
values.each do |name, value|
|
68
|
+
instance_variable_set name, value
|
22
69
|
end
|
23
70
|
end
|
24
71
|
end
|
@@ -1,3 +1,23 @@
|
|
1
|
+
class SharedContext < Module
|
2
|
+
def self.create_from_behavior(beh)
|
3
|
+
mod = self.new
|
4
|
+
mod.behavior = beh
|
5
|
+
mod
|
6
|
+
end
|
7
|
+
|
8
|
+
def behavior=(beh)
|
9
|
+
@behavior = beh
|
10
|
+
end
|
11
|
+
|
12
|
+
def behavior
|
13
|
+
@behavior
|
14
|
+
end
|
15
|
+
|
16
|
+
def included(arg)
|
17
|
+
@behavior.call
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
1
21
|
class Test::Unit::TestCase
|
2
22
|
class << self
|
3
23
|
def shared(name, &block)
|
@@ -10,14 +30,14 @@ class Test::Unit::TestCase
|
|
10
30
|
raise ArgumentError, "Provide a String or Symbol as the name of the shared behavior group"
|
11
31
|
end
|
12
32
|
|
13
|
-
Object.const_set(name,
|
33
|
+
Object.const_set(name, SharedContext.create_from_behavior(block))
|
14
34
|
end
|
15
35
|
|
16
36
|
%w(shared_behavior share_as share_behavior_as shared_examples_for).each {|m| alias_method m, :shared}
|
17
37
|
|
18
38
|
def use(shared_name)
|
19
39
|
case shared_name.class.name
|
20
|
-
when "Module"
|
40
|
+
when "SharedContext", "Module"
|
21
41
|
include shared_name
|
22
42
|
when "String"
|
23
43
|
include Object.const_get(shared_name.to_module_name)
|
data/lib/context/suite.rb
CHANGED
@@ -1,20 +1,39 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
module Test
|
2
|
+
module Unit
|
3
|
+
class TestCase
|
4
|
+
class << self
|
5
|
+
# Tweaks to standard method so we don't get superclass methods and we don't
|
6
|
+
# get weird default tests
|
7
|
+
def suite # :nodoc:
|
8
|
+
method_names = public_instance_methods - superclass.public_instance_methods
|
9
|
+
|
10
|
+
tests = method_names.delete_if {|method_name| method_name !~ /^test./}
|
11
|
+
suite = Test::Unit::TestSuite.new(name)
|
12
|
+
|
13
|
+
tests.sort.each do |test|
|
14
|
+
catch(:invalid_test) do
|
15
|
+
suite << new(test)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
suite
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
7
23
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
24
|
+
class TestSuite
|
25
|
+
# Runs the tests and/or suites contained in this
|
26
|
+
# TestSuite.
|
27
|
+
def run(result, &progress_block)
|
28
|
+
yield(STARTED, name)
|
29
|
+
ivars_from_callback = @tests.first.run_all_callbacks(:before) if @tests.first.is_a?(Test::Unit::TestCase)
|
30
|
+
@tests.each do |test|
|
31
|
+
test.set_values_from_callbacks(ivars_from_callback) if ivars_from_callback
|
32
|
+
test.run(result, &progress_block)
|
14
33
|
end
|
34
|
+
ivars_from_callback = @tests.first.run_all_callbacks(:after) if ivars_from_callback
|
35
|
+
yield(FINISHED, name)
|
15
36
|
end
|
16
|
-
|
17
|
-
suite
|
18
37
|
end
|
19
38
|
end
|
20
39
|
end
|
data/lib/context/test.rb
CHANGED
@@ -9,7 +9,7 @@ class Test::Unit::TestCase
|
|
9
9
|
#
|
10
10
|
def test(name, &block)
|
11
11
|
test_name = "test_#{((context_name == "" ? context_name : context_name + " ") + name).to_method_name}".to_sym
|
12
|
-
puts "running test #{test_name}"
|
12
|
+
# puts "running test #{test_name}"
|
13
13
|
defined = instance_method(test_name) rescue false
|
14
14
|
raise "#{test_name} is already defined in #{self}" if defined
|
15
15
|
|
data/lib/context/version.rb
CHANGED
data/test/test_lifecycle.rb
CHANGED
@@ -1,17 +1,130 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
2
|
|
3
3
|
class TestLifecycle < Test::Unit::TestCase
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
before do
|
5
|
+
@inherited_before_each_var = 1
|
6
|
+
end
|
7
|
+
|
8
|
+
before do
|
9
|
+
@inherited_before_each_var = 2
|
10
|
+
@inherited_before_each_var_2 = 1
|
11
|
+
end
|
12
|
+
|
13
|
+
after do
|
14
|
+
@inherited_after_each_var = 1
|
15
|
+
end
|
16
|
+
|
17
|
+
before :all do
|
18
|
+
@inherited_before_all_var = 1
|
19
|
+
end
|
20
|
+
|
21
|
+
after :all do
|
22
|
+
@inherited_after_all_var = 1
|
23
|
+
end
|
24
|
+
|
25
|
+
sample_test = context "lifecycle" do
|
26
|
+
attr_reader :inherited_before_each_var, :inherited_before_each_var_2, :inherited_after_each_var,
|
27
|
+
:after_each_var, :inherited_before_all_var, :inherited_after_all_var, :before_all_var, :after_all_var,
|
28
|
+
:superclass_before_each_var, :superclass_after_each_var, :superclass_before_all_var, :superclass_after_all_var
|
29
|
+
|
30
|
+
before do
|
31
|
+
@inherited_before_each_var = 3
|
32
|
+
end
|
33
|
+
|
34
|
+
after do
|
35
|
+
@after_each_var = 1
|
36
|
+
end
|
37
|
+
|
38
|
+
before :all do
|
39
|
+
@before_all_var = 1
|
40
|
+
end
|
41
|
+
|
42
|
+
after :all do
|
43
|
+
@after_all_var = 1
|
8
44
|
end
|
45
|
+
|
46
|
+
test "foo" do
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
before do
|
51
|
+
@superclass_before_each_var = 1
|
9
52
|
end
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
53
|
+
|
54
|
+
after do
|
55
|
+
@superclass_after_each_var = 1
|
56
|
+
end
|
57
|
+
|
58
|
+
before :all do
|
59
|
+
@superclass_before_all_var = 1
|
60
|
+
end
|
61
|
+
|
62
|
+
after :all do
|
63
|
+
@superclass_after_all_var = 1
|
64
|
+
end
|
65
|
+
|
66
|
+
context "With before/after :each blocks" do
|
67
|
+
before do
|
68
|
+
@result = Test::Unit::TestResult.new
|
69
|
+
@test = sample_test.new("test_lifecycle_foo")
|
70
|
+
@test.run(@result) { |inherited_after_each_var, v| }
|
71
|
+
end
|
72
|
+
|
73
|
+
it "it runs superclass before callbacks in order" do
|
74
|
+
assert_equal 1, @test.superclass_before_each_var
|
75
|
+
end
|
76
|
+
|
77
|
+
it "it runs inherited before callbacks in order" do
|
78
|
+
assert_equal 3, @test.inherited_before_each_var
|
79
|
+
end
|
80
|
+
|
81
|
+
it "it runs before callbacks in order" do
|
82
|
+
assert_equal 1, @test.inherited_before_each_var_2
|
83
|
+
end
|
84
|
+
|
85
|
+
it "it runs superclass after callbacks" do
|
86
|
+
assert_equal 1, @test.superclass_after_each_var
|
87
|
+
end
|
88
|
+
|
89
|
+
it "it runs inherited after callbacks" do
|
90
|
+
assert_equal 1, @test.inherited_after_each_var
|
91
|
+
end
|
92
|
+
|
93
|
+
it "it runs after callbacks" do
|
94
|
+
assert_equal 1, @test.after_each_var
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context "With before/after :all blocks" do
|
99
|
+
before do
|
100
|
+
@result = Test::Unit::TestResult.new
|
101
|
+
@suite = sample_test.suite
|
102
|
+
@suite.run(@result) { |inherited_after_each_var, v| }
|
103
|
+
@test = @suite.tests.first
|
104
|
+
end
|
105
|
+
|
106
|
+
it "it runs superclass before callbacks in order" do
|
107
|
+
assert_equal 1, @test.superclass_before_all_var
|
108
|
+
end
|
109
|
+
|
110
|
+
it "it runs inherited before callbacks in order" do
|
111
|
+
assert_equal 1, @test.inherited_before_all_var
|
112
|
+
end
|
113
|
+
|
114
|
+
it "it runs before callbacks in order" do
|
115
|
+
assert_equal 1, @test.before_all_var
|
116
|
+
end
|
117
|
+
|
118
|
+
it "it runs superclass after callbacks" do
|
119
|
+
assert_equal 1, @test.superclass_after_all_var
|
120
|
+
end
|
121
|
+
|
122
|
+
it "it runs inherited after callbacks" do
|
123
|
+
assert_equal 1, @test.inherited_after_all_var
|
124
|
+
end
|
125
|
+
|
126
|
+
it "it runs after callbacks" do
|
127
|
+
assert_equal 1, @test.after_all_var
|
15
128
|
end
|
16
129
|
end
|
17
130
|
end
|