assert 2.4.0 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/README.md +8 -8
  2. data/lib/assert.rb +9 -62
  3. data/lib/assert/assert_runner.rb +15 -30
  4. data/lib/assert/assertions.rb +105 -41
  5. data/lib/assert/cli.rb +1 -1
  6. data/lib/assert/config.rb +56 -0
  7. data/lib/assert/context.rb +44 -150
  8. data/lib/assert/context/setup_dsl.rb +70 -0
  9. data/lib/assert/context/subject_dsl.rb +39 -0
  10. data/lib/assert/context/suite_dsl.rb +20 -0
  11. data/lib/assert/context/test_dsl.rb +51 -0
  12. data/lib/assert/runner.rb +8 -2
  13. data/lib/assert/suite.rb +33 -12
  14. data/lib/assert/test.rb +11 -8
  15. data/lib/assert/utils.rb +23 -11
  16. data/lib/assert/version.rb +1 -1
  17. data/lib/assert/view.rb +9 -7
  18. data/lib/assert/view/base.rb +26 -4
  19. data/lib/assert/view/default_view.rb +1 -1
  20. data/lib/assert/view/helpers/ansi_styles.rb +1 -1
  21. data/lib/assert/view/helpers/common.rb +16 -6
  22. data/test/helper.rb +1 -94
  23. data/test/support/factory.rb +70 -0
  24. data/test/system/running_tests.rb +55 -28
  25. data/test/unit/assert_tests.rb +6 -33
  26. data/test/unit/assertions/assert_block_tests.rb +3 -3
  27. data/test/unit/assertions/assert_empty_tests.rb +6 -4
  28. data/test/unit/assertions/assert_equal_tests.rb +19 -22
  29. data/test/unit/assertions/assert_file_exists_tests.rb +6 -4
  30. data/test/unit/assertions/assert_includes_tests.rb +8 -4
  31. data/test/unit/assertions/assert_instance_of_tests.rb +8 -6
  32. data/test/unit/assertions/assert_kind_of_tests.rb +8 -5
  33. data/test/unit/assertions/assert_match_tests.rb +8 -4
  34. data/test/unit/assertions/assert_nil_tests.rb +6 -4
  35. data/test/unit/assertions/assert_raises_tests.rb +2 -2
  36. data/test/unit/assertions/assert_respond_to_tests.rb +7 -5
  37. data/test/unit/assertions/assert_same_tests.rb +75 -6
  38. data/test/unit/assertions/assert_true_false_tests.rb +116 -0
  39. data/test/unit/assertions_tests.rb +7 -5
  40. data/test/unit/config_tests.rb +58 -0
  41. data/test/unit/context/{setup_teardown_singleton_tests.rb → setup_dsl_tests.rb} +17 -19
  42. data/test/unit/context/subject_dsl_tests.rb +78 -0
  43. data/test/unit/context/suite_dsl_tests.rb +47 -0
  44. data/test/unit/context/{test_should_singleton_tests.rb → test_dsl_tests.rb} +33 -34
  45. data/test/unit/context_tests.rb +19 -15
  46. data/test/unit/runner_tests.rb +9 -3
  47. data/test/unit/suite_tests.rb +20 -23
  48. data/test/unit/test_tests.rb +22 -14
  49. data/test/unit/utils_tests.rb +15 -21
  50. data/test/unit/view_tests.rb +12 -5
  51. metadata +23 -10
  52. data/test/unit/context/basic_singleton_tests.rb +0 -86
data/lib/assert/cli.rb CHANGED
@@ -50,7 +50,7 @@ module Assert
50
50
  def run
51
51
  begin
52
52
  @cli.parse!(@args)
53
- Assert::AssertRunner.new(@cli.args, @cli.opts).run
53
+ Assert::AssertRunner.new(Assert.config, @cli.args, @cli.opts).run
54
54
  rescue CLIRB::HelpExit
55
55
  puts help
56
56
  rescue CLIRB::VersionExit
