assert 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/Gemfile.lock +3 -1
  2. data/README.rdoc +6 -6
  3. data/Rakefile +2 -3
  4. data/assert.gemspec +1 -0
  5. data/lib/assert/assertions.rb +30 -30
  6. data/lib/assert/context.rb +71 -66
  7. data/lib/assert/macro.rb +14 -0
  8. data/lib/assert/macros/methods.rb +52 -0
  9. data/lib/assert/rake_tasks.rb +31 -13
  10. data/lib/assert/result.rb +12 -4
  11. data/lib/assert/result_set.rb +2 -2
  12. data/lib/assert/runner.rb +2 -6
  13. data/lib/assert/setup/autorun.rb +0 -1
  14. data/lib/assert/suite.rb +19 -15
  15. data/lib/assert/test.rb +6 -17
  16. data/lib/assert/version.rb +1 -1
  17. data/lib/assert/view/base.rb +1 -1
  18. data/lib/assert/view/terminal.rb +8 -30
  19. data/test/assertions/assert_block_test.rb +1 -1
  20. data/test/assertions/assert_empty_test.rb +43 -0
  21. data/test/assertions/assert_equal_test.rb +43 -0
  22. data/test/assertions/assert_includes_test.rb +44 -0
  23. data/test/assertions/assert_instance_of_test.rb +4 -4
  24. data/test/assertions/assert_kind_of_test.rb +3 -3
  25. data/test/assertions/assert_match_test.rb +43 -0
  26. data/test/assertions/assert_nil_test.rb +43 -0
  27. data/test/assertions/assert_not_block_test.rb +1 -1
  28. data/test/assertions/assert_not_empty_test.rb +43 -0
  29. data/test/assertions/assert_not_equal_test.rb +43 -0
  30. data/test/assertions/assert_not_included_test.rb +44 -0
  31. data/test/assertions/assert_not_instance_of_test.rb +4 -4
  32. data/test/assertions/assert_not_kind_of_test.rb +2 -2
  33. data/test/assertions/assert_not_match_test.rb +43 -0
  34. data/test/assertions/assert_not_nil_test.rb +43 -0
  35. data/test/assertions/assert_not_respond_to_test.rb +6 -6
  36. data/test/assertions/assert_not_same_test.rb +45 -0
  37. data/test/assertions/assert_respond_to_test.rb +6 -6
  38. data/test/assertions/assert_same_test.rb +45 -0
  39. data/test/assertions_test.rb +21 -298
  40. data/test/context/class_methods_test.rb +81 -112
  41. data/test/context_test.rb +35 -40
  42. data/test/helper.rb +5 -2
  43. data/test/irb.rb +2 -5
  44. data/test/macro_test.rb +99 -0
  45. data/test/options_test.rb +2 -2
  46. data/test/result_set_test.rb +47 -54
  47. data/test/result_test.rb +4 -17
  48. data/test/runner_test.rb +2 -10
  49. data/test/suite_test.rb +85 -13
  50. data/test/test/running_test.rb +19 -28
  51. data/test/test_test.rb +130 -128
  52. data/test/view_test.rb +3 -17
  53. metadata +50 -7
data/Gemfile.lock CHANGED
@@ -1,11 +1,13 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- assert (0.1.0)
4
+ assert (0.2.0)
5
+ ansi (~> 1.3)
5
6
 
6
7
  GEM
7
8
  remote: http://rubygems.org/
8
9
  specs:
10
+ ansi (1.3.0)
9
11
  rake (0.9.2)
10
12
 
11
13
  PLATFORMS
data/README.rdoc CHANGED
@@ -4,16 +4,16 @@ Test::Unit style testing framework, just better than Test::Unit.
4
4
 
5
5
  == What Assert is
6
6
 
7
- * *A framework:* you define tests and the context they run in - Assert runs them. Everything is pure ruby so use any 3rd party testing tools you like. Create 3rd party tools that extend Assert behavior.
8
- * *First Class:* everything is a first class object and can be extended to your liking (and should be)
9
- * *MVC:* tests and how they are defined (M) and executed (C) are distinct from how you view the test results (V).
10
- * *Backwards compatible:* (assuming a few minor tweaks) with Test::Unit test suites
7
+ * *Framework*: you define tests and the context they run in - Assert runs them. Everything is pure ruby so use any 3rd party testing tools you like. Create 3rd party tools that extend Assert behavior.
8
+ * *First Class*: everything is a first class object and can be extended to your liking (and should be)
9
+ * *MVC*: tests and how they are defined (M) and executed (C) are distinct from how you view the test results (V).
10
+ * *Backwards compatible*: (assuming a few minor tweaks) with Test::Unit test suites
11
11
 
