assert 2.4.0 → 2.5.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 (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