@@ -0,0 +1,56 @@
1
+ module Assert
2
+
3
+ class Config
4
+
5
+ def self.settings(*items)
6
+ items.each do |item|
7
+ define_method(item) do |*args|
8
+ if !(value = args.size > 1 ? args : args.first).nil?
9
+ instance_variable_set("@#{item}", value)
10
+ end
11
+ instance_variable_get("@#{item}")
12
+ end
13
+ end
14
+ end
15
+
16
+ settings :view, :suite, :runner
17
+ settings :test_dir, :test_helper, :test_file_suffixes, :runner_seed
18
+ settings :changed_proc, :pp_proc, :use_diff_proc, :run_diff_proc
19
+ settings :capture_output, :halt_on_fail, :changed_only, :pp_objects, :debug
20
+
21
+ def initialize(settings = nil)
22
+ @suite = Assert::Suite.new(self)
23
+ @view = Assert::View::DefaultView.new($stdout, self, @suite)
24
+ @runner = Assert::Runner.new(self)
25
+
26
+ @test_dir = "test"
27
+ @test_helper = "helper.rb"
28
+ @test_file_suffixes = ['_tests.rb', '_test.rb']
29
+ @runner_seed = begin; srand; srand % 0xFFFF; end.to_i
30
+
31
+ @changed_proc = Assert::U.git_changed_proc
32
+ @pp_proc = Assert::U.stdlib_pp_proc
33
+ @use_diff_proc = Assert::U.default_use_diff_proc
34
+ @run_diff_proc = Assert::U.syscmd_diff_proc
35
+
36
+ # mode flags
37
+ @capture_output = false
38
+ @halt_on_fail = true
39
+ @changed_only = false
40
+ @pp_objects = false
41
+ @debug = false
42
+
43
+ self.apply(settings || {})
44
+ end
45
+
46
+ def apply(settings)
47
+ settings.keys.each do |name|
48
+ if !settings[name].nil? && self.respond_to?(name.to_s)
49
+ self.send(name.to_s, settings[name])
50
+ end
51
+ end
52
+ end
53
+
54
+ end
55
+
56
+ end
@@ -1,11 +1,21 @@
1
- require 'assert/utils'
2
- require 'assert/suite'
3
1
  require 'assert/assertions'
4
- require 'assert/result'
2
+ require 'assert/context/setup_dsl'
3
+ require 'assert/context/subject_dsl'
4
+ require 'assert/context/suite_dsl'
5
+ require 'assert/context/test_dsl'
5
6
  require 'assert/macros/methods'
7
+ require 'assert/result'
8
+ require 'assert/suite'
9
+ require 'assert/utils'
6
10
 
7
11
  module Assert
12
+
8
13
  class Context
14
+ # put all logic in DSL methods to keep context instances pure for running tests
15
+ extend SetupDSL
16
+ extend SubjectDSL
17
+ extend SuiteDSL
18
+ extend TestDSL
9
19
  include Assert::Assertions
10
20
  include Assert::Macros::Methods
11
21
 
@@ -21,155 +31,21 @@ module Assert
21
31
  if method_name.to_s =~ Suite::TEST_METHOD_REGEX
22
32
  klass_method_name = "#{self}##{method_name}"
23
33
 
24
- if Assert.suite.test_methods.include?(klass_method_name)
34
+ if self.suite.test_methods.include?(klass_method_name)
25
35
  puts "WARNING: redefining '#{klass_method_name}'"
26
36
  puts " from: #{called_from}"
27
37
  else
28
- Assert.suite.test_methods << klass_method_name
38
+ self.suite.test_methods << klass_method_name
29
39
  end
30
40
 
31
41
  ci = Suite::ContextInfo.new(self, nil, caller.first)