12
12
  == What Assert is not
13
13
 
14
14
  * *Rspec*
15
- * *Unit/Functional/Integration/etc:* Assert is agnostic - you define whatever kinds of tests you like (one or more of the above) and assert runs them in context.
16
- * *Mock/Spec/BDD/Factories/etc:* Assert is the framework and there are a variety of 3rd party tools to do such things - feel free to use whatever you like.
15
+ * *Unit/Functional/Integration/etc*: Assert is agnostic - you define whatever kinds of tests you like (one or more of the above) and assert runs them in context.
16
+ * *Mock/Spec/BDD/Factories/etc*: Assert is the framework and there are a variety of 3rd party tools to do such things - feel free to use whatever you like.
17
17
 
18
18
  == Description
19
19
 
data/Rakefile CHANGED
@@ -1,7 +1,6 @@
1
- include Rake::DSL
1
+ require 'assert/rake_tasks'
2
+ include Assert::RakeTasks
2
3
 
3
4
  require 'bundler'
4
5
  Bundler::GemHelper.install_tasks
5
6
 
6
- require 'lib/assert/rake_tasks'
7
- Assert::RakeTasks.for :test
data/assert.gemspec CHANGED
@@ -18,4 +18,5 @@ Gem::Specification.new do |s|
18
18
  s.require_paths = ["lib"]
19
19
 
20
20
  s.add_development_dependency("bundler", ["~> 1.0"])
21
+ s.add_dependency("ansi", ["~> 1.3"])
21
22
  end
@@ -67,7 +67,7 @@ module Assert
67
67
 
68
68
 
69
69
 
