assert 0.7.3 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/.gitignore +16 -4
  2. data/{CHANGELOG.rdoc → CHANGELOG.md} +14 -3
  3. data/LICENSE +22 -0
  4. data/README.md +261 -0
  5. data/Rakefile +1 -1
  6. data/assert.gemspec +2 -1
  7. data/lib/assert/assertions.rb +16 -0
  8. data/lib/assert/autorun.rb +11 -7
  9. data/lib/assert/macros/methods.rb +49 -3
  10. data/lib/assert/rake_tasks.rb +13 -7
  11. data/lib/assert/rake_tasks/irb.rb +1 -1
  12. data/lib/assert/rake_tasks/scope.rb +55 -28
  13. data/lib/assert/rake_tasks/test_task.rb +4 -1
  14. data/lib/assert/result.rb +7 -9
  15. data/lib/assert/result_set.rb +7 -4
  16. data/lib/assert/runner.rb +10 -10
  17. data/lib/assert/setup/helpers.rb +5 -3
  18. data/lib/assert/setup/runner.rb +2 -3
  19. data/lib/assert/setup/suite.rb +2 -5
  20. data/lib/assert/setup/view.rb +26 -3
  21. data/lib/assert/test.rb +56 -37
  22. data/lib/assert/version.rb +1 -1
  23. data/lib/assert/view/base.rb +75 -0
  24. data/lib/assert/view/default_view.rb +75 -0
  25. data/lib/assert/view/helpers/ansi_styles.rb +25 -0
  26. data/lib/assert/view/helpers/capture_output.rb +23 -0
  27. data/lib/assert/view/helpers/common.rb +154 -0
  28. data/test/assertions/assert_file_exists_test.rb +43 -0
  29. data/test/assertions/assert_not_file_exists_test.rb +43 -0
  30. data/test/assertions_test.rb +4 -1
  31. data/test/macro_test.rb +25 -0
  32. data/test/rake_tasks/irb_test.rb +2 -2
  33. data/test/rake_tasks/scope_test.rb +9 -9
  34. data/test/result_set_test.rb +13 -23
  35. data/test/runner_test.rb +1 -1
  36. data/test/test/{running_test.rb → running_tests.rb} +14 -14
  37. data/test/view/base_tests.rb +65 -0
  38. metadata +29 -18
  39. data/Gemfile.lock +0 -23
  40. data/README.rdoc +0 -183
