assert 0.1.0 → 0.2.0

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.
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