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 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/**/test_*.rb"]
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
@@ -2,7 +2,7 @@ require 'fileutils'
2
2
  include FileUtils
3
3
 
4
4
  require 'rubygems'
5
- %w[rake hoe newgem rubigen].each do |req_gem|
5
+ %w[rake hoe].each do |req_gem|
6
6
  begin
7
7
  require req_gem
8
8
  rescue LoadError
data/context.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "context"
3
- s.version = "0.0.3"
3
+ s.version = "0.0.5"
4
4
  s.date = "2008-10-03"
5
5
  s.summary = "Contexts and DSL sugar for your tests"
6
6
  s.email = "jeremy@entp.com"
@@ -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(/\s+/,'_')
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
@@ -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
- define_method(:setup, &block)
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
- define_method(:teardown, &block)
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, Module.new(&block))
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
- class Test::Unit::TestCase
2
- class << self
3
- # Tweaks to standard method so we don't get superclass methods and we don't
4
- # get weird default tests
5
- def suite # :nodoc:
6
- method_names = public_instance_methods(false)
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
- tests = method_names.delete_if {|method_name| method_name !~ /^test./}
9
- suite = Test::Unit::TestSuite.new(name)
10
-
11
- tests.sort.each do |test|
12
- catch(:invalid_test) do
13
- suite << new(test)
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
 
@@ -2,7 +2,7 @@ module Context
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 0
5
- TINY = 3
5
+ TINY = 5
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -1,17 +1,130 @@
1
1
  require File.dirname(__FILE__) + '/test_helper.rb'
2
2
 
3
3
  class TestLifecycle < Test::Unit::TestCase
4
- context "A before block" do
5
- it "should define a setup method" do
6
- self.class.before { true }
7
- assert self.class.method_defined?(:setup)
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
- context "An after block" do
12
- it "should define a teardown method" do
13
- self.class.after { true }
14
- assert self.class.method_defined?(:teardown)
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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jeremymcanally-context
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy McAnally