djsun-context 0.5.5
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/History.txt +10 -0
- data/License.txt +20 -0
- data/Manifest.txt +29 -0
- data/PostInstall.txt +0 -0
- data/README.rdoc +158 -0
- data/Rakefile +4 -0
- data/config/hoe.rb +73 -0
- data/config/requirements.rb +15 -0
- data/context.gemspec +44 -0
- data/lib/context/context.rb +64 -0
- data/lib/context/core_ext/rails_hacks.rb +10 -0
- data/lib/context/core_ext/string.rb +17 -0
- data/lib/context/lifecycle.rb +103 -0
- data/lib/context/shared_behavior.rb +97 -0
- data/lib/context/suite.rb +39 -0
- data/lib/context/test.rb +37 -0
- data/lib/context/version.rb +9 -0
- data/lib/context.rb +19 -0
- data/setup.rb +1585 -0
- data/test/test_context.rb +57 -0
- data/test/test_core_ext.rb +21 -0
- data/test/test_helper.rb +2 -0
- data/test/test_lifecycle.rb +224 -0
- data/test/test_test.rb +23 -0
- metadata +79 -0
data/History.txt
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
== 0.0.3 2008-10-05
|
2
|
+
|
3
|
+
* 1 minor enhancement:
|
4
|
+
* Fiddled with the way contexts are defined; makes the object model make more sense and the code cleaner
|
5
|
+
|
6
|
+
== 0.0.1 2008-10-02
|
7
|
+
|
8
|
+
* 1 major enhancement:
|
9
|
+
* Initial release
|
10
|
+
* Contexts, lifecycle, and test methods
|
data/License.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2008 Jeremy McAnally
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Manifest.txt
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
History.txt
|
2
|
+
License.txt
|
3
|
+
Manifest.txt
|
4
|
+
PostInstall.txt
|
5
|
+
README.rdoc
|
6
|
+
Rakefile
|
7
|
+
config/hoe.rb
|
8
|
+
config/requirements.rb
|
9
|
+
context.gemspec
|
10
|
+
countloc.rb
|
11
|
+
lib/context.rb
|
12
|
+
lib/context/context.rb
|
13
|
+
lib/context/core_ext/rails_hacks.rb
|
14
|
+
lib/context/core_ext/string.rb
|
15
|
+
lib/context/lifecycle.rb
|
16
|
+
lib/context/shared_behavior.rb
|
17
|
+
lib/context/suite.rb
|
18
|
+
lib/context/test.rb
|
19
|
+
lib/context/version.rb
|
20
|
+
setup.rb
|
21
|
+
tasks/deployment.rake
|
22
|
+
tasks/environment.rake
|
23
|
+
test/test_context.rb
|
24
|
+
test/test_core_ext.rb
|
25
|
+
test/test_helper.rb
|
26
|
+
test/test_lifecycle.rb
|
27
|
+
test/test_nested_lifecycle.rb
|
28
|
+
test/test_shared.rb
|
29
|
+
test/test_test.rb
|
data/PostInstall.txt
ADDED
File without changes
|
data/README.rdoc
ADDED
@@ -0,0 +1,158 @@
|
|
1
|
+
= context – The testing library you've been looking for
|
2
|
+
|
3
|
+
http://github.com/jeremymcanally/context
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
If you've ever wanted contexts in your Test::Unit tests, then context is for you. Your tests will be easier to read and write without all the magic and extra code smell!
|
8
|
+
|
9
|
+
== FEATURES/PROBLEMS:
|
10
|
+
|
11
|
+
* Add contexts to Test::Unit tests
|
12
|
+
* Small DSL for specifying tests that are pretty
|
13
|
+
* Ability to chain context lifecycle methods (coming soon)
|
14
|
+
|
15
|
+
== SYNOPSIS:
|
16
|
+
|
17
|
+
* Add contexts using familiar syntax:
|
18
|
+
|
19
|
+
class UserTest < Test::Unit::TestCase
|
20
|
+
context "A new User" do
|
21
|
+
# Before/after lifecycle blocks
|
22
|
+
before do
|
23
|
+
@user = User.first
|
24
|
+
end
|
25
|
+
|
26
|
+
# Specify tests using DSL
|
27
|
+
test "should have the right full_name" do
|
28
|
+
assert_equal "Dude Man", @user.full_name
|
29
|
+
end
|
30
|
+
|
31
|
+
test "should be able to set parts of the name" do
|
32
|
+
@user.first_name = "Mad"
|
33
|
+
@user.last_name = "Max"
|
34
|
+
@user.save
|
35
|
+
assert_equal "Mad Max", @user.full_name
|
36
|
+
end
|
37
|
+
|
38
|
+
after do
|
39
|
+
@user.first_name = "Dude"
|
40
|
+
@user.last_name = "Man"
|
41
|
+
@user.save!
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
* It also has aliases that match other library's syntaxes (all of which can be mixed and matched):
|
47
|
+
|
48
|
+
class UserTest < Test::Unit::TestCase
|
49
|
+
context "A new Account" do
|
50
|
+
test "should be new" do
|
51
|
+
Account.new.new_record?
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# RSpec-esque
|
56
|
+
describe "A new User" do
|
57
|
+
it "should do things" do
|
58
|
+
User.first.do_things!
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Shoulda-esque
|
63
|
+
context "Another User" do
|
64
|
+
should "do things that are fun" do
|
65
|
+
User.first.do_things!(:fun)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
* Contexts can also be nested:
|
71
|
+
|
72
|
+
class UserTest < Test::Unit::TestCase
|
73
|
+
context "A new User" do
|
74
|
+
context "with clown shoes" do
|
75
|
+
test "should squeak" do
|
76
|
+
assert_true User.find_by_shoes("clown").squeak?
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context "without clown shoes" do
|
81
|
+
test "should not squeak" do
|
82
|
+
assert_false User.find_by_shoes("dressy").squeak?
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
* You can also share behavior among contexts:
|
89
|
+
|
90
|
+
class UserTest < Test::Unit::TestCase
|
91
|
+
shared "shared things" do
|
92
|
+
test "things are shared" do
|
93
|
+
# test logic here...
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context "the first thing" do
|
98
|
+
uses "shared things"
|
99
|
+
|
100
|
+
test "other things..." do
|
101
|
+
# More testing...
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
* Shared behaviors can also use RSpec syntax
|
107
|
+
|
108
|
+
class UserTest < Test::Unit::TestCase
|
109
|
+
share_examples_for "shared things" do
|
110
|
+
it "things are shared" do
|
111
|
+
# test logic here...
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe "the first thing" do
|
116
|
+
it_should_behave_like "shared things"
|
117
|
+
|
118
|
+
it "other things..." do
|
119
|
+
# More testing...
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
== REQUIREMENTS:
|
125
|
+
|
126
|
+
* Test::Unit (you have it; trust me)
|
127
|
+
|
128
|
+
== INSTALL:
|
129
|
+
|
130
|
+
$ gem sources -a http://gems.github.com
|
131
|
+
$ sudo gem install jeremymcanally-context
|
132
|
+
|
133
|
+
== LICENSE:
|
134
|
+
|
135
|
+
Copyright (c) 2008 Jeremy McAnally
|
136
|
+
|
137
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
138
|
+
a copy of this software and associated documentation files (the
|
139
|
+
'Software'), to deal in the Software without restriction, including
|
140
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
141
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
142
|
+
permit persons to whom the Software is furnished to do so, subject to
|
143
|
+
the following conditions:
|
144
|
+
|
145
|
+
The above copyright notice and this permission notice shall be
|
146
|
+
included in all copies or substantial portions of the Software.
|
147
|
+
|
148
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
149
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
150
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
151
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
152
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
153
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
154
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
155
|
+
|
156
|
+
== ACKNOWLEDGEMENTS:
|
157
|
+
|
158
|
+
Original implementation by myself, but heavily tweaked and borrowed from Rails Core and Pratik Naik.
|
data/Rakefile
ADDED
data/config/hoe.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'context/version'
|
2
|
+
|
3
|
+
AUTHOR = 'Jeremy McAnally' # can also be an array of Authors
|
4
|
+
EMAIL = "jeremy@entp.com"
|
5
|
+
DESCRIPTION = "Contexts and DSL sugar for your tests"
|
6
|
+
GEM_NAME = 'context' # what ppl will type to install your gem
|
7
|
+
RUBYFORGE_PROJECT = 'context' # The unix name for your project
|
8
|
+
HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
|
9
|
+
DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
|
10
|
+
EXTRA_DEPENDENCIES = [
|
11
|
+
# ['activesupport', '>= 1.3.1']
|
12
|
+
] # An array of rubygem dependencies [name, version]
|
13
|
+
|
14
|
+
@config_file = "~/.rubyforge/user-config.yml"
|
15
|
+
@config = nil
|
16
|
+
RUBYFORGE_USERNAME = "unknown"
|
17
|
+
def rubyforge_username
|
18
|
+
unless @config
|
19
|
+
begin
|
20
|
+
@config = YAML.load(File.read(File.expand_path(@config_file)))
|
21
|
+
rescue
|
22
|
+
puts <<-EOS
|
23
|
+
ERROR: No rubyforge config file found: #{@config_file}
|
24
|
+
Run 'rubyforge setup' to prepare your env for access to Rubyforge
|
25
|
+
- See http://newgem.rubyforge.org/rubyforge.html for more details
|
26
|
+
EOS
|
27
|
+
exit
|
28
|
+
end
|
29
|
+
end
|
30
|
+
RUBYFORGE_USERNAME.replace @config["username"]
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
REV = nil
|
35
|
+
# UNCOMMENT IF REQUIRED:
|
36
|
+
# REV = YAML.load(`svn info`)['Revision']
|
37
|
+
VERS = Context::VERSION::STRING + (REV ? ".#{REV}" : "")
|
38
|
+
RDOC_OPTS = ['--quiet', '--title', 'context documentation',
|
39
|
+
"--opname", "index.html",
|
40
|
+
"--line-numbers",
|
41
|
+
"--main", "README.rdoc",
|
42
|
+
"--inline-source"]
|
43
|
+
|
44
|
+
class Hoe
|
45
|
+
def extra_deps
|
46
|
+
@extra_deps.reject! { |x| Array(x).first == 'hoe' }
|
47
|
+
@extra_deps
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Generate all the Rake tasks
|
52
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
53
|
+
$hoe = Hoe.new(GEM_NAME, VERS) do |p|
|
54
|
+
p.developer(AUTHOR, EMAIL)
|
55
|
+
p.description = DESCRIPTION
|
56
|
+
p.summary = DESCRIPTION
|
57
|
+
p.url = HOMEPATH
|
58
|
+
p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
|
59
|
+
p.test_globs = ["test/test_*.rb"]
|
60
|
+
p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] #An array of file patterns to delete on clean.
|
61
|
+
|
62
|
+
# == Optional
|
63
|
+
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
|
64
|
+
#p.extra_deps = EXTRA_DEPENDENCIES
|
65
|
+
|
66
|
+
#p.spec_extras = {} # A hash of extra values to set in the gemspec.
|
67
|
+
end
|
68
|
+
|
69
|
+
CHANGES = $hoe.paragraphs_of('History.txt', 0..1).join("\\n\\n")
|
70
|
+
PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
|
71
|
+
$hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), 'rdoc')
|
72
|
+
$hoe.rsync_args = '-av --delete --ignore-errors'
|
73
|
+
$hoe.spec.post_install_message = File.open(File.dirname(__FILE__) + "/../PostInstall.txt").read rescue ""
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
include FileUtils
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
%w[rake hoe].each do |req_gem|
|
6
|
+
begin
|
7
|
+
require req_gem
|
8
|
+
rescue LoadError
|
9
|
+
puts "This Rakefile requires the '#{req_gem}' RubyGem."
|
10
|
+
puts "Installation: gem install #{req_gem} -y"
|
11
|
+
exit
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
$:.unshift(File.join(File.dirname(__FILE__), %w[.. lib]))
|
data/context.gemspec
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "context"
|
3
|
+
s.version = "0.5.5"
|
4
|
+
s.date = "2008-10-03"
|
5
|
+
s.summary = "Contexts and DSL sugar for your tests"
|
6
|
+
s.email = "jeremy@entp.com"
|
7
|
+
s.homepage = "http://github.com/jeremymcanally/context"
|
8
|
+
s.description = "If you've ever wanted contexts in your Test::Unit tests, then context is for you. Your tests will be easier to read and write without all the magic and extra code smell!"
|
9
|
+
s.has_rdoc = true
|
10
|
+
s.authors = ["Jeremy McAnally"]
|
11
|
+
s.files = [
|
12
|
+
"README.rdoc",
|
13
|
+
"Rakefile",
|
14
|
+
"context.gemspec",
|
15
|
+
"History.txt",
|
16
|
+
"License.txt",
|
17
|
+
"Manifest.txt",
|
18
|
+
"PostInstall.txt",
|
19
|
+
"config/hoe.rb",
|
20
|
+
"config/requirements.rb",
|
21
|
+
"lib/context.rb",
|
22
|
+
"lib/context/version.rb",
|
23
|
+
"lib/context/lifecycle.rb",
|
24
|
+
"lib/context/suite.rb",
|
25
|
+
"lib/context/context.rb",
|
26
|
+
"lib/context/shared_behavior.rb",
|
27
|
+
"lib/context/test.rb",
|
28
|
+
"lib/context/version.rb",
|
29
|
+
"lib/context/core_ext/string.rb",
|
30
|
+
"lib/context/core_ext/rails_hacks.rb",
|
31
|
+
"setup.rb"
|
32
|
+
]
|
33
|
+
|
34
|
+
s.test_files = [
|
35
|
+
"test/test_context.rb",
|
36
|
+
"test/test_core_ext.rb",
|
37
|
+
"test/test_lifecycle.rb",
|
38
|
+
"test/test_test.rb",
|
39
|
+
"test/test_helper.rb"
|
40
|
+
]
|
41
|
+
|
42
|
+
s.rdoc_options = ["--main", "README.rdoc"]
|
43
|
+
s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.rdoc"]
|
44
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Context
|
2
|
+
module Context
|
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
|
+
|
8
|
+
def context_name #:nodoc:
|
9
|
+
@context_name ||= ""
|
10
|
+
if superclass.respond_to?(:context_name)
|
11
|
+
return "#{superclass.context_name} #{@context_name}".gsub(/^\s+/, "")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def context_name=(val) #:nodoc:
|
16
|
+
@context_name = val
|
17
|
+
end
|
18
|
+
|
19
|
+
# Add a context to a set of tests.
|
20
|
+
#
|
21
|
+
# context "A new account" do
|
22
|
+
# it "should not have users"
|
23
|
+
# assert Account.new.users.empty?
|
24
|
+
# end
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# The context name is prepended to the test name, so failures look like this:
|
28
|
+
#
|
29
|
+
# 1) Failure:
|
30
|
+
# test_a_new_account_should_not_have_users() [./test/test_accounts.rb:4]:
|
31
|
+
# <false> is not true.
|
32
|
+
#
|
33
|
+
# Contexts can also be nested like so:
|
34
|
+
#
|
35
|
+
# context "A new account" do
|
36
|
+
# context "created by the web application" do
|
37
|
+
# it "should have web as its vendor" do
|
38
|
+
# assert_equal "web", users(:web_user).vendor
|
39
|
+
# end
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# Since contexts create a singleton instance of a class, each one must have its own before/after blocks. This
|
44
|
+
# will be tweaked in future releases to allow you to chain these blocks from its parent contexts.
|
45
|
+
#
|
46
|
+
def context(name, &block)
|
47
|
+
cls = Class.new(self)
|
48
|
+
cls.context_name = name
|
49
|
+
# puts "Creating context #{cls.context_name}"
|
50
|
+
|
51
|
+
# Care about Rails tests in nested contexts
|
52
|
+
cls.tests($1.constantize) if defined?(Rails) &&
|
53
|
+
self.name =~ /^(.*(Controller|Helper|Mailer))Test/ &&
|
54
|
+
self < ActiveSupport::TestCase
|
55
|
+
|
56
|
+
cls.class_eval(&block)
|
57
|
+
(self.context_list ||= []) << cls
|
58
|
+
const_set("Test#{name.to_class_name}#{cls.object_id.abs}", cls)
|
59
|
+
cls
|
60
|
+
end
|
61
|
+
|
62
|
+
%w(contexts describe describes group specify specifies).each {|m| alias_method m, :context}
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class String
|
2
|
+
# Replaces spaces and tabs with _ so we can use the string as a method name
|
3
|
+
# Also replace dangerous punctuation
|
4
|
+
def to_method_name
|
5
|
+
self.downcase.gsub(/[\s:',\.~;!#=\(\)&]+/,'_')
|
6
|
+
end
|
7
|
+
|
8
|
+
# Borrowed from +camelize+ in ActiveSupport
|
9
|
+
def to_module_name
|
10
|
+
self.to_method_name.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
|
11
|
+
end
|
12
|
+
|
13
|
+
# Borrowed from +camelize+ in ActiveSupport
|
14
|
+
def to_class_name
|
15
|
+
self.to_method_name.gsub(/\/(.?)/) { "#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
class Test::Unit::TestCase
|
2
|
+
class << self
|
3
|
+
attr_accessor :before_each_callbacks, :before_all_callbacks, :after_each_callbacks, :after_all_callbacks, :before_should_callbacks
|
4
|
+
|
5
|
+
# Add logic to run before the tests (i.e., a +setup+ method)
|
6
|
+
#
|
7
|
+
# before do
|
8
|
+
# @user = User.first
|
9
|
+
# end
|
10
|
+
#
|
11
|
+
def before(period = :each, &block)
|
12
|
+
unless block_given?
|
13
|
+
block = period
|
14
|
+
period = :each
|
15
|
+
end
|
16
|
+
|
17
|
+
send("before_#{period}_callbacks") << block
|
18
|
+
end
|
19
|
+
|
20
|
+
alias :setup :before
|
21
|
+
|
22
|
+
# Add logic to run after the tests (i.e., a +teardown+ method)
|
23
|
+
#
|
24
|
+
# after do
|
25
|
+
# User.delete_all
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
def after(period = :each, &block)
|
29
|
+
unless block_given?
|
30
|
+
block = period
|
31
|
+
period = :each
|
32
|
+
end
|
33
|
+
|
34
|
+
send("after_#{period}_callbacks") << block
|
35
|
+
end
|
36
|
+
|
37
|
+
alias :teardown :after
|
38
|
+
|
39
|
+
def gather_callbacks(callback_type, period) # :nodoc:
|
40
|
+
callbacks = superclass.respond_to?(:gather_callbacks) ? superclass.gather_callbacks(callback_type, period) : []
|
41
|
+
callbacks.push(*send("#{callback_type}_#{period}_callbacks"))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
self.before_all_callbacks = []
|
46
|
+
self.before_each_callbacks = []
|
47
|
+
self.after_each_callbacks = []
|
48
|
+
self.after_all_callbacks = []
|
49
|
+
self.before_should_callbacks = {}
|
50
|
+
|
51
|
+
def self.inherited(child) # :nodoc:
|
52
|
+
super
|
53
|
+
child.before_all_callbacks = []
|
54
|
+
child.before_each_callbacks = []
|
55
|
+
child.after_each_callbacks = []
|
56
|
+
child.after_all_callbacks = []
|
57
|
+
child.before_should_callbacks = {}
|
58
|
+
|
59
|
+
child.class_eval do
|
60
|
+
def setup(&block)
|
61
|
+
super
|
62
|
+
|
63
|
+
unless self.class.before_should_callbacks[method_name].nil?
|
64
|
+
instance_eval(&self.class.before_should_callbacks[method_name])
|
65
|
+
end
|
66
|
+
|
67
|
+
run_each_callbacks :before
|
68
|
+
end
|
69
|
+
|
70
|
+
def teardown
|
71
|
+
super
|
72
|
+
|
73
|
+
run_each_callbacks :after
|
74
|
+
end
|
75
|
+
end if self == Test::Unit::TestCase
|
76
|
+
end
|
77
|
+
|
78
|
+
def run_each_callbacks(callback_type) # :nodoc:
|
79
|
+
self.class.gather_callbacks(callback_type, :each).each do |c|
|
80
|
+
c.is_a?(Proc) ? instance_eval(&c) : send(c)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def run_all_callbacks(callback_type) # :nodoc:
|
85
|
+
previous_ivars = instance_variables
|
86
|
+
self.class.gather_callbacks(callback_type, :all).each { |c| instance_eval(&c) if c }
|
87
|
+
(instance_variables - previous_ivars).inject({}) do |hash, ivar|
|
88
|
+
hash.update ivar => instance_variable_get(ivar)
|
89
|
+
end
|
90
|
+
rescue Object => exception
|
91
|
+
raise <<-BANG
|
92
|
+
Error running the #{callback_type}(:all) callback for #{name}
|
93
|
+
#{exception.class.name}: #{exception.message}
|
94
|
+
#{exception.backtrace.join("\n")}
|
95
|
+
BANG
|
96
|
+
end
|
97
|
+
|
98
|
+
def set_values_from_callbacks(values) # :nodoc:
|
99
|
+
values.each do |name, value|
|
100
|
+
instance_variable_set name, value
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module Context
|
2
|
+
class SharedBehavior < Module
|
3
|
+
def self.create_from_behavior(beh) # :nodoc:
|
4
|
+
mod = self.new
|
5
|
+
mod._behavior = beh
|
6
|
+
mod
|
7
|
+
end
|
8
|
+
|
9
|
+
def _behavior=(beh) # :nodoc:
|
10
|
+
@_behavior = beh
|
11
|
+
end
|
12
|
+
|
13
|
+
def included(including_module) # :nodoc:
|
14
|
+
including_module.class_eval(&@_behavior)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class Test::Unit::TestCase
|
20
|
+
class << self
|
21
|
+
# Share behavior among different contexts. This creates a module (actually, a Module subclass)
|
22
|
+
# that is included using the +use+ method (or one of its aliases) provided by context or +include+
|
23
|
+
# if you know the module's constant name.
|
24
|
+
#
|
25
|
+
# ==== Examples
|
26
|
+
#
|
27
|
+
# shared "other things" do
|
28
|
+
# it "should do things but not some things" do
|
29
|
+
# # behavior is fun
|
30
|
+
# end
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# use "other things"
|
34
|
+
# # or...
|
35
|
+
# it_should_behave_like "other things"
|
36
|
+
#
|
37
|
+
# shared :client do
|
38
|
+
# it "should be a client to our server" do
|
39
|
+
# # TODO: client behavior here
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# use :client
|
44
|
+
# # or...
|
45
|
+
# uses "client"
|
46
|
+
# behaves_like "client"
|
47
|
+
#
|
48
|
+
def shared(name, &block)
|
49
|
+
case name.class.name
|
50
|
+
when "String"
|
51
|
+
name = name.to_module_name
|
52
|
+
when "Symbol"
|
53
|
+
name = name.to_s.to_module_name
|
54
|
+
else
|
55
|
+
raise ArgumentError, "Provide a String or Symbol as the name of the shared behavior group"
|
56
|
+
end
|
57
|
+
|
58
|
+
Object.const_set(name, Context::SharedBehavior.create_from_behavior(block))
|
59
|
+
end
|
60
|
+
|
61
|
+
%w(shared_behavior share_as share_behavior_as shared_examples_for).each {|m| alias_method m, :shared}
|
62
|
+
|
63
|
+
# Pull in behavior shared by +shared+ or a module.
|
64
|
+
#
|
65
|
+
# ==== Examples
|
66
|
+
#
|
67
|
+
# shared "other things" do
|
68
|
+
# it "should do things but not some things" do
|
69
|
+
# # behavior is fun
|
70
|
+
# end
|
71
|
+
# end
|
72
|
+
#
|
73
|
+
# use "other things"
|
74
|
+
# # or...
|
75
|
+
# it_should_behave_like "other things"
|
76
|
+
#
|
77
|
+
# module Things
|
78
|
+
# end
|
79
|
+
#
|
80
|
+
# uses Things
|
81
|
+
#
|
82
|
+
def use(shared_name)
|
83
|
+
case shared_name.class.name
|
84
|
+
when "Context::SharedBehavior", "Module"
|
85
|
+
include shared_name
|
86
|
+
when "String"
|
87
|
+
include Object.const_get(shared_name.to_module_name)
|
88
|
+
when "Symbol"
|
89
|
+
include Object.const_get(shared_name.to_s.to_module_name)
|
90
|
+
else
|
91
|
+
raise ArgumentError, "Provide a String or Symbol as the name of the shared behavior group or the module name"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
%w(uses it_should_behave_like behaves_like uses_examples_from).each {|m| alias_method m, :use}
|
96
|
+
end
|
97
|
+
end
|