jeremymcanally-context 0.0.3 → 0.0.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/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