data/.gitignore CHANGED
@@ -1,5 +1,17 @@
1
- pkg/*
2
- .bundle
3
1
  *.gem
4
- *.log
5
- .rvmrc
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
@@ -1,6 +1,17 @@
1
- == Assert Changes
1
+ ## Assert Changes
2
2
 
3
- === v0.7.x
3
+ ### v0.8.x
4
+ * deprecated assert-view sister repo
5
+ * `DefaultView` now provided by assert directly
6
+ * views render by defining callbacks that are fired by the runner
7
+ * added in the corresponding `not_*` method macros (#87)
8
+ * added in aliases for `assert_responds_to` assertion helpers (#86)
9
+ * added in `assert_file_exists` assertion helpers (#85)
10
+ * allows test files ending in `_tests.rb` to be recognized by rake task generator
11
+ * `DefaultView` syncs its io output
12
+ * README enhanced; added docs for view rendering and customization
13
+
14
+ ### v0.7.x
4
15
  * tests know context info (klass, called_from, file) (#62)
5
16
  * suites track tests ungrouped
6
17
  * fixed issue where method macros display incorrect fail traces
@@ -17,5 +28,5 @@
17
28
  * overhaul to how the rake tasks are generated and handled (#69)
18
29
  * added name attr to Result model (#61)
19
30
 
20
- === v0.6.x
31
+ ### v0.6.x
21
32
  * everything prior to changelog tracking...
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2011-Present Kelly Redding, Collin Redding, and Team Insight
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,261 @@
1
+ # The Assert testing framework
2
+
3
+ Test::Unit style testing framework, just better than Test::Unit.
4
+
5
+ ## What Assert is
6
+
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
+
12
+ ## What Assert is not
13
+
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.
17
+
18
+ ## Description
19
+
20
+ Assert is a Test::Unit style testing framework. This means you can write tests in Assert the same way you would with test-unit. In addition, Assert adds some helpers and syntax sugar to enhance the way tests are written - most taken from ideas in [Shoulda](https://github.com/thoughtbot/shoulda) and [Leftright](https://github.com/jordi/leftright/). Assert uses class-based contexts so if you want to nest your contexts, use good old inheritance.
21
+
22
+ Assert is tested using itself. The tests are a pretty good place to look for examples and usage patterns.
23
+
24
+ ## Installation
25
+
26
+ ```
27
+ $ gem install assert
28
+ ```
29
+
30
+ ## Usage
31
+
32
+ ```ruby
33
+ require 'assert'
34
+
35
+ class MyTests < Assert::Context
36
+
37
+ def test_something
38
+ assert_equal 1, 1
39
+ end
40
+
41
+ end
42
+ ```
43
+
44
+ ## Models
45
+
46
+ Assert models exist to define, collect, structure, and report on Assert test data.
47
+
48
+ ### Suite
49
+
50
+ A `Suite` object is reponsible for collecting and structuring tests and defines the set of tests to run using the test `Runner`. Tests are grouped within the suite by their context. Suite provides access to the contexts, tests, and test results. In addition, the Suite model provides some stats (ie. run_time, runner_seed, etc...).
51
+
52
+ ### Runner
53
+
54
+ A `Runner` object is responsible for running a suite of tests and firing event callbacks to the `View`. Any runner object should take the test suite and view as arguments and should provide a 'run' method that runs the tests and renders the view.
55
+
56
+ ### Context
57
+
58
+ A `Context` object is the scope that tests are run in. When tests are run, a new instance of the test context is created and the test code is evaluated within the scope of this context instance. Context provides methods for defining tests and test callbacks and for generating test results in running tests. Subclass context classes to achieve nested context behavior.
59
+
60
+ ### Test
61
+
62
+ A `Test` object defines the test code that needs to be run and the results generated by that test code. Tests are aware of their context and are responsible for running their code in context.
63
+
64
+ ### Result
65
+
66
+ A `Result` object defines the data related to a test result. There are a few kinds of test results available:
67
+
68
+ * `Pass`
69
+ * `Fail`
70
+ * `Error`
71
+ * `Skip`
72
+ * `Ignore`
73
+
74
+ Tests produce results as they are executed. Every `assert` statement produces a result. Some results, like `Error` and `Skip`, will halt execution. `Pass` and `Ignore` results do not halt execution. `Fail` results, by default, halt execution but there is an option to have them not halt execution. Therefore, tests can have many results of varying types.
75
+
76
+ ### View
77
+
78
+ A `View` object is responsible for rendering test result output. Assert provides a `Assert::View::Base` object to provide common helpers and default runner callback handlers for building views. Assert also provides a `Assert::View::DefaultView` that it renders its output with. See the "Viewing Test Results" section below for more details.
79
+
80
+ ### Macro
81
+
82
+ Macros are procs that define sets of test code and make it available for easy reuse. Macros work nicely with the 'should' and 'test' context methods.
83
+
84
+ ## User Options and Helpers
85
+
86
+ Assert provides ways for setting user-specfic options and helpers. When Assert is setting itself up, the last setup step is to look for and require the file `~/.assert/options.rb`. This file is essentially a user level test helper file. Use it to set options, configure assert extensions, setup/define how to view test results, etc.
87
+
88
+ ## Running Tests
89
+
90
+ Assert uses its [`Assert::Runner`](https://github.com/teaminsight/assert/blob/master/lib/assert/runner.rb) object to run tests by default. This runner runs its suite's tests in random order based on the suite's `runner_seed`.
91
+
92
+ You can extend this default runner or use your own runner implementation. Either way, specify that you want to use your new runner class by adding this to your user options file
93
+
94
+ ```ruby
95
+ Assert.runner MyAwesomeRunner
96
+ ```
97
+
98
+ ### Test Order
99
+
100
+ The default runner object runs tests in random order and the `DefaultView` view will display the seed value. If you want to run tests in a consistant order, set a 'runner_seed' environment variable. Here's an example running tests with rake:
101
+
102
+ ```
103
+ $ rake test # run tests in random order
104
+ $ rake test runner_seed=1234 # run tests seeding with '1234'
105
+ ```
106
+
107
+ ## Viewing Test Results
108
+
109
+ You have a few options when it comes to viewing test results in Assert. Assert comes with its own `DefaultView` class that handles displaying test results.
110
+
111
+ First, lets look at the default: `Assert::View::DefaultView`. This is the default view class. Its output goes something like this:
112
+
113
+ * before the run starts, output some info about the test suite that is about to run
114
+ * print out result abbreviations as the test results are generated
115
+ * after the run finishes...
116
+ * display any result details (from failing or error results) in reverse test/result order
117
+ * output some summary info
118
+
119
+ You can run assert's test suite using `rake test` and get a feel for what this default outputs. This view has a few options you can tweak:
120
+
121
+ * `styled`: whether to apply ANSI styles to the output, default `true`
122
+ * `pass_styles`: how to style pass result output, default `:green`
123
+ * `fail_styles`: default `:red, :bold`
124
+ * `error_styles`: default `:yellow, :bold`
125
+ * `skip_styles`: default `:cyan`
126
+ * `ignore_styles`: default: `:magenta`
127
+
128
+ To override an option, do so in your user options file:
129
+
130
+ ```ruby
131
+ Assert.view.options.styled false
132
+ ```
133
+
134
+ However, the view you use is configurable. Define you own view class and specify it in your `~/.assert/options.rb` file:
135
+
136
+ ```ruby
137
+ class MyCustomView < Assert::View::Base
138
+ # define your view here...
139
+ end
140
+
141
+ Assert.options.view MyCustomView.new
142
+ ```
143
+
144
+ ### Anatomy of a View
145
+
146
+ A view class handles the logic and templating of test result output. A view class should inherit from `Assert::View::Base`. This defines default callback handlers for the test runner and gives access to a bunch of common helpers for reading test result data.
147
+
148
+ Each view should implement the callback handler methods to output information at different points during the running of a test suite. Callbacks have access to any view methods and should output information using `puts` and `prints`. See the `DefaultView` template for a usage example.
149
+
150
+ Available callbacks from the runner, and when they are called:
151
+
152
+ * `before_load`: at the beginning, before the suite is loaded
153
+ * `after_load`: after the suite is loaded, just before `on_start`
154
+ * `on_start`: when a loaded test suite starts running
155
+ * `before_test`: before a test starts running, the test is passed as an arg
156
+ * `on_result`: when a running tests generates a result, the result is passed as an arg
157
+ * `after_test`: after a test finishes running, the test is passed as an arg
158
+ * `on_finish`: when the test suite is finished running
159
+
160
+ Beyond that, each view can do as it sees fit. Initialize how you wish, take whatever options you'd like, and output results as you see fit, given the available callbacks.
161
+
162
+ ### Using 3rd party views
163
+
164
+ To use a 3rd party custom view, you first require it in and then specify using the `Assert.options.view` option. Assert provides a helper for requiring in views. It can be used in two ways. You can pass a fully qualified path to the helper and if it exists, will require it in.
165
+
166
+ ```ruby
167
+ Assert::View.require_user_view '/path/to/my/view'
168
+ ```
169
+
170
+ Alternatively, you can install/clone/copy/write your view implementations in `~/.assert/views` and require it in by name. To have assert require it by name, have it installed at `~/assert/views/view_name/lib/view_name.rb` (this structure is compatible with popular conventions in rubygem development). For example:
171
+
172
+ ```ruby
173
+ # assuming ~/.assert/views/my-custom-view/lib/my-custom-view.rb exists
174
+ # this will require it in
175
+ Assert::View.require_user_view 'my-custom-view'
176
+ ```
177
+
178
+ Once your view class is required in, use it and configure it just as you would any view.
179
+
180
+ ## Failure Handling
181
+
182
+ Assert, by default, will halt test execution when a test produces a Fail result. However, Assert provides an option to not halt when Fail results are produced. You can control how assert handles fails by either setting a user option (in your user `~/.assert/options.rb` file):
183
+
184
+ ```ruby
185
+ Assert::Test.options.halt_on_fail false # force not halting on fail results
186
+ ```
187
+
188
+ or by setting an env variable:
189
+
190
+ ```
191
+ $ rake test halt_on_fail=true # force halt on failure using an env var
192
+ ```
193
+
194
+ ## Rake Tasks
195
+
196
+ Assert provides some rake task helpers that will scan your test folder and recursively generate rake tasks for each one of your test folders or files. Test files must end in either `'_test.rb'` or `'_tests.rb'`. Use this as an alternative to running ruby on each one of your test files individually.
197
+
198
+ As an example, say your test folder has a file structure like so:
199
+
200
+ ```
201
+ - test
202
+ | - basic_test.rb
203
+ | - helper.rb
204
+ | - complex
205
+ | | - fast_tests.rb
206
+ | | - slow_tests.rb
207
+ ```
208
+
209
+ Add the following to your Rakefile to generate the test tasks:
210
+
211
+ ```ruby
212
+ require 'assert/rake_tasks'
213
+ Assert::RakeTasks.install
214
+ ```
215
+
216
+ This would generate following rake tasks:
217
+
218
+ ```
219
+ $ rake -T
220
+ rake test # Run all tests
221
+ rake test:basic # Run tests for basic
222
+ rake test:complex # Run all tests for assertions
223
+ rake test:complex:fast # Run tests for assertions:assert_block
224
+ rake test:complex:slow # Run tests for assertions:assert_empty
225
+ ```
226
+
227
+ By default, the rake tasks do not show which test files are being loaded. If you want to see this output from the rake tasks, set a "show_loaded_files" environment variable at the rake command line:
228
+
229
+ ```
230
+ $ rake test show_loaded_files=true # run the tests showing which files were loaded
231
+ ```
232
+
233
+ ## IRB with your environment loaded
234
+
235
+ Assert provides a rake task for running irb with your test environment loaded. Create an `irb.rb` file in your test file directory and have it `require 'assert/setup'`. See [Assert's irb.rb](https://github.com/teaminsight/assert/blob/master/test/irb.rb) for an example. Here's how you could use it:
236
+
237
+ ```
238
+ $ rake irb
239
+ > Assert
240
+ => Assert
241
+ ```
242
+
243
+ ## The Assert family of testing tools
244
+
245
+ TODO: add in references to assert related tools.
246
+
247
+ ## Contributing
248
+
249
+ The source code is hosted on Github. Feel free to submit pull requests and file bugs on the issues tracker.
250
+
251
+ If submitting a Pull Request, please:
252
+
253
+ 1. Fork it
254
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
255
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
256
+ 4. Push to the branch (`git push origin my-new-feature`)
257
+ 5. Create new Pull Request
258
+
259
+ One note: please respect that Assert itself is intended to be the flexible, base-level type logic that should change little if at all. Pull requests for niche functionality or personal testing philosphy stuff will likely not be accepted.
260
+
261
+ If you wish to extend Assert for your niche purpose/desire/philosophy, please do so in it's own gem (preferrably named 'assert-<whatever>') that uses Assert as a dependency. When you do, tell us about it and we'll add to this readme with a short description.
data/Rakefile CHANGED
@@ -1,5 +1,5 @@
1
1
  require 'assert/rake_tasks'
2
- Assert::RakeTasks.for(:test)
2
+ Assert::RakeTasks.install
3
3
 
4
4
  require 'bundler'
5
5
  Bundler::GemHelper.install_tasks
@@ -18,5 +18,6 @@ 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("assert-view", ["~> 0.5"])
21
+ s.add_dependency("ansi", ["~> 1.3"])
22
+
22
23
  end
@@ -74,6 +74,7 @@ module Assert
74
74
  ].join
75
75
  assert(object.respond_to?(method), fail_desc, what_failed_msg)
76
76
  end
77
+ alias_method :assert_responds_to, :assert_respond_to
77
78
 
78
79
  def assert_not_respond_to(method, object, fail_desc=nil)
79
80
  what_failed_msg = [
@@ -82,7 +83,9 @@ module Assert
82
83
  ].join
83
84
  assert(!object.respond_to?(method), fail_desc, what_failed_msg)
84
85
  end
86
+ alias_method :assert_not_responds_to, :assert_not_respond_to
85
87
  alias_method :refute_respond_to, :assert_not_respond_to
88
+ alias_method :refute_responds_to, :assert_not_respond_to
86
89
 
87
90
 
88
91
 
@@ -180,6 +183,19 @@ module Assert
180
183
 
181
184
 
182
185
 
186
+ def assert_file_exists(file_path, fail_desc=nil)
187
+ what_failed_msg = "Expected #{file_path.inspect} to exist."
188
+ assert(File.exists?(File.expand_path(file_path)), fail_desc, what_failed_msg)
189
+ end
190
+
191
+ def assert_not_file_exists(file_path, fail_desc=nil)
192
+ what_failed_msg = "Expected #{file_path.inspect} to not exist."
193
+ assert(!File.exists?(File.expand_path(file_path)), fail_desc, what_failed_msg)
194
+ end
195
+ alias_method :refute_file_exists, :assert_not_file_exists
196
+
197
+
198
+
183
199
  IGNORED_ASSERTION_HELPERS = [ :assert_throws, :assert_nothing_thrown, :assert_send,
184
200
  :assert_operator, :refute_operator, :assert_in_epsilon, :refute_in_epsilon,
185
201
  :assert_in_delta, :refute_in_delta
@@ -5,12 +5,14 @@ module Assert
5
5
  # a flag to know if at_exit hook has been installed already
6
6
  @@at_exit_installed ||= false
7
7
 
8
- class << self
8
+ # install at_exit hook (if needed) (runs at process exit)
9
+ # this ensures the test suite won't run until all test files are loaded
10
+ # (this is essentially a direct rip from Minitest)
11
+
12
+ def self.autorun
13
+ if !@@at_exit_installed
14
+ self.view.fire(:before_load)
9
15
 
10
- # install at_exit hook (if needed) (runs at process exit)
11
- # this ensures the test suite won't run unitl all test files are loaded
12
- # (this is essentially a direct rip from Minitest)
13
- def autorun
14
16
  at_exit do
15
17
  # don't run if there was an exception
16
18
  next if $!
@@ -22,11 +24,13 @@ module Assert
22
24
 
23
25
  exit_code = nil
24
26
  at_exit { exit(false) if exit_code && exit_code != 0 }
27
+
28
+ self.view.fire(:after_load)
25
29
  self.runner.new(self.suite, self.view).run
26
- end unless @@at_exit_installed
30
+ end
31
+
27
32
  @@at_exit_installed = true
28
33
  end
29
-
30
34
  end
31
35
 
32
36
  end
@@ -22,6 +22,19 @@ module Assert::Macros
22
22
  end
23
23
  alias_method :have_instance_methods, :have_instance_method
24
24
 
25
+ def not_have_instance_method(*methods)
26
+ called_from = (methods.last.kind_of?(Array) ? methods.pop : caller).first
27
+ name = "not have instance methods: #{methods.map{|m| "'#{m}'"}.join(', ')}"
28
+ Assert::Macro.new(name) do
29
+ methods.each do |method|
30
+ should "not respond to instance method ##{method}", called_from do
31
+ assert_not_respond_to method, subject, "#{subject.class.name} has instance method ##{method}"
32
+ end
33
+ end
34
+ end
35
+ end
36
+ alias_method :not_have_instance_methods, :not_have_instance_method
37
+
25
38
  def have_class_method(*methods)
26
39
  called_from = (methods.last.kind_of?(Array) ? methods.pop : caller).first
27
40
  name = "have class methods: #{methods.map{|m| "'#{m}'"}.join(', ')}"
@@ -35,14 +48,31 @@ module Assert::Macros
35
48
  end
36
49
  alias_method :have_class_methods, :have_class_method
37
50
 
38
- def have_reader(*methods)
39
- unless methods.last.kind_of?(Array)
40
- methods << caller
51
+ def not_have_class_method(*methods)
52
+ called_from = (methods.last.kind_of?(Array) ? methods.pop : caller).first
53
+ name = "not have class methods: #{methods.map{|m| "'#{m}'"}.join(', ')}"
54
+ Assert::Macro.new(name) do
55
+ methods.each do |method|
56
+ should "not respond to class method ##{method}", called_from do
57
+ assert_not_respond_to method, subject.class, "#{subject.class.name} has class method ##{method}"
58
+ end
59
+ end
41
60
  end
61
+ end
62
+ alias_method :not_have_class_methods, :not_have_class_method
63
+
64
+ def have_reader(*methods)
65
+ methods << caller if !methods.last.kind_of?(Array)
42
66
  have_instance_methods(*methods)
43
67
  end
44
68
  alias_method :have_readers, :have_reader
45
69
 
70
+ def not_have_reader(*methods)
71
+ methods << caller if !methods.last.kind_of?(Array)
72
+ not_have_instance_methods(*methods)
73
+ end
74
+ alias_method :not_have_readers, :not_have_reader
75
+
46
76
  def have_writer(*methods)
47
77
  called = methods.last.kind_of?(Array) ? methods.pop : caller
48
78
  writer_meths = methods.collect{|m| "#{m}="}
@@ -51,6 +81,14 @@ module Assert::Macros
51
81
  end
52
82
  alias_method :have_writers, :have_writer
53
83
 
84
+ def not_have_writer(*methods)
85
+ called = methods.last.kind_of?(Array) ? methods.pop : caller
86
+ writer_meths = methods.collect{|m| "#{m}="}
87
+ writer_meths << called
88
+ not_have_instance_methods(*writer_meths)
89
+ end
90
+ alias_method :not_have_writers, :not_have_writer
91
+
54
92
  def have_accessor(*methods)
55
93
  called = methods.last.kind_of?(Array) ? methods.pop : caller
56
94
  accessor_meths = methods.collect{|m| [m, "#{m}="]}.flatten
@@ -59,6 +97,14 @@ module Assert::Macros
59
97
  end
60
98
  alias_method :have_accessors, :have_accessor
61
99
 
100
+ def not_have_accessor(*methods)
101
+ called = methods.last.kind_of?(Array) ? methods.pop : caller
102
+ accessor_meths = methods.collect{|m| [m, "#{m}="]}.flatten
103
+ accessor_meths << called
104
+ not_have_instance_methods(*accessor_meths)
105
+ end
106
+ alias_method :not_have_accessors, :not_have_accessor
107
+
62
108
  end
63
109
 
64
110
  end