32
- Assert.suite.tests << Test.new(method_name.to_s, ci, method_name)
33
- end
34
- end
35
-
36
- # put all logic here to keep context instances pure for running tests
37
- class << self
38
-
39
- def setup_once(&block)
40
- Assert.suite.setup(&block)
41
- end
42
- alias_method :before_once, :setup_once
43
- alias_method :startup, :setup_once
44
-
45
- def teardown_once(&block)
46
- Assert.suite.teardown(&block)
47
- end
48
- alias_method :after_once, :teardown_once
49
- alias_method :shutdown, :teardown_once
50
-
51
- # Add a setup block to run before each test or run the list of teardown blocks in given scope
52
- def setup(scope_or_method_name = nil, &block)
53
- is_method = scope_or_method_name.kind_of?(String) || scope_or_method_name.kind_of?(Symbol)
54
- if block_given? || is_method
55
- # arg is a block or method that needs to be stored as a setup
56
- self.setups << (block || scope_or_method_name)
57
- elsif !is_method
58
- # arg is an instance of this class (the scope for a test),
59
- # run the setups for this context in the scope
60
- scope = scope_or_method_name
61
- # setup parent...
62
- self.superclass.setup(scope) if self.superclass.respond_to?(:setup)
63
- # ... before child
64
- self.setups.each do |setup|
65
- setup.kind_of?(::Proc) ? scope.instance_eval(&setup) : scope.send(setup)
66
- end
67
- end
68
- end
69
- alias_method :before, :setup
70
-
71
- # Add a teardown block to run after each test or run the list of teardown blocks in given scope
72
- def teardown(scope_or_method_name = nil, &block)
73
- is_method = scope_or_method_name.kind_of?(String) || scope_or_method_name.kind_of?(Symbol)
74
- if block_given? || is_method
75
- # arg is a block or method that needs to be stored as a teardown
76
- self.teardowns << (block || scope_or_method_name)
77
- elsif !is_method
78
- # arg is an instance of this class (the scope for a test),
79
- # run the setups for this context in the scope
80
- scope = scope_or_method_name
81
- # teardown child...
82
- self.teardowns.each do |teardown|
83
- teardown.kind_of?(::Proc) ? scope.instance_eval(&teardown) : scope.send(teardown)
84
- end
85
- # ... before parent
86
- self.superclass.teardown(scope) if self.superclass.respond_to?(:teardown)
87
- end
88
- end
89
- alias_method :after, :teardown
90
-
91
- # Add a piece of description text or return the full description for the context
92
- def description(text=nil)
93
- if text
94
- self.descriptions << text.to_s
95
- else
96
- parent = self.superclass.desc if self.superclass.respond_to?(:desc)
97
- own = self.descriptions
98
- [parent, *own].compact.reject do |p|
99
- p.to_s.empty?
100
- end.join(" ")
101
- end
102
- end
103
- alias_method :desc, :description
104
- alias_method :describe, :description
105
-
106
- def subject(&block)
107
- if block_given?
108
- @subject = block
109
- else
110
- @subject || if superclass.respond_to?(:subject)
111
- superclass.subject
112
- end
113
- end
114
- end
115
-
116
- def test(desc_or_macro, called_from=nil, first_caller=nil, &block)
117
- if desc_or_macro.kind_of?(Macro)
118
- instance_eval(&desc_or_macro)
119
- elsif block_given?
120
- ci = Suite::ContextInfo.new(self, called_from, first_caller || caller.first)
121
- test_name = desc_or_macro
122
-
123
- # create a test from the given code block
124
- Assert.suite.tests << Test.new(test_name, ci, &block)
125
- else
126
- test_eventually(desc_or_macro, called_from, first_caller || caller.first, &block)
127
- end
128
- end
129
-
130
- def test_eventually(desc_or_macro, called_from=nil, first_caller=nil, &block)
131
- ci = Suite::ContextInfo.new(self, called_from, first_caller || caller.first)
132
- test_name = desc_or_macro.kind_of?(Macro) ? desc_or_macro.name : desc_or_macro
133
- skip_block = block.nil? ? Proc.new { skip 'TODO' } : Proc.new { skip }
134
-
135
- # create a test from a proc that just skips
136
- Assert.suite.tests << Test.new(test_name, ci, &skip_block)
137
- end
138
- alias_method :test_skip, :test_eventually
139
-
140
- def should(desc_or_macro, called_from=nil, first_caller=nil, &block)
141
- if !desc_or_macro.kind_of?(Macro)
142
- desc_or_macro = "should #{desc_or_macro}"
143
- end
144
- test(desc_or_macro, called_from, first_caller || caller.first, &block)
145
- end
146
-
147
- def should_eventually(desc_or_macro, called_from=nil, first_caller=nil, &block)
148
- if !desc_or_macro.kind_of?(Macro)
149
- desc_or_macro = "should #{desc_or_macro}"
150
- end
151
- test_eventually(desc_or_macro, called_from, first_caller || caller.first, &block)
152
- end
153
- alias_method :should_skip, :should_eventually
154
-
155
- protected
156
-
157
- def descriptions
158
- @descriptions ||= []
42
+ test = Test.new(method_name.to_s, ci, self.suite.config, :code => method_name)
43
+ self.suite.tests << test
159
44
  end
