tu-context 0.5.7
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +21 -0
- data/History.txt +10 -0
- data/License.txt +20 -0
- data/Manifest.txt +30 -0
- data/PostInstall.txt +0 -0
- data/README.rdoc +159 -0
- data/Rakefile +52 -0
- data/VERSION +1 -0
- data/config/hoe.rb +73 -0
- data/config/requirements.rb +15 -0
- data/context.gemspec +44 -0
- data/countloc.rb +65 -0
- data/lib/context.rb +19 -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/setup.rb +1585 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/environment.rake +7 -0
- data/test/test_context.rb +57 -0
- data/test/test_core_ext.rb +25 -0
- data/test/test_helper.rb +2 -0
- data/test/test_lifecycle.rb +224 -0
- data/test/test_nested_lifecycle.rb +44 -0
- data/test/test_shared.rb +116 -0
- data/test/test_shared_lifecycle.rb +24 -0
- data/test/test_test.rb +23 -0
- metadata +108 -0
data/countloc.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
|
2
|
+
def extract_path(argv)
|
3
|
+
if argv[1].nil?
|
4
|
+
if argv[0] =~ /-a/
|
5
|
+
return "/**/*.rb"
|
6
|
+
elsif argv[0]
|
7
|
+
if argv[0] =~ /\.rb$/
|
8
|
+
return argv[0]
|
9
|
+
end
|
10
|
+
return argv[0] + "/**/*.rb"
|
11
|
+
else
|
12
|
+
return "/**/*.rb"
|
13
|
+
end
|
14
|
+
elsif argv[1] =~ /\.rb$/
|
15
|
+
return argv[1]
|
16
|
+
else
|
17
|
+
return argv[1] + "/**/*.rb"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def all?
|
22
|
+
ARGV.join =~ /-a/
|
23
|
+
end
|
24
|
+
|
25
|
+
def comment?(line)
|
26
|
+
line =~ /^\s*#/
|
27
|
+
end
|
28
|
+
|
29
|
+
def blank?(line)
|
30
|
+
line =~ /^\s*$/
|
31
|
+
end
|
32
|
+
|
33
|
+
def puke(header, locs, comments, blanks)
|
34
|
+
puts header + ":"
|
35
|
+
puts "#{locs} loc"
|
36
|
+
puts "#{comments} lines of comments"
|
37
|
+
puts "#{blanks} blank lines"
|
38
|
+
end
|
39
|
+
|
40
|
+
dir = File.dirname(__FILE__)
|
41
|
+
full_path = File.join(dir,extract_path(ARGV))
|
42
|
+
gloc = gcmts = gblanks = 0
|
43
|
+
Dir[File.expand_path("#{full_path}")].uniq.each do |file|
|
44
|
+
if file =~ /.*\.rb$/
|
45
|
+
|
46
|
+
loc = cmts = blanks = 0
|
47
|
+
|
48
|
+
File.open(file, "r") do |f|
|
49
|
+
while f.gets
|
50
|
+
if comment?($_)
|
51
|
+
cmts += 1
|
52
|
+
elsif blank?($_)
|
53
|
+
blanks += 1
|
54
|
+
else
|
55
|
+
loc += 1
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
gcmts += cmts
|
60
|
+
gloc += loc
|
61
|
+
gblanks += blanks
|
62
|
+
puke(file, loc, cmts, blanks) if all?
|
63
|
+
end
|
64
|
+
end
|
65
|
+
puke("Total", gloc, gcmts, gblanks)
|
data/lib/context.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
2
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'test/unit'
|
6
|
+
|
7
|
+
require 'context/core_ext/string'
|
8
|
+
require 'context/core_ext/rails_hacks'
|
9
|
+
|
10
|
+
require 'context/version'
|
11
|
+
require 'context/suite'
|
12
|
+
require 'context/test'
|
13
|
+
require 'context/lifecycle'
|
14
|
+
require 'context/context'
|
15
|
+
require 'context/shared_behavior'
|
16
|
+
|
17
|
+
class Test::Unit::TestCase
|
18
|
+
extend Context::Context
|
19
|
+
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
|
@@ -0,0 +1,39 @@
|
|
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
|
23
|
+
|
24
|
+
class TestSuite
|
25
|
+
# Runs the tests and/or suites contained in this
|
26
|
+
# TestSuite.
|
27
|
+
def run(result, &progress_block) # :nodoc:
|
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)
|
33
|
+
end
|
34
|
+
ivars_from_callback = @tests.first.run_all_callbacks(:after) if ivars_from_callback
|
35
|
+
yield(FINISHED, name)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/context/test.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
class Test::Unit::TestCase
|
2
|
+
class << self
|
3
|
+
# Create a test method. +name+ is a native-language string to describe the test
|
4
|
+
# (e.g., no more +test_this_crazy_thing_with_underscores+).
|
5
|
+
#
|
6
|
+
# test "A user should not be able to delete another user" do
|
7
|
+
# assert_false @user.can?(:delete, @other_user)
|
8
|
+
# end
|
9
|
+
#
|
10
|
+
def test(name, opts={}, &block)
|
11
|
+
test_name = ["test:", context_name, name].reject { |n| n == "" }.join(' ')
|
12
|
+
# puts "running test #{test_name}"
|
13
|
+
defined = instance_method(test_name) rescue false
|
14
|
+
raise "#{test_name} is already defined in #{self}" if defined
|
15
|
+
|
16
|
+
unless opts[:before].nil?
|
17
|
+
before_should_callbacks[test_name] = opts[:before]
|
18
|
+
end
|
19
|
+
|
20
|
+
if block_given?
|
21
|
+
define_method(test_name, &block)
|
22
|
+
else
|
23
|
+
define_method(test_name) do
|
24
|
+
flunk "No implementation provided for #{name}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
%w(it should tests).each {|m| alias_method m, :test}
|
30
|
+
|
31
|
+
def before_test(name, &block)
|
32
|
+
test(name, :before => block) {}
|
33
|
+
end
|
34
|
+
|
35
|
+
%w(before_it before_should before_tests).each {|m| alias_method m, :before_test}
|
36
|
+
end
|
37
|
+
end
|