70
- def assert_respond_to(object, method, fail_desc=nil)
70
+ def assert_respond_to(method, object, fail_desc=nil)
71
71
  what_failed_msg = [
72
72
  "Expected #{object.inspect} (#{object.class}) to ",
73
73
  "respond to ##{method}."
@@ -75,7 +75,7 @@ module Assert
75
75
  assert(object.respond_to?(method), fail_desc, what_failed_msg)
76
76
  end
77
77
 
78
- def assert_not_respond_to(object, method, fail_desc=nil)
78
+ def assert_not_respond_to(method, object, fail_desc=nil)
79
79
  what_failed_msg = [
80
80
  "#{object.inspect} (#{object.class}) not expected to ",
81
81
  "respond to ##{method}."
@@ -86,59 +86,58 @@ module Assert
86
86
 
87
87
 
88
88
 
89
- def assert_same(left, right, fail_desc=nil)
89
+ def assert_same(expected, actual, fail_desc=nil)
90
90
  what_failed_msg = [
91
- "Expected #{left} (#{left.object_id}) to be the same ",
92
- "as #{right} (#{right.object_id})."
91
+ "Expected #{expected} (#{expected.object_id}) to be the same ",
92
+ "as #{actual} (#{actual.object_id})."
93
93
  ].join
94
- assert(right.equal?(left), fail_desc, what_failed_msg)
94
+ assert(actual.equal?(expected), fail_desc, what_failed_msg)
95
95
  end
96
96
 
97
- def assert_not_same(left, right, fail_desc=nil)
97
+ def assert_not_same(expected, actual, fail_desc=nil)
98
98
  what_failed_msg = [
99
- "#{left} (#{left.object_id}) not expected to be the same ",
100
- "as #{right} (#{right.object_id})."
99
+ "#{expected} (#{expected.object_id}) not expected to be the same ",
100
+ "as #{actual} (#{actual.object_id})."
101
101
  ].join
102
- assert(!right.equal?(left), fail_desc, what_failed_msg)
102
+ assert(!actual.equal?(expected), fail_desc, what_failed_msg)
103
103
  end
104
104
  alias_method :refute_same, :assert_not_same
105
105
 
106
106
 
107
107
 
108
- def assert_equal(left, right, fail_desc=nil)
109
- what_failed_msg = "Expected #{left.inspect}, not #{right.inspect}."
110
- assert(right == left, fail_desc, what_failed_msg)
108
+ def assert_equal(expected, actual, fail_desc=nil)
109
+ what_failed_msg = "Expected #{expected.inspect}, not #{actual.inspect}."
110
+ assert(actual == expected, fail_desc, what_failed_msg)
111
111
  end
112
112
 
113
- def assert_not_equal(left, right, fail_desc=nil)
113
+ def assert_not_equal(expected, actual, fail_desc=nil)
114
114
  what_failed_msg = [
115
- "#{left.inspect} not expected to be equal ", "to #{right.inspect}."
115
+ "#{expected.inspect} not expected to be equal ", "to #{actual.inspect}."
116
116
  ].join
117
- assert(right != left, fail_desc, what_failed_msg)
117
+ assert(actual != expected, fail_desc, what_failed_msg)
118
118
  end
119
119
  alias_method :refute_equal, :assert_not_equal
120
120
 
121
121
 
122
122
 
123
- def assert_match(left, right, fail_desc=nil)
124
- what_failed_msg = "Expected #{left.inspect} to match #{right.inspect}."
125
- left = /#{Regexp.escape(left)}/ if String === left && String === right
126
- assert(left =~ right, fail_desc, what_failed_msg)
123
+ def assert_match(expected, actual, fail_desc=nil)
124
+ what_failed_msg = "Expected #{actual.inspect} to match #{expected.inspect}."
125
+ expected = /#{Regexp.escape(expected)}/ if String === expected && String === actual
126
+ assert(actual =~ expected, fail_desc, what_failed_msg)
127
127
  end
128
128
 
129
- def assert_not_match(left, right, fail_desc=nil)
129
+ def assert_not_match(expected, actual, fail_desc=nil)
130
130
  what_failed_msg = [
131
- "#{left.inspect} not expected to ", "match #{right.inspect}."
131
+ "#{actual.inspect} not expected to ", "match #{expected.inspect}."
132
132
  ].join
133
- left = /#{Regexp.escape(left)}/ if String === left && String === right
134
- assert(left !~ right, fail_desc, what_failed_msg)
133
+ expected = /#{Regexp.escape(expected)}/ if String === expected && String === actual
134
+ assert(actual !~ expected, fail_desc, what_failed_msg)
135
135
  end
136
136
  alias_method :refute_match, :assert_not_match
137
137
  alias_method :assert_no_match, :assert_not_match
138
138
 
139
139
 
140
140
 
141
- # TODO: tests!
142
141
  def assert_empty(collection, fail_desc=nil)
143
142
  what_failed_msg = "Expected #{collection.inspect} to be empty."
144
143
  assert(collection.empty?, fail_desc, what_failed_msg)
@@ -152,21 +151,22 @@ module Assert
152
151
 
153
152
 
154
153
 
155
- # TODO: tests!
156
- def assert_includes(collection, object, fail_desc=nil)
154
+ def assert_includes(object, collection, fail_desc=nil)
157
155
  what_failed_msg = "Expected #{collection.inspect} to include #{object.inspect}."
158
156
  assert(collection.include?(object), fail_desc, what_failed_msg)
159
157
  end
158
+ alias_method :assert_included, :assert_includes
160
159
 
161
- def assert_not_included(collection, object, fail_desc=nil)
160
+ def assert_not_includes(object, collection, fail_desc=nil)
162
161
  what_failed_msg = "Expected #{collection.inspect} to not include #{object.inspect}."
163
162
  assert(!collection.include?(object), fail_desc, what_failed_msg)
164
163
  end
165
- alias_method :refute_includes, :assert_not_included
164
+ alias_method :assert_not_included, :assert_not_includes
165
+ alias_method :refute_includes, :assert_not_includes
166
+ alias_method :refute_included, :assert_not_includes
166
167
 
167
168
 
168
169
 
169
- # TODO: tests!
170
170
  def assert_nil(object, fail_desc=nil)
171
171
  what_failed_msg = "Expected nil, not #{object.inspect}."
172
172
  assert(object.nil?, fail_desc, what_failed_msg)
@@ -1,10 +1,12 @@
1
1
  require 'assert/suite'
2
2
  require 'assert/assertions'
3
3
  require 'assert/result'
4
+ require 'assert/macros/methods'
4
5
 
5
6
  module Assert
6
7
  class Context
7
8
  include Assert::Assertions
9
+ include Assert::Macros::Methods
8
10
 
9
11
  # a Context is a scope for tests to run in. Contexts have setup and
10
12
  # teardown blocks, subjects, and descriptions. Tests are run in the
@@ -19,7 +21,6 @@ module Assert
19
21
 
20
22
  # put all logic here to keep context instances pure for running tests
21
23
  class << self
22
- attr_accessor :subject_block
23
24
 
24
25
  def setup_once(&block)
25
26
  Assert.suite.setup(&block)
@@ -31,84 +32,86 @@ module Assert
31
32
  end
32
33
  alias_method :after_once, :teardown_once
33
34
 
34
- def setup(&block)
35
- raise ArgumentError, "please provide a setup block" unless block_given?
36
- self.setup_blocks << block
35
+ # Add a setup block to run before each test or run the list of teardown blocks in given scope
36
+ def setup(scope=nil, &block)
37
+ if block_given?
38
+ self.setups << block
39
+ elsif scope
40
+ # setup parent before child
41
+ self.superclass.setup(scope) if self.superclass.respond_to?(:setup)
42
+ self.setups.each{|setup| scope.instance_eval(&setup)}
43
+ end
37
44
  end
38
45
  alias_method :before, :setup
39
46
 
40
- def teardown(&block)
41
- raise ArgumentError, "please provide a teardown block" unless block_given?
42
- self.teardown_blocks << block
47
+ # Add a teardown block to run after each test or run the list of teardown blocks in given scope
48
+ def teardown(scope=nil, &block)
49
+ if block_given?
50
+ self.teardowns << block
51
+ elsif scope
52
+ # teardown child before parent
53
+ self.teardowns.each{|teardown| scope.instance_eval(&teardown)}
54
+ self.superclass.teardown(scope) if self.superclass.respond_to?(:teardown)
55
+ end
43
56
  end
44
57
  alias_method :after, :teardown
45
58
 
46
- def setup_blocks
47
- @setup_blocks ||= []
48
- end
49
-
50
- def teardown_blocks
51
- @teardown_blocks ||= []
59
+ # Add a piece of description text or return the full description for the context
60
+ def description(text=nil)
61
+ if text
62
+ self.descriptions << text.to_s
63
+ else
64
+ parent = self.superclass.desc if self.superclass.respond_to?(:desc)
65
+ own = self.descriptions
66
+ [parent, *own].compact.reject do |p|
67
+ p.to_s.empty?
68
+ end.join(" ")
69
+ end
52
70
  end
71
+ alias_method :desc, :description
53
72
 
54
- def all_setup_blocks
55
- inherited_blocks = if superclass.respond_to?(:all_setup_blocks)
56
- superclass.all_setup_blocks
73
+ def subject(&block)
74
+ if block_given?
75
+ @subject = block
76
+ else
77
+ @subject || if superclass.respond_to?(:subject)
78
+ superclass.subject
79
+ end
57
80
  end
58
- (inherited_blocks || []) + self.setup_blocks
59
81
  end
60
82
 
61
- def all_teardown_blocks
62
- inherited_blocks = if superclass.respond_to?(:all_teardown_blocks)
63
- superclass.all_teardown_blocks
83
+ def should(desc_or_macro, &block)
84
+ if desc_or_macro.kind_of?(Macro)
85
+ instance_eval(&desc_or_macro)
86
+ else
87
+ raise ArgumentError, "please provide a test block" unless block_given?
88
+ method_name = "test: should #{desc_or_macro}"
89
+ if method_defined?(method_name)
90
+ from = caller.first
91
+ puts "WARNING: should #{desc_or_macro.inspect} is redefining #{method_name}!"
92
+ puts " from: #{from}"
93
+ end
94
+ define_method(method_name, &block)
64
95
  end
65
- (inherited_blocks || []) + self.teardown_blocks
66
96
  end
67
97
 
68
- def desc(text)
69
- raise ArgumentError, "no context description provided" if text.nil?
70
- self.descriptions << text
98
+ def should_eventually(desc, &block)
99
+ should(desc) { skip }
71
100
  end
72
- alias_method :description, :desc
101
+ alias_method :should_skip, :should_eventually
102
+
103
+ protected
73
104
 
74
105
  def descriptions
75
106
  @descriptions ||= []
76
107
  end
77
108
 
78
- def full_description
79
- inherited_description = if superclass.respond_to?(:full_description)
80
- superclass.full_description
81
- end
82
- parts = [ inherited_description ].push(self.descriptions).flatten.reject do |part|
83
- !part || part.to_s.empty?
84
- end
85
- parts.join(" ") if !parts.empty?
86
- end
87
-
88
- def subject(&block)
89
- raise ArgumentError, "please provide a subject block" unless block_given?
90
- self.subject_block = block
91
- end
92
-
93
- def subject_block
94
- @subject_block ||= if superclass.respond_to?(:subject_block)
95
- superclass.subject_block
96
- end
109
+ def setups
110
+ @setups ||= []
97
111
  end
98
112
 
99
- def should(desc, &block)
100
- raise ArgumentError, "please provide a test block" unless block_given?
101
- method_name = "test: should #{desc}"
102
- if method_defined?(method_name)
103
- from = caller.first
104
- puts "WARNING: should #{desc.inspect} is redefining #{method_name}!"
105
- puts " from: #{from}"
106
- end
107
- define_method(method_name, &block)
108
- end
109
-
110
- def should_eventually(desc, &block)
111
- should(desc){ skip }
113
+ def teardowns
114
+ @teardowns ||= []
112
115
  end
113
116
 
114
117
  end
@@ -166,8 +169,8 @@ module Assert
166
169
  end
167
170
 
168
171
  def subject
169
- if subject_block = self.class.subject_block
170
- instance_eval(&subject_block)
172
+ if subj = self.class.subject
173
+ instance_eval(&subj)
171
174
  end
172
175
  end
173
176
 
@@ -177,6 +180,15 @@ module Assert
177
180
 
178
181
  protected
179
182
 
183
+ # Returns a Proc that will output a custom message along with the default fail message.
184
+ def fail_message(fail_desc=nil, &what_failed)
185
+ fail_desc.kind_of?(::Proc) ? fail_desc : Proc.new do
186
+ [ fail_desc, what_failed.call ].compact.join("\n")
187
+ end
188
+ end
189
+
190
+ private
191
+
180
192
  def capture_result
181
193
  if block_given?
182
194
  result = yield @__running_test__.name, caller
@@ -185,12 +197,5 @@ module Assert
185
197
  end
186
198
  end
187
199
 
188
- # Returns a Proc that will output a custom message along with the default fail message.
189
- def fail_message(fail_desc=nil, &what_failed)
190
- fail_desc.kind_of?(::Proc) ? fail_desc : Proc.new do
191
- [ what_failed.call, fail_desc ].compact.join("\n")
192
- end
193
- end
194
-
195
200
  end
196
201
  end
@@ -0,0 +1,14 @@
1
+ module Assert
2
+ class Macro < ::Proc
3
+
4
+ # this class is essentially a way to define a custom set of tests using
5
+ # arguments. When passed as an argument to the 'should' method, a macro
6
+ # will be instance_eval'd in that Assert::Context.
7
+
8
+ def initialize(*args, &block)
9
+ raise ArgumentError unless block_given?
10
+ super()
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,52 @@
1
+ require 'assert/macro'
2
+
3
+ module Assert::Macros
4
+ module Methods
5
+
6
+ def self.included(receiver)
7
+ receiver.send(:extend, ClassMethods)
8
+ end
9
+
10
+ module ClassMethods
11
+
12
+ def have_instance_method(*methods)
13
+ Assert::Macro.new do
14
+ methods.each do |method|
15
+ should "respond to instance method ##{method}" do
16
+ assert_respond_to method, subject, "#{subject.class.name} does not have instance method ##{method}"
17
+ end
18
+ end
19
+ end
20
+ end
21
+ alias_method :have_instance_methods, :have_instance_method
22
+
23
+ def have_class_method(*methods)
24
+ Assert::Macro.new do
25
+ methods.each do |method|
26
+ should "respond to class method ##{method}" do
27
+ assert_respond_to method, subject.class, "#{subject.class.name} does not have class method ##{method}"
28
+ end
29
+ end
30
+ end
31
+ end
32
+ alias_method :have_class_methods, :have_class_method
33
+
34
+ def have_reader(*methods)
35
+ have_instance_methods(*methods)
36
+ end
37
+ alias_method :have_readers, :have_reader
38
+
39
+ def have_writer(*methods)
40
+ have_instance_methods(*methods.collect{|m| "#{m}="})
41
+ end
42
+ alias_method :have_writers, :have_writer
43
+
44
+ def have_accessor(*methods)
45
+ have_instance_methods(*methods.collect{|m| [m, "#{m}="]}.flatten)
46
+ end
47
+ alias_method :have_accessors, :have_accessor
48
+
49
+ end
50
+
51
+ end
52
+ end