160
-
161
- def setups
162
- @setups ||= []
163
- end
164
-
165
- def teardowns
166
- @teardowns ||= []
167
- end
168
-
169
45
  end
170
46
 
171
- def initialize(running_test = nil)
172
- @__running_test__ = running_test
47
+ def initialize(running_test, config)
48
+ @__running_test__, @__assert_config__ = running_test, config
173
49
  end
174
50
 
175
51
  # check if the assertion is a truthy value, if so create a new pass result, otherwise
@@ -179,7 +55,11 @@ module Assert
179
55
  if assertion
180
56
  pass
181
57
  else
182
- what = block_given? ? yield : "Failed assert: assertion was `#{Assert::U.show(assertion)}`."
58
+ what = if block_given?
59
+ yield
60
+ else
61
+ "Failed assert: assertion was `#{Assert::U.show(assertion, __assert_config__)}`."
62
+ end
183
63
  fail(fail_message(desc, what))
184
64
  end
185
65
  end
@@ -187,7 +67,9 @@ module Assert
187
67
  # the opposite of assert, check if the assertion is a false value, if so create a new pass
188
68
  # result, otherwise create a new fail result with the desc and it's what failed msg
189
69
  def assert_not(assertion, fail_desc = nil)
190
- assert(!assertion, fail_desc){ "Failed assert_not: assertion was `#{Assert::U.show(assertion)}`." }
70
+ assert(!assertion, fail_desc) do
71
+ "Failed assert_not: assertion was `#{Assert::U.show(assertion, __assert_config__)}`."
72
+ end
191
73
  end
192
74
  alias_method :refute, :assert_not
193
75
 
@@ -208,9 +90,9 @@ module Assert
208
90
  end
209
91
 
210
92
  # adds a Fail result to the end of the test's results
211
- # break test execution if Assert.config.halt_on_fail
93
+ # break test execution if assert is configured to halt on failures
212
94
  def fail(message = nil)
213
- if Assert.config.halt_on_fail
95
+ if halt_on_fail?
214
96
  raise Result::TestFailure, message || ''
215
97
  else
216
98
  capture_result do |test, backtrace|
@@ -258,16 +140,28 @@ module Assert
258
140
 
259
141
  private
260
142
 
143
+ def halt_on_fail?
144
+ __assert_config__.halt_on_fail
145
+ end
146
+
261
147
  def capture_result
262
148
  if block_given?
263
- result = yield @__running_test__, caller
264
- @__running_test__.results << result
149
+ result = yield __running_test__, caller
150
+ __running_test__.results << result
265
151
  result
266
152
  end
267
153
  end
268
154
 
269
155
  def current_results
270
- @__running_test__.results
156
+ __running_test__.results
157
+ end
158
+
159
+ def __running_test__
160
+ @__running_test__
161
+ end
162
+
163
+ def __assert_config__
164
+ @__assert_config__
271
165
  end
272
166
 
273
167
  end
@@ -0,0 +1,70 @@
1
+ module Assert; end
2
+ class Assert::Context
3
+
4
+ module SetupDSL
5
+
6
+ def setup_once(&block)
7
+ self.suite.setup(&block)
8
+ end
9
+ alias_method :before_once, :setup_once
10
+ alias_method :startup, :setup_once
11
+
12
+ def teardown_once(&block)
13
+ self.suite.teardown(&block)
14
+ end
15
+ alias_method :after_once, :teardown_once
16
+ alias_method :shutdown, :teardown_once
17
+
18
+ # Add a setup block to run before each test or run the list of teardown blocks in given scope
19
+ def setup(scope_or_method_name = nil, &block)
20
+ is_method = scope_or_method_name.kind_of?(String) || scope_or_method_name.kind_of?(Symbol)
21
+ if block_given? || is_method
22
+ # arg is a block or method that needs to be stored as a setup
23
+ self.setups << (block || scope_or_method_name)
24
+ elsif !is_method
25
+ # arg is an instance of this class (the scope for a test),
26
+ # run the setups for this context in the scope
27
+ scope = scope_or_method_name
28
+ # setup parent...
29
+ self.superclass.setup(scope) if self.superclass.respond_to?(:setup)
30
+ # ... before child
31
+ self.setups.each do |setup|
32
+ setup.kind_of?(::Proc) ? scope.instance_eval(&setup) : scope.send(setup)
33
+ end
34
+ end
35
+ end
36
+ alias_method :before, :setup
37
+
38
+ # Add a teardown block to run after each test or run the list of teardown blocks in given scope
39
+ def teardown(scope_or_method_name = nil, &block)
40
+ is_method = scope_or_method_name.kind_of?(String) || scope_or_method_name.kind_of?(Symbol)
41
+ if block_given? || is_method
42
+ # arg is a block or method that needs to be stored as a teardown
43
+ self.teardowns << (block || scope_or_method_name)
44
+ elsif !is_method
45
+ # arg is an instance of this class (the scope for a test),
46
+ # run the setups for this context in the scope
47
+ scope = scope_or_method_name
48
+ # teardown child...
49
+ self.teardowns.each do |teardown|
50
+ teardown.kind_of?(::Proc) ? scope.instance_eval(&teardown) : scope.send(teardown)
51
+ end
52
+ # ... before parent
53
+ self.superclass.teardown(scope) if self.superclass.respond_to?(:teardown)
54
+ end
55
+ end
56
+ alias_method :after, :teardown
57
+
58
+ protected
59
+
60
+ def setups
61
+ @setups ||= []
62
+ end
63
+
64
+ def teardowns
65
+ @teardowns ||= []
66
+ end
67
+
68
+ end
69
+
70
+ end
@@ -0,0 +1,39 @@
1
+ module Assert; end
2
+ class Assert::Context
3
+
4
+ module SubjectDSL
5
+
6
+ # Add a piece of description text or return the full description for the context
7
+ def description(text = nil)
8
+ if text
9
+ self.descriptions << text.to_s
10
+ else
11
+ parent = self.superclass.desc if self.superclass.respond_to?(:desc)
12
+ own = self.descriptions
13
+ [parent, *own].compact.reject do |p|
14
+ p.to_s.empty?
15
+ end.join(" ")
16
+ end
17
+ end
18
+ alias_method :desc, :description
19
+ alias_method :describe, :description
20
+
21
+ def subject(&block)
22
+ if block_given?
23
+ @subject = block
24
+ else
25
+ @subject || if superclass.respond_to?(:subject)
26
+ superclass.subject
27
+ end
28
+ end
29
+ end
30
+
31
+ protected
32
+
33
+ def descriptions
34
+ @descriptions ||= []
35
+ end
36
+
37
+ end
38
+
39
+ end
@@ -0,0 +1,20 @@
1
+ module Assert; end
2
+ class Assert::Context
3
+
4
+ module SuiteDSL
5
+
6
+ def suite(suite_obj = nil)
7
+ if suite_obj
8
+ @suite = suite_obj
9
+ else
10
+ @suite || if superclass.respond_to?(:suite)
11
+ superclass.suite
12
+ else
13
+ Assert.suite
14
+ end
15
+ end
16
+ end
17
+
18
+ end
19
+
20
+ end