Next step in upgrading Tracks to Rails 2.2. Some highlights:

* Ran rake rails:update
* Added old actionwebservice framework
* Updated RSpec and RSpec-Rails
* Removed asset_packager plugin (not compatible, Scott no longer maintaining), and replaced with bundle_fu. See the bundle_fu README for more info.
* Hacks to UJS and ARTS plugins, which are no longer supported. Probably should move off both UJS and RJS.
* Hack to flashobject_helper plugin (upgrade to Rails 2.2-compatible version if/when it comes out.)
* Hack to skinny-spec plugin, for Rails 2.2 compatibility. Should check for official release.
* Hacks to resource_feeder plugin, for Rails 2.2 compatibility. Should check for official release (not likely) or move off it.
* Addressed some deprecation warnings. More to come.
* My mobile mime type hackery is no longer necessary with new Rails features. Yay!
* Updated environment.rb.tmpl with changes

TODO:
* Restore view specs marked pending
* Fix failing integration tests.
* Try selenium tests.
* Investigate OpenID support.
* Address deprecation warnings.
* Consider moving parts of environment.rb to initializers
* Address annoying config.gem warning about highline gem
This commit is contained in:
Luke Melia 2008-11-29 12:00:06 -05:00
parent 6d11ebd1b0
commit 35ae5fc431
394 changed files with 15184 additions and 9936 deletions

View file

@ -1,7 +1,9 @@
pkg
doc
coverage
tmtags
story_server/prototype/rspec_stories.html
.DS_Store
.emacs-project
*~
email.txt

View file

@ -1,5 +1,57 @@
== Version 1.1.5 (in git)
=== Maintenance
* 5 bug fixes
* spec command prints help when no arguments
* fixed typo in help. Fixes #73.
* fixed bug where should_receive..and_yield after similar stub added the args_to_yield to the stub's original args_to_yield (Pat Maddox)
* fixed bug where rspec-autotest (autospec) was loading non-spec files in spec directory. Fixes #559.
* fixed bug where should_not_receive was reporting twice
* 2 minor enhancements
* mingw indicates windows too (thanks to Luis Lavena for the tip)
* improved output for partial mock expecation failures
=== Version 1.1.8 / 2008-10-03
* 2 bug fixes
* restore colorized output in linux and windows w/ autotest (Tim Pope). Fixes #413.
* autospec no longer hangs on windows. Fixes #554.
=== Version 1.1.7 / 2008-10-02
* no changes since 1.1.6, but releasing rspec-1.1.7 to align versions with rspec-rails-1.1.7
=== Version 1.1.6 / 2008-10-02
* 2 bug fixes
* fixed bug where negative message expectations following stubs resulted in false (negative) positives (Mathias Meyer). Closes #548.
* fixed bug where Not Yet Implemented examples report incorrect caller (Scott Taylor). Closes #547.
* 1 minor enhancement
* removed deprecated mock argument constraint symbols
=== Version 1.1.5 / 2008-09-28
IMPORTANT: use the new 'autospec' command instead of 'autotest'. We changed
the way autotest discovers rspec so the autotest executable won't
automatically load rspec anymore. This allows rspec to live side by side other
spec frameworks without always co-opting autotest through autotest's discovery
mechanism.
ALSO IMPORTANT: $rspec_options is gone. If you were using this for anything
(like your own runners), use Spec::Runner.options instead.
ADDITIONALLY IMPORTANT: If you have any custom formatters, you'll need to
modify #example_pending to accept three arguments instead of just two. See the
rdoc for Spec::Runner::Formatter::BaseFormatter#example_pending for more
information.
* Consider MinGW as valid RUBY_PLATFORM for --colour option. (patch from Luis Lavena). Closes #406.
* Added additional characters to be escaped in step strings (patch from Jake Cahoon). Closes #417.
* Disable color codes on STDOUT when STDOUT.tty? is false (patch from Tim Pope). Closes #413.
* mock(:null_object=>true) plays nice with HTML (patch from Gerrit Kaiser). Closes #230.
@ -10,8 +62,31 @@
* html story formatter correctly colors story/scenario red if step fails (Patch from Joseph Wilk). Closes #300
* plain text story formatter correctly colors story/scenario red if step fails (Patch from Joseph Wilk). Closes #439
* quiet deprecation warning on inflector - patch from RSL. Closes #430
* added autospec executable
* added configurable messages to simple_matcher
* should and should_not return true on success
* use hoe for build/release
* bye, bye translator
* autotest/rspec uses ruby command instead of spec command (no need for spec command unless loading directories)
* Avoid 'invalid option -O' in autotest (patch from Jonathan del Strother). Closes #486.
* Fix: Unimplemented step with new line throws error (patch from Ben Mabey). Closes #494.
* Only use color codes on tty; override for autospec (patch from Tim Pope). Closes #413.
* Warn when setting mock expectations on nil (patch from Ben Mabey). Closes #521.
* Support argument constraints as values in the hash_including contstraint. Thanks to Pirkka Hartikainen for failing code examples and the fix. Buttons up #501.
* mock(:null_object=>true) plays nice with HTML (patch from Gerrit Kaiser)
* Consider MinGW as valid RUBY_PLATFORM for --colour option. (patch from Luis Lavena). Closes #406.
* Add 2nd arg to respond_to? to align w/ core Ruby rdoc: http://www.ruby-doc.org/core/classes/Object.html#M000604
* quiet backtrace tweaker filters individual lines out of multiline (ala Rails) error messages (Pat Maddox)
* added ability to stub multiple methods in one stub! call (Pat Maddox)
* story progress bar formatter and more colourful summaries from the plain text story formatter (Joseph Wilk)
* Avoid ruby invocation errors when autotesting (Jonathan del Strother)
* added mock('foo').as_null_object
* add file and line number to pending_example for formatters (Scott Taylor)
* return last stubbed value for mock expectation with no explicit return (Pat Maddox)
* Fixed bug when should_receive(:foo).any_number_of_times is called after similar stub (Pat Maddox)
* Warning messages now issued when expectations are set on nil (Ben Mabey)
== Version 1.1.4
=== Version 1.1.4
Maintenance release.
@ -45,7 +120,7 @@ metaclass call with (class << self; self; end) and all will be well.
* decoupled mock framework from global extensions used by rspec - supports use of flexmock or mocha w/ rails
* Applied patch from Roman Chernyatchik to allow the user to pass in the ruby version into spectask. Closes #325, #370
== Version 1.1.3
=== Version 1.1.3
Maintenance release.
Notice to autotest users: you must also upgrade to ZenTest-3.9.0.
@ -63,7 +138,7 @@ Notice to autotest users: you must also upgrade to ZenTest-3.9.0.
* More tweaks to regexp step names
* Fixed focused specs in nested ExampleGroups. Closes #225.
== Version 1.1.2
=== Version 1.1.2
Minor bug fixes/enhancements.
Notice to autotest users: you must also upgrade to ZenTest-3.8.0.
@ -79,14 +154,14 @@ Notice to autotest users: you must also upgrade to ZenTest-3.8.0.
* Applied patch from Ian Dees to quiet the Story Runner backtrace. Closes #183.
* Complete support for defining steps with regexp 'names'.
== Version 1.1.1
=== Version 1.1.1
Bug fix release.
* Fix regression in 1.1.0 that caused transactions to not get rolled back between examples.
* Applied patch from Bob Cotton to reintroduce ExampleGroup.description_options. Closes LH[#186]
== Version 1.1.0
=== Version 1.1.0
The "tell me a story and go nest yourself" release.
@ -97,7 +172,7 @@ The "tell me a story and go nest yourself" release.
* Applied LH[#178] small annoyances running specs with warnings enabled (Patch from Mikko Lehtonen)
* Tighter integration with Rails fixtures. Take advantage of fixture caching to get performance improvements (Thanks to Pat Maddox, Nick Kallen, Jonathan Barnes, and Curtis)
== Version 1.1.0-RC1
=== Version 1.1.0-RC1
Textmate Bundle users - this release adds a new RSpec bundle that highlights describe, it, before and after and
provides navigation to descriptions and examples (rather than classes and methods). When you first install this,
@ -207,18 +282,18 @@ rspec_on_rails users - don't forget to run script/generate rspec
* Added (back) the verbose attribute in Spec::Rake::SpecTask
* Changed documentation to point at the new http svn URL, which is more accessible.
== Version 1.0.8
=== Version 1.0.8
Another bugfix release - this time to resolve the version mismatch
== Version 1.0.7
=== Version 1.0.7
Quick bugfix release to ensure that you don't have to have the rspec gem installed
in order to use autotest with rspec_on_rails.
* Fixed [#13015] autotest gives failure in 'spec_command' after upgrade 1.0.5 to 1.0.6
== Version 1.0.6
=== Version 1.0.6
The "holy cow, batman, it's been a long time since we released and there are a ton of bug
fixes, patches and even new features" release.
@ -295,7 +370,7 @@ able to use the passed Example instance as if it were a String.
* Documented environment variables for Spec::Rake::SpecTask. Renamed SPECOPTS and RCOVOPTS to SPEC_OPTS and RCOV_OPTS.
* Fixed [#10534] Windows: undefined method 'controller_name'
== Version 1.0.5
=== Version 1.0.5
Bug fixes. Autotest plugin tweaks.
* Fixed [#11378] fix to 10814 broke drb (re-opened #10814)
@ -307,7 +382,7 @@ Bug fixes. Autotest plugin tweaks.
* Fixed [#11247] standalone autotest doesn't work because of unneeded autotest.rb
* Applied [#11221] Autotest support does not work w/o Rails Gem installed (Patch from Josh Knowles)
== Version 1.0.4
=== Version 1.0.4
The getting ready for JRuby release.
* Fixed [#11181] behaviour_type scoping of config.before(:each) is not working
@ -319,7 +394,7 @@ The getting ready for JRuby release.
* Fixed [#11143] Views code for ActionController::Base#render broke between 1.0.0 and 1.0.3 on Rails Edge r6731
* Added raise_controller_errors for controller examples in Spec::Rails
== Version 1.0.3
=== Version 1.0.3
Bug fixes.
* Fixed [#11104] Website uses old specify notation
@ -330,10 +405,10 @@ Bug fixes.
* Fixed [#11082] RspecResourceGenerator should be RspecScaffoldGenerator
* Fixed [#10959] Focused Examples do not work for Behaviour defined with constant with modules
== Version 1.0.2
=== Version 1.0.2
This is just to align the version numbers in rspec and rspec_on_rails.
== Version 1.0.1
=== Version 1.0.1
This is a maintenance release with mostly cleaning up, and one minor enhancement -
Modules are automatically included when described directly.
@ -345,7 +420,7 @@ Modules are automatically included when described directly.
* Improved integration with autotest (Patches from Ryan Davis and David Goodland)
* Some small fixes to make all specs run on JRuby.
== Version 1.0.0
=== Version 1.0.0
The stake in the ground release. This represents a commitment to the API as it is. No significant
backwards compatibility changes in the API are expected after this release.
@ -370,7 +445,7 @@ backwards compatibility changes in the API are expected after this release.
* Applied [#10698] Running with --drb executes specs twice (patch from Ruy Asan)
* Fixed [#10871] 0.9.4 - Focussed spec runner fails to run specs in descriptions with type and string when there is no leading space in the string
== Version 0.9.4
=== Version 0.9.4
This release introduces massive improvements to Spec::Ui - the user interface functional testing
extension to RSpec. There are also some minor bug fixes to the RSpec core.
@ -383,7 +458,7 @@ extension to RSpec. There are also some minor bug fixes to the RSpec core.
* Each formatter now flushes their own IO. This is to avoid buffering of output.
* Fixed [#10670] IVarProxy#delete raises exception when instance variable does not exist
== Version 0.9.3
=== Version 0.9.3
This is a bugfix release.
* Fixed [#10594] Failing Custom Matcher show NAME NOT GENERATED description
@ -392,7 +467,7 @@ This is a bugfix release.
* Applied [#10566] prepend_before and prepend_after callbacks
* Applied [#10567] Call setup and teardown using before and after callbacks
== Version 0.9.2
=== Version 0.9.2
This is a quick maintenance release.
* Added some website love
@ -402,7 +477,7 @@ This is a quick maintenance release.
* Fixed --colour support for Windows. This is a regression that was introduced in 0.9.1
* Applied [#10460] Make SpecRunner easier to instantiate without using commandline args
== Version 0.9.1
=== Version 0.9.1
This release introduces #describe and #it (aliased as #context and #specify for
backwards compatibility). This allows you to express specs like this:
@ -519,15 +594,15 @@ See Spec::DSL::Behaviour for more on predicate_matchers
* Applied [#8994] trunk: generated names for be_ specs (Multiple patches from Yurii Rashkovskii)
* Applied [#9983]: Allow before and after to be called in BehaviourEval. This is useful for shared examples.
== Version 0.8.2
=== Version 0.8.2
Replaced assert_select fork with an assert_select wrapper for have_tag. This means that "should have_rjs" no longer supports :hide or :effect, but you can still use should_have_rjs for those.
== Version 0.8.1
=== Version 0.8.1
Quick "in house" bug-fix
== Version 0.8.0
=== Version 0.8.0
This release introduces a new approach to handling expectations using Expression Matchers.
@ -587,11 +662,11 @@ It also sports myriad new features, bug fixes, patches and general goodness:
* Applied [#7393] Fix for rake task (Patch from Pat Maddox)
* Reinstated support for response.should_render (in addition to controller.should_render)
== Version 0.7.5.1
=== Version 0.7.5.1
Bug fix release to allow downloads of rspec gem using rubygems 0.9.1.
== Version 0.7.5
=== Version 0.7.5
This release adds support for Heckle - Seattle'rb's code mutation tool.
There are also several bug fixes to the RSpec core and the RSpec on Rails plugin.
@ -614,7 +689,7 @@ There are also several bug fixes to the RSpec core and the RSpec on Rails plugin
* Applied [#6989] partials with locals (patch from Micah Martin)
* Applied [#7023] Typo in team.page
== Version 0.7.4
=== Version 0.7.4
This release features a complete redesign of the reports generated with --format html.
As usual there are many bug fixes - mostly related to spec/rails.
@ -636,7 +711,7 @@ As usual there are many bug fixes - mostly related to spec/rails.
* Using obj.inspect for all messages
* Improved performance by getting rid of instance_exec (instance_eval is good enough because we never need to pass it args)
== Version 0.7.3
=== Version 0.7.3
Almost normal bug fix/new feature release.
@ -657,7 +732,7 @@ A couple of things you need to change in your rails specs:
* Fixed [#6643] script/generate rspec_controller: invalid symbol generation for 'controller_name' for *modularized* controllers
* The script/rails_spec command has been moved to bin/drbspec in RSpec core (installed by the gem)
== Version 0.7.2
=== Version 0.7.2
This release introduces a brand new RSpec bundle for TextMate, plus some small bugfixes.
@ -669,7 +744,7 @@ This release introduces a brand new RSpec bundle for TextMate, plus some small b
* Added [#6589] New -l --line option. This is useful for IDE/editor runners/extensions.
* Fixed [#6615] controller.should_render_rjs should support :partial => 'path/to/template'
== Version 0.7.1
=== Version 0.7.1
Bug fixes and a couple o' new features.
@ -688,7 +763,7 @@ Bug fixes and a couple o' new features.
* Different printing and colours for unmet expectations (red) and other exceptions (magenta)
* Simplified method_missing on mock_methods to make it less invasive on partial mocks.
== Version 0.7.0
=== Version 0.7.0
This is the "Grow up and eat your own dog food release". RSpec is now used on itself and
we're no longer using Test::Unit to test it. Although, we are still extending Test::Unit
@ -775,7 +850,7 @@ As usual, there are also other new features and bug fixes:
* Added [#6334] subject.should_have_xyz will try to call subject.has_xyz? - use this for hash.should_have_key(key)
* Fixed [#6017] Rake task should ignore empty or non-existent spec-dirs
== Version 0.6.4
=== Version 0.6.4
In addition to a number of bug fixes and patches, this release begins to formalize the support for
RSpec on Rails.
@ -801,7 +876,7 @@ RSpec on Rails.
* Restructured directories and Modules in order to separate rspec into three distinct Modules: Spec::Expectations, Spec::Runner and Spec::Mocks. This will allow us to more easily integrate other mock frameworks and/or allow test/unit users to take advantage of the expectation API.
* Applied [#5620] support any boolean method and arbitrary comparisons (5.should_be < 6) (Patch from Mike Williams)
== Version 0.6.3
=== Version 0.6.3
This release fixes some minor bugs related to RSpec on Rails
Note that if you upgrade a rails app with this version of the rspec_on_rails plugin
@ -811,14 +886,14 @@ you should remove your lib/tasks/rspec.rake if it exists.
* Applied [#5557] Put rspec.rake into the task directory of the RSpec on Rails plugin (Patch from Daniel Siemssen)
* Applied [#5556] rails_spec_server loads environment.rb twice (Patch from Daniel Siemssen)
== Version 0.6.2
=== Version 0.6.2
This release fixes a couple of regressions with the rake task that were introduced in the previous version (0.6.1)
* Fixed [#5518] ruby -w: warnings in 0.6.1
* Applied [#5525] fix rake task path to spec tool for gem-installed rspec (patch from Riley Lynch)
* Fixed a teensey regression with the rake task - introduced in 0.6.1. The spec command is now quoted so it works on windows.
== Version 0.6.1
=== Version 0.6.1
This is the "fix the most annoying bugs release" of RSpec. There are 9 bugfixes this time.
Things that may break backwards compatibility:
1) Spec::Rake::SpecTask no longer has the options attribute. Use ruby_opts, spec_opts and rcov_opts instead.
@ -833,7 +908,7 @@ Things that may break backwards compatibility:
* Applied fixes to rails_spec_server to improve its ability to run several times. (Patch from Daniel Siemssen)
* Changed RCov::VerifyTask to fail if the coverage is above the threshold. This is to ensure it gets bumped when coverage improves.
== Version 0.6.0
=== Version 0.6.0
This release makes an official commitment to underscore_syntax (with no more support for dot.syntax)
* Fixed bug (5292) that caused mock argument matching to fail
@ -845,7 +920,7 @@ This release makes an official commitment to underscore_syntax (with no more sup
* Added support for should_not_receive(:msg) (will be removing should_receive(:msg).never some time soon)
* Added support for should_have_exactly(5).items_in_collection
== Version 0.5.16
=== Version 0.5.16
This release improves Rails support and test2spec translation.
* Fixed underscore problems that occurred when RSpec was used in Rails
@ -855,12 +930,12 @@ This release improves Rails support and test2spec translation.
* Added failure_message to RSpec Rake task
* test2spec now defines converted helper methods outside of the setup block (bug #5057).
== Version 0.5.15
=== Version 0.5.15
This release removes a prematurely added feature that shouldn't have been added.
* Removed support for differences that was added in 0.5.14. The functionality is not aligned with RSpec's vision.
== Version 0.5.14
=== Version 0.5.14
This release introduces better ways to extend specs, improves some of the core API and
a experimental support for faster rails specs.
@ -872,7 +947,7 @@ a experimental support for faster rails specs.
* Fixed bug that caused should_render to break if given a :symbol (in Rails)
* Added support for comparing exception message in should_raise and should_not_raise
== Version 0.5.13
=== Version 0.5.13
This release fixes some subtle bugs in the mock API.
* Use fully-qualified class name of Exceptions in failure message. Easier to debug that way.
@ -880,7 +955,7 @@ This release fixes some subtle bugs in the mock API.
* Mocks not raise AmbiguousReturnError if an explicit return is used at the same time as an expectation block.
* Blocks passed to yielding mocks can now raise without causing mock verification to fail.
== Version 0.5.12
=== Version 0.5.12
This release adds diff support for failure messages, a HTML formatter plus some other
minor enhancements.
@ -892,26 +967,26 @@ minor enhancements.
* Added --verbose mode for test2spec - useful for debugging when classes fail to translate.
* Output of various formatters is now flushed - to get more continuous output.
== Version 0.5.11
=== Version 0.5.11
This release makes test2spec usable with Rails (with some manual steps).
See http://rspec.rubyforge.org/tools/rails.html for more details
* test2spec now correctly translates bodies of helper methods (non- test_*, setup and teardown ones).
* Added more documentation about how to get test2spec to work with Rails.
== Version 0.5.10
=== Version 0.5.10
This version features a second rewrite of test2spec - hopefully better than the previous one.
* Improved test2spec's internals. It now transforms the syntax tree before writing out the code.
== Version 0.5.9
=== Version 0.5.9
This release improves test2spec by allowing more control over the output
* Added --template option to test2spec, which allows for custom output driven by ERB
* Added --quiet option to test2spec
* Removed unnecessary dependency on RubyToC
== Version 0.5.8
=== Version 0.5.8
This release features a new Test::Unit to RSpec translation tool.
Also note that the RubyGem of the previous release (0.5.7) was corrupt.
We're close to being able to translate all of RSpec's own Test::Unit
@ -920,7 +995,7 @@ tests and have them run successfully!
* Updated test2spec documentation.
* Replaced old test2rspec with a new test2spec, which is based on ParseTree and RubyInline.
== Version 0.5.7
=== Version 0.5.7
This release changes examples and documentation to recommend underscores rather than dots,
and addresses some bugfixes and changes to the spec commandline.
@ -928,12 +1003,12 @@ and addresses some bugfixes and changes to the spec commandline.
* All documentation and examples are now using '_' instead of '.'
* Custom external formatters can now be specified via --require and --format.
== Version 0.5.6
=== Version 0.5.6
This release fixes a bug in the Rails controller generator
* The controller generator did not write correct source code (missing 'do'). Fixed.
== Version 0.5.5
=== Version 0.5.5
This release adds initial support for Ruby on Rails in the rspec_generator gem.
* [Rails] Reorganised Lachie's original code to be a generator packaged as a gem rather than a plugin.
@ -941,7 +1016,7 @@ This release adds initial support for Ruby on Rails in the rspec_generator gem.
* Remove stack trace lines from TextMate's Ruby bundle
* Better error message from spectask when no spec files are found.
== Version 0.5.4
=== Version 0.5.4
The "the tutorial is ahead of the gem" release
* Support for running a single spec with --spec
@ -966,7 +1041,7 @@ The "the tutorial is ahead of the gem" release
* backtrace excludes rspec code - use -b to include it
* split examples into examples (passing) and failing_examples
== Version 0.5.3
=== Version 0.5.3
The "hurry up, CoR is in two days" release.
* Don't run rcov by default
@ -975,14 +1050,14 @@ The "hurry up, CoR is in two days" release.
* Even more failure output cleanup (simplification)
* Added duck_type constraint for mocks
== Version 0.5.2
=== Version 0.5.2
This release has minor improvements to the commandline and fixes some gem warnings
* Readded README to avoid RDoc warnings
* Added --version switch to commandline
* More changes to the mock API
== Version 0.5.1
=== Version 0.5.1
This release is the first release of RSpec with a new website. It will look better soon.
* Added initial documentation for API
@ -992,7 +1067,7 @@ This release is the first release of RSpec with a new website. It will look bett
* Various changes to the mock API,
* Various improvements to failure reporting
== Version 0.5.0
=== Version 0.5.0
This release introduces a new API and obsolesces previous versions.
* Moved source code to separate subfolders
@ -1002,20 +1077,20 @@ This release introduces a new API and obsolesces previous versions.
* this would be 0.5.0 if I updated the documentation
* it breaks all of your existing specifications. We're not sorry.
== Version 0.3.2
=== Version 0.3.2
The "srbaker is an idiot" release.
* also forgot to update the path to the actual Subversion repository
* this should be it
== Version 0.3.1
=== Version 0.3.1
This is just 0.3.0, but with the TUTORIAL added to the documentation list.
* forgot to include TUTORIAL in the documentation
== Version 0.3.0
=== Version 0.3.0
It's been a while since last release, lots of new stuff is available. For instance:
@ -1024,7 +1099,7 @@ It's been a while since last release, lots of new stuff is available. For insta
* some documentation improvements
* RSpec usable as a DSL
== Version 0.2.0
=== Version 0.2.0
This release provides a tutorial for new users wishing to get started with
RSpec, and many improvements.
@ -1033,7 +1108,7 @@ RSpec, and many improvements.
* update the examples to the new mock api
* added TUTORIAL, a getting started document for new users of RSpec
== Version 0.1.7
=== Version 0.1.7
This release improves installation and documentation, mock integration and error reporting.
@ -1048,27 +1123,27 @@ This release improves installation and documentation, mock integration and error
* Made more parts of the Spec::Context API private to avoid accidental usage.
* Added more RDoc to Spec::Context.
== Version 0.1.6
=== Version 0.1.6
More should methods.
* Added should_match and should_not_match.
== Version 0.1.5
=== Version 0.1.5
Included examples and tests in gem.
== Version 0.1.4
=== Version 0.1.4
More tests on block based Mock expectations.
== Version 0.1.3
=== Version 0.1.3
Improved mocking:
* block based Mock expectations.
== Version 0.1.2
=== Version 0.1.2
This release adds some improvements to the mock API and minor syntax improvements
@ -1079,14 +1154,14 @@ This release adds some improvements to the mock API and minor syntax improvement
* Improved exception trace by adding exception class name to error message.
* Renamed some tests for better consistency.
== Version 0.1.1
=== Version 0.1.1
This release adds some shoulds and improves error reporting
* Added should be_same_as and should_not be_same_as.
* Improved error reporting for comparison expectations.
== Version 0.1.0
=== Version 0.1.0
This is the first preview release of RSpec, a Behaviour-Driven Development library for Ruby

View file

@ -1,3 +1,5 @@
(The MIT License)
Copyright (c) 2005-2008 The RSpec Development Team
Permission is hereby granted, free of charge, to any person obtaining

404
vendor/plugins/rspec/Manifest.txt vendored Normal file
View file

@ -0,0 +1,404 @@
History.txt
License.txt
Manifest.txt
README.txt
Rakefile
TODO.txt
bin/autospec
bin/spec
examples/pure/autogenerated_docstrings_example.rb
examples/pure/before_and_after_example.rb
examples/pure/behave_as_example.rb
examples/pure/custom_expectation_matchers.rb
examples/pure/custom_formatter.rb
examples/pure/dynamic_spec.rb
examples/pure/file_accessor.rb
examples/pure/file_accessor_spec.rb
examples/pure/greeter_spec.rb
examples/pure/helper_method_example.rb
examples/pure/io_processor.rb
examples/pure/io_processor_spec.rb
examples/pure/legacy_spec.rb
examples/pure/mocking_example.rb
examples/pure/multi_threaded_behaviour_runner.rb
examples/pure/nested_classes_example.rb
examples/pure/partial_mock_example.rb
examples/pure/pending_example.rb
examples/pure/predicate_example.rb
examples/pure/priority.txt
examples/pure/shared_example_group_example.rb
examples/pure/shared_stack_examples.rb
examples/pure/spec_helper.rb
examples/pure/stack.rb
examples/pure/stack_spec.rb
examples/pure/stack_spec_with_nested_example_groups.rb
examples/pure/stubbing_example.rb
examples/pure/yielding_example.rb
examples/stories/adder.rb
examples/stories/addition
examples/stories/addition.rb
examples/stories/calculator.rb
examples/stories/game-of-life/.loadpath
examples/stories/game-of-life/README.txt
examples/stories/game-of-life/behaviour/everything.rb
examples/stories/game-of-life/behaviour/examples/examples.rb
examples/stories/game-of-life/behaviour/examples/game_behaviour.rb
examples/stories/game-of-life/behaviour/examples/grid_behaviour.rb
examples/stories/game-of-life/behaviour/stories/CellsWithLessThanTwoNeighboursDie.story
examples/stories/game-of-life/behaviour/stories/CellsWithMoreThanThreeNeighboursDie.story
examples/stories/game-of-life/behaviour/stories/EmptySpacesWithThreeNeighboursCreateACell.story
examples/stories/game-of-life/behaviour/stories/ICanCreateACell.story
examples/stories/game-of-life/behaviour/stories/ICanKillACell.story
examples/stories/game-of-life/behaviour/stories/TheGridWraps.story
examples/stories/game-of-life/behaviour/stories/create_a_cell.rb
examples/stories/game-of-life/behaviour/stories/helper.rb
examples/stories/game-of-life/behaviour/stories/kill_a_cell.rb
examples/stories/game-of-life/behaviour/stories/steps.rb
examples/stories/game-of-life/behaviour/stories/stories.rb
examples/stories/game-of-life/behaviour/stories/stories.txt
examples/stories/game-of-life/life.rb
examples/stories/game-of-life/life/game.rb
examples/stories/game-of-life/life/grid.rb
examples/stories/helper.rb
examples/stories/steps/addition_steps.rb
failing_examples/README.txt
failing_examples/diffing_spec.rb
failing_examples/failing_autogenerated_docstrings_example.rb
failing_examples/failure_in_setup.rb
failing_examples/failure_in_teardown.rb
failing_examples/mocking_example.rb
failing_examples/mocking_with_flexmock.rb
failing_examples/mocking_with_mocha.rb
failing_examples/mocking_with_rr.rb
failing_examples/partial_mock_example.rb
failing_examples/predicate_example.rb
failing_examples/raising_example.rb
failing_examples/spec_helper.rb
failing_examples/syntax_error_example.rb
failing_examples/team_spec.rb
failing_examples/timeout_behaviour.rb
init.rb
lib/autotest/discover.rb
lib/autotest/rspec.rb
lib/spec.rb
lib/spec/adapters.rb
lib/spec/adapters/ruby_engine.rb
lib/spec/adapters/ruby_engine/mri.rb
lib/spec/adapters/ruby_engine/rubinius.rb
lib/spec/example.rb
lib/spec/example/configuration.rb
lib/spec/example/errors.rb
lib/spec/example/example_group.rb
lib/spec/example/example_group_factory.rb
lib/spec/example/example_group_methods.rb
lib/spec/example/example_matcher.rb
lib/spec/example/example_methods.rb
lib/spec/example/module_inclusion_warnings.rb
lib/spec/example/module_reopening_fix.rb
lib/spec/example/pending.rb
lib/spec/example/shared_example_group.rb
lib/spec/expectations.rb
lib/spec/expectations/differs/default.rb
lib/spec/expectations/errors.rb
lib/spec/expectations/extensions.rb
lib/spec/expectations/extensions/object.rb
lib/spec/expectations/extensions/string_and_symbol.rb
lib/spec/expectations/handler.rb
lib/spec/extensions.rb
lib/spec/extensions/class.rb
lib/spec/extensions/main.rb
lib/spec/extensions/metaclass.rb
lib/spec/extensions/object.rb
lib/spec/interop/test.rb
lib/spec/interop/test/unit/autorunner.rb
lib/spec/interop/test/unit/testcase.rb
lib/spec/interop/test/unit/testresult.rb
lib/spec/interop/test/unit/testsuite_adapter.rb
lib/spec/interop/test/unit/ui/console/testrunner.rb
lib/spec/matchers.rb
lib/spec/matchers/be.rb
lib/spec/matchers/be_close.rb
lib/spec/matchers/change.rb
lib/spec/matchers/eql.rb
lib/spec/matchers/equal.rb
lib/spec/matchers/exist.rb
lib/spec/matchers/has.rb
lib/spec/matchers/have.rb
lib/spec/matchers/include.rb
lib/spec/matchers/match.rb
lib/spec/matchers/operator_matcher.rb
lib/spec/matchers/raise_error.rb
lib/spec/matchers/respond_to.rb
lib/spec/matchers/satisfy.rb
lib/spec/matchers/simple_matcher.rb
lib/spec/matchers/throw_symbol.rb
lib/spec/mocks.rb
lib/spec/mocks/argument_constraints.rb
lib/spec/mocks/argument_expectation.rb
lib/spec/mocks/error_generator.rb
lib/spec/mocks/errors.rb
lib/spec/mocks/extensions.rb
lib/spec/mocks/extensions/object.rb
lib/spec/mocks/framework.rb
lib/spec/mocks/message_expectation.rb
lib/spec/mocks/methods.rb
lib/spec/mocks/mock.rb
lib/spec/mocks/order_group.rb
lib/spec/mocks/proxy.rb
lib/spec/mocks/space.rb
lib/spec/mocks/spec_methods.rb
lib/spec/rake/spectask.rb
lib/spec/rake/verify_rcov.rb
lib/spec/runner.rb
lib/spec/runner/backtrace_tweaker.rb
lib/spec/runner/class_and_arguments_parser.rb
lib/spec/runner/command_line.rb
lib/spec/runner/drb_command_line.rb
lib/spec/runner/example_group_runner.rb
lib/spec/runner/formatter/base_formatter.rb
lib/spec/runner/formatter/base_text_formatter.rb
lib/spec/runner/formatter/failing_example_groups_formatter.rb
lib/spec/runner/formatter/failing_examples_formatter.rb
lib/spec/runner/formatter/html_formatter.rb
lib/spec/runner/formatter/nested_text_formatter.rb
lib/spec/runner/formatter/profile_formatter.rb
lib/spec/runner/formatter/progress_bar_formatter.rb
lib/spec/runner/formatter/snippet_extractor.rb
lib/spec/runner/formatter/specdoc_formatter.rb
lib/spec/runner/formatter/story/html_formatter.rb
lib/spec/runner/formatter/story/plain_text_formatter.rb
lib/spec/runner/formatter/story/progress_bar_formatter.rb
lib/spec/runner/formatter/text_mate_formatter.rb
lib/spec/runner/heckle_runner.rb
lib/spec/runner/heckle_runner_unsupported.rb
lib/spec/runner/option_parser.rb
lib/spec/runner/options.rb
lib/spec/runner/reporter.rb
lib/spec/runner/spec_parser.rb
lib/spec/story.rb
lib/spec/story/extensions.rb
lib/spec/story/extensions/main.rb
lib/spec/story/extensions/regexp.rb
lib/spec/story/extensions/string.rb
lib/spec/story/given_scenario.rb
lib/spec/story/runner.rb
lib/spec/story/runner/plain_text_story_runner.rb
lib/spec/story/runner/scenario_collector.rb
lib/spec/story/runner/scenario_runner.rb
lib/spec/story/runner/story_mediator.rb
lib/spec/story/runner/story_parser.rb
lib/spec/story/runner/story_runner.rb
lib/spec/story/scenario.rb
lib/spec/story/step.rb
lib/spec/story/step_group.rb
lib/spec/story/step_mother.rb
lib/spec/story/story.rb
lib/spec/story/world.rb
lib/spec/version.rb
plugins/mock_frameworks/flexmock.rb
plugins/mock_frameworks/mocha.rb
plugins/mock_frameworks/rr.rb
plugins/mock_frameworks/rspec.rb
rake_tasks/examples.rake
rake_tasks/examples_with_rcov.rake
rake_tasks/failing_examples_with_html.rake
rake_tasks/verify_rcov.rake
rspec.gemspec
spec/README.jruby
spec/autotest/autotest_helper.rb
spec/autotest/autotest_matchers.rb
spec/autotest/discover_spec.rb
spec/autotest/rspec_spec.rb
spec/rspec_suite.rb
spec/ruby_forker.rb
spec/spec.opts
spec/spec/adapters/ruby_engine_spec.rb
spec/spec/example/configuration_spec.rb
spec/spec/example/example_group/described_module_spec.rb
spec/spec/example/example_group/warning_messages_spec.rb
spec/spec/example/example_group_class_definition_spec.rb
spec/spec/example/example_group_factory_spec.rb
spec/spec/example/example_group_methods_spec.rb
spec/spec/example/example_group_spec.rb
spec/spec/example/example_matcher_spec.rb
spec/spec/example/example_methods_spec.rb
spec/spec/example/example_runner_spec.rb
spec/spec/example/nested_example_group_spec.rb
spec/spec/example/pending_module_spec.rb
spec/spec/example/predicate_matcher_spec.rb
spec/spec/example/shared_example_group_spec.rb
spec/spec/example/subclassing_example_group_spec.rb
spec/spec/expectations/differs/default_spec.rb
spec/spec/expectations/extensions/object_spec.rb
spec/spec/expectations/fail_with_spec.rb
spec/spec/extensions/main_spec.rb
spec/spec/interop/test/unit/resources/spec_that_fails.rb
spec/spec/interop/test/unit/resources/spec_that_passes.rb
spec/spec/interop/test/unit/resources/spec_with_errors.rb
spec/spec/interop/test/unit/resources/test_case_that_fails.rb
spec/spec/interop/test/unit/resources/test_case_that_passes.rb
spec/spec/interop/test/unit/resources/test_case_with_errors.rb
spec/spec/interop/test/unit/resources/testsuite_adapter_spec_with_test_unit.rb
spec/spec/interop/test/unit/spec_spec.rb
spec/spec/interop/test/unit/test_unit_spec_helper.rb
spec/spec/interop/test/unit/testcase_spec.rb
spec/spec/interop/test/unit/testsuite_adapter_spec.rb
spec/spec/matchers/be_close_spec.rb
spec/spec/matchers/be_spec.rb
spec/spec/matchers/change_spec.rb
spec/spec/matchers/description_generation_spec.rb
spec/spec/matchers/eql_spec.rb
spec/spec/matchers/equal_spec.rb
spec/spec/matchers/exist_spec.rb
spec/spec/matchers/handler_spec.rb
spec/spec/matchers/has_spec.rb
spec/spec/matchers/have_spec.rb
spec/spec/matchers/include_spec.rb
spec/spec/matchers/match_spec.rb
spec/spec/matchers/matcher_methods_spec.rb
spec/spec/matchers/mock_constraint_matchers_spec.rb
spec/spec/matchers/operator_matcher_spec.rb
spec/spec/matchers/raise_error_spec.rb
spec/spec/matchers/respond_to_spec.rb
spec/spec/matchers/satisfy_spec.rb
spec/spec/matchers/simple_matcher_spec.rb
spec/spec/matchers/throw_symbol_spec.rb
spec/spec/mocks/any_number_of_times_spec.rb
spec/spec/mocks/argument_expectation_spec.rb
spec/spec/mocks/at_least_spec.rb
spec/spec/mocks/at_most_spec.rb
spec/spec/mocks/bug_report_10260_spec.rb
spec/spec/mocks/bug_report_10263_spec.rb
spec/spec/mocks/bug_report_11545_spec.rb
spec/spec/mocks/bug_report_15719_spec.rb
spec/spec/mocks/bug_report_496.rb
spec/spec/mocks/bug_report_7611_spec.rb
spec/spec/mocks/bug_report_7805_spec.rb
spec/spec/mocks/bug_report_8165_spec.rb
spec/spec/mocks/bug_report_8302_spec.rb
spec/spec/mocks/failing_mock_argument_constraints_spec.rb
spec/spec/mocks/hash_including_matcher_spec.rb
spec/spec/mocks/mock_ordering_spec.rb
spec/spec/mocks/mock_space_spec.rb
spec/spec/mocks/mock_spec.rb
spec/spec/mocks/multiple_return_value_spec.rb
spec/spec/mocks/nil_expectation_warning_spec.rb
spec/spec/mocks/null_object_mock_spec.rb
spec/spec/mocks/once_counts_spec.rb
spec/spec/mocks/options_hash_spec.rb
spec/spec/mocks/partial_mock_spec.rb
spec/spec/mocks/partial_mock_using_mocks_directly_spec.rb
spec/spec/mocks/passing_mock_argument_constraints_spec.rb
spec/spec/mocks/precise_counts_spec.rb
spec/spec/mocks/record_messages_spec.rb
spec/spec/mocks/stub_spec.rb
spec/spec/mocks/twice_counts_spec.rb
spec/spec/package/bin_spec_spec.rb
spec/spec/runner/class_and_argument_parser_spec.rb
spec/spec/runner/command_line_spec.rb
spec/spec/runner/drb_command_line_spec.rb
spec/spec/runner/empty_file.txt
spec/spec/runner/examples.txt
spec/spec/runner/failed.txt
spec/spec/runner/formatter/base_formatter_spec.rb
spec/spec/runner/formatter/failing_example_groups_formatter_spec.rb
spec/spec/runner/formatter/failing_examples_formatter_spec.rb
spec/spec/runner/formatter/html_formatted-1.8.4.html
spec/spec/runner/formatter/html_formatted-1.8.5-jruby.html
spec/spec/runner/formatter/html_formatted-1.8.5.html
spec/spec/runner/formatter/html_formatted-1.8.6-jruby.html
spec/spec/runner/formatter/html_formatted-1.8.6.html
spec/spec/runner/formatter/html_formatter_spec.rb
spec/spec/runner/formatter/nested_text_formatter_spec.rb
spec/spec/runner/formatter/profile_formatter_spec.rb
spec/spec/runner/formatter/progress_bar_formatter_spec.rb
spec/spec/runner/formatter/snippet_extractor_spec.rb
spec/spec/runner/formatter/spec_mate_formatter_spec.rb
spec/spec/runner/formatter/specdoc_formatter_spec.rb
spec/spec/runner/formatter/story/html_formatter_spec.rb
spec/spec/runner/formatter/story/plain_text_formatter_spec.rb
spec/spec/runner/formatter/story/progress_bar_formatter_spec.rb
spec/spec/runner/formatter/text_mate_formatted-1.8.4.html
spec/spec/runner/formatter/text_mate_formatted-1.8.6.html
spec/spec/runner/heckle_runner_spec.rb
spec/spec/runner/heckler_spec.rb
spec/spec/runner/noisy_backtrace_tweaker_spec.rb
spec/spec/runner/option_parser_spec.rb
spec/spec/runner/options_spec.rb
spec/spec/runner/output_one_time_fixture.rb
spec/spec/runner/output_one_time_fixture_runner.rb
spec/spec/runner/output_one_time_spec.rb
spec/spec/runner/quiet_backtrace_tweaker_spec.rb
spec/spec/runner/reporter_spec.rb
spec/spec/runner/resources/a_bar.rb
spec/spec/runner/resources/a_foo.rb
spec/spec/runner/resources/a_spec.rb
spec/spec/runner/spec.opts
spec/spec/runner/spec_drb.opts
spec/spec/runner/spec_parser/spec_parser_fixture.rb
spec/spec/runner/spec_parser_spec.rb
spec/spec/runner/spec_spaced.opts
spec/spec/runner_spec.rb
spec/spec/spec_classes.rb
spec/spec/story/builders.rb
spec/spec/story/extensions/main_spec.rb
spec/spec/story/extensions_spec.rb
spec/spec/story/given_scenario_spec.rb
spec/spec/story/runner/plain_text_story_runner_spec.rb
spec/spec/story/runner/scenario_collector_spec.rb
spec/spec/story/runner/scenario_runner_spec.rb
spec/spec/story/runner/story_mediator_spec.rb
spec/spec/story/runner/story_parser_spec.rb
spec/spec/story/runner/story_runner_spec.rb
spec/spec/story/runner_spec.rb
spec/spec/story/scenario_spec.rb
spec/spec/story/step_group_spec.rb
spec/spec/story/step_mother_spec.rb
spec/spec/story/step_spec.rb
spec/spec/story/story_helper.rb
spec/spec/story/story_spec.rb
spec/spec/story/world_spec.rb
spec/spec_helper.rb
stories/all.rb
stories/configuration/before_blocks.story
stories/configuration/stories.rb
stories/example_groups/autogenerated_docstrings
stories/example_groups/example_group_with_should_methods
stories/example_groups/nested_groups
stories/example_groups/output
stories/example_groups/stories.rb
stories/helper.rb
stories/interop/examples_and_tests_together
stories/interop/stories.rb
stories/interop/test_case_with_should_methods
stories/mock_framework_integration/stories.rb
stories/mock_framework_integration/use_flexmock.story
stories/pending_stories/README
stories/resources/helpers/cmdline.rb
stories/resources/helpers/story_helper.rb
stories/resources/matchers/smart_match.rb
stories/resources/spec/before_blocks_example.rb
stories/resources/spec/example_group_with_should_methods.rb
stories/resources/spec/simple_spec.rb
stories/resources/spec/spec_with_flexmock.rb
stories/resources/steps/running_rspec.rb
stories/resources/stories/failing_story.rb
stories/resources/test/spec_and_test_together.rb
stories/resources/test/test_case_with_should_methods.rb
stories/stories/multiline_steps.story
stories/stories/steps/multiline_steps.rb
stories/stories/stories.rb
story_server/prototype/javascripts/builder.js
story_server/prototype/javascripts/controls.js
story_server/prototype/javascripts/dragdrop.js
story_server/prototype/javascripts/effects.js
story_server/prototype/javascripts/prototype.js
story_server/prototype/javascripts/rspec.js
story_server/prototype/javascripts/scriptaculous.js
story_server/prototype/javascripts/slider.js
story_server/prototype/javascripts/sound.js
story_server/prototype/javascripts/unittest.js
story_server/prototype/lib/server.rb
story_server/prototype/stories.html
story_server/prototype/stylesheets/rspec.css
story_server/prototype/stylesheets/test.css

View file

@ -1,36 +0,0 @@
== RSpec
RSpec is a Behaviour Driven Development framework with tools to express User Stories
with Executable Scenarios and Executable Examples at the code level.
RSpec ships with several modules:
Spec::Story provides a framework for expressing User Stories and Scenarios
Spec::Example provides a framework for expressing Isolated Examples
Spec::Matchers provides Expression Matchers for use with Spec::Expectations
and Spec::Mocks.
Spec::Expectations supports setting expectations on your objects so you
can do things like:
result.should equal(expected_result)
Spec::Mocks supports creating Mock Objects, Stubs, and adding Mock/Stub
behaviour to your existing objects.
== Installation
The simplest approach is to install the gem (as root in some environments):
gem install -r rspec
== Building the RSpec gem
If you prefer to build the gem locally:
git clone git://github.com/dchelimsky/rspec.git
cd rspec
rake gem
gem install pkg/rspec-0.x.x.gem #as root

39
vendor/plugins/rspec/README.txt vendored Normal file
View file

@ -0,0 +1,39 @@
= RSpec
* http://rspec.info
* http://rspec.info/rdoc/
* http://rubyforge.org/projects/rspec
* http://github.com/dchelimsky/rspec/wikis
* mailto:rspec-devel@rubyforge.org
== DESCRIPTION:
RSpec is a Behaviour Driven Development framework with tools to express User
Stories with Executable Scenarios and Executable Examples at the code level.
== FEATURES:
* Spec::Story provides a framework for expressing User Stories and Scenarios
* Spec::Example provides a framework for expressing Isolated Examples
* Spec::Matchers provides Expression Matchers for use with Spec::Expectations and Spec::Mocks.
== SYNOPSIS:
Spec::Expectations supports setting expectations on your objects so you
can do things like:
result.should equal(expected_result)
Spec::Mocks supports creating Mock Objects, Stubs, and adding Mock/Stub
behaviour to your existing objects.
== INSTALL:
[sudo] gem install rspec
or
git clone git://github.com/dchelimsky/rspec.git
cd rspec
rake gem
rake install_gem

View file

@ -1,105 +1,61 @@
$:.unshift('lib')
require 'rubygems'
require 'rake/gempackagetask'
require 'rake/contrib/rubyforgepublisher'
require 'rake/clean'
require 'rake/rdoctask'
require 'rake/testtask'
require 'spec/version'
dir = File.dirname(__FILE__)
# -*- ruby -*-
# Some of the tasks are in separate files since they are also part of the website documentation
$:.unshift(File.join(File.dirname(__FILE__), 'lib'))
require 'rubygems'
require 'hoe'
require 'spec/version'
require 'spec/rake/spectask'
class Hoe
def extra_deps
@extra_deps.reject! { |x| Array(x).first == 'hoe' }
@extra_deps
end
end
Hoe.new('rspec', Spec::VERSION::STRING) do |p|
p.summary = Spec::VERSION::SUMMARY
p.url = 'http://rspec.info/'
p.description = "Behaviour Driven Development for Ruby."
p.rubyforge_name = 'rspec'
p.extra_dev_deps = ['diff-lcs',['spicycode-rcov','>= 0.8.1.3'],'syntax']
p.developer('RSpec Development Team', 'rspec-devel@rubyforge.org')
p.remote_rdoc_dir = "rspec/#{Spec::VERSION::STRING}"
end
['audit','test','test_deps','default','post_blog'].each do |task|
Rake.application.instance_variable_get('@tasks').delete(task)
end
task :verify_rcov => [:spec, :stories]
task :default => :verify_rcov
# # Some of the tasks are in separate files since they are also part of the website documentation
load File.dirname(__FILE__) + '/rake_tasks/examples.rake'
load File.dirname(__FILE__) + '/rake_tasks/examples_with_rcov.rake'
load File.dirname(__FILE__) + '/rake_tasks/failing_examples_with_html.rake'
load File.dirname(__FILE__) + '/rake_tasks/verify_rcov.rake'
PKG_NAME = "rspec"
PKG_VERSION = Spec::VERSION::STRING
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
PKG_FILES = FileList[
'[A-Z]*',
'lib/**/*.rb',
'spec/**/*',
'examples/**/*',
'failing_examples/**/*',
'plugins/**/*',
'stories/**/*',
'rake_tasks/**/*'
]
task :default => [:verify_rcov]
task :verify_rcov => [:spec, :stories]
desc "Run all specs"
Spec::Rake::SpecTask.new do |t|
t.spec_files = FileList['spec/**/*_spec.rb']
t.spec_opts = ['--options', 'spec/spec.opts']
unless ENV['NO_RCOV']
t.rcov = true
t.rcov_dir = '../doc/output/coverage'
t.rcov_opts = ['--exclude', 'lib/spec.rb,lib/spec/runner.rb,spec\/spec,bin\/spec,examples,\/var\/lib\/gems,\/Library\/Ruby,\.autotest']
t.rcov_dir = 'coverage'
t.rcov_opts = ['--exclude', "lib/spec.rb,lib/spec/runner.rb,spec\/spec,bin\/spec,examples,\/var\/lib\/gems,\/Library\/Ruby,\.autotest,#{ENV['GEM_HOME']}"]
end
end
desc "Run all stories"
task :stories do
html = 'story_server/prototype/rspec_stories.html'
ruby "stories/all.rb --colour --format plain --format html:#{html}"
unless IO.read(html) =~ /<span class="param">/m
raise 'highlighted parameters are broken in story HTML'
end
ruby "stories/all.rb --colour --format plain"
end
desc "Run all specs and store html output in doc/output/report.html"
Spec::Rake::SpecTask.new('spec_html') do |t|
t.spec_files = FileList['spec/**/*_spec.rb']
t.spec_opts = ['--format html:../../../../doc/output/report.html', '--format progress','--backtrace']
end
desc "Run all failing examples"
desc "Run failing examples (see failure output)"
Spec::Rake::SpecTask.new('failing_examples') do |t|
t.spec_files = FileList['failing_examples/**/*_spec.rb']
end
desc 'Generate RDoc'
rd = Rake::RDocTask.new do |rdoc|
rdoc.rdoc_dir = '../doc/output/rdoc'
rdoc.options << '--title' << 'RSpec' << '--line-numbers' << '--inline-source' << '--main' << 'README'
rdoc.rdoc_files.include('README', 'CHANGES', 'MIT-LICENSE', 'UPGRADE', 'lib/**/*.rb')
end
spec = Gem::Specification.new do |s|
s.name = PKG_NAME
s.version = PKG_VERSION
s.summary = Spec::VERSION::DESCRIPTION
s.description = <<-EOF
RSpec is a behaviour driven development (BDD) framework for Ruby. RSpec was
created in response to Dave Astels' article _A New Look at Test Driven Development_
which can be read at: http://daveastels.com/index.php?p=5 RSpec is intended to
provide the features discussed in Dave's article.
EOF
s.files = PKG_FILES.to_a
s.require_path = 'lib'
s.has_rdoc = true
s.rdoc_options = rd.options
s.extra_rdoc_files = rd.rdoc_files.reject { |fn| fn =~ /\.rb$|^EXAMPLES.rd$/ }.to_a
s.bindir = 'bin'
s.executables = ['spec', 'spec_translator']
s.default_executable = 'spec'
s.author = "RSpec Development Team"
s.email = "rspec-devel@rubyforge.org"
s.homepage = "http://rspec.rubyforge.org"
s.platform = Gem::Platform::RUBY
s.rubyforge_project = "rspec"
end
Rake::GemPackageTask.new(spec) do |pkg|
pkg.need_zip = true
pkg.need_tar = true
t.spec_opts = ['--options', 'spec/spec.opts']
end
def egrep(pattern)
@ -121,7 +77,8 @@ task :todo do
egrep /(FIXME|TODO|TBD)/
end
task :release => [:verify_committed, :verify_user, :spec, :publish_packages, :tag, :publish_news]
desc "verify_committed, verify_rcov, post_news, release"
task :complete_release => [:verify_committed, :verify_rcov, :post_news, :release]
desc "Verifies that there is no uncommitted code"
task :verify_committed do
@ -130,133 +87,4 @@ task :verify_committed do
raise "\n!!! Do a git commit first !!!\n\n" if line =~ /^#\s*modified:/
end
end
end
desc "Creates a tag in svn"
task :tag do
# from = `svn info #{File.dirname(__FILE__)}`.match(/URL: (.*)\/rspec/n)[1]
# to = from.gsub(/trunk/, "tags/#{Spec::VERSION::TAG}")
# current = from.gsub(/trunk/, "tags/CURRENT")
#
# puts "Creating tag in SVN"
# tag_cmd = "svn cp #{from} #{to} -m \"Tag release #{Spec::VERSION::FULL_VERSION}\""
# `#{tag_cmd}` ; raise "ERROR: #{tag_cmd}" unless $? == 0
#
# puts "Removing CURRENT"
# remove_current_cmd = "svn rm #{current} -m \"Remove tags/CURRENT\""
# `#{remove_current_cmd}` ; raise "ERROR: #{remove_current_cmd}" unless $? == 0
#
# puts "Re-Creating CURRENT"
# create_current_cmd = "svn cp #{to} #{current} -m \"Copy #{Spec::VERSION::TAG} to tags/CURRENT\""
# `#{create_current_cmd}` ; "ERROR: #{create_current_cmd}" unless $? == 0
end
task :verify_user do
raise "RUBYFORGE_USER environment variable not set!" unless ENV['RUBYFORGE_USER']
end
desc "Upload Website to RubyForge"
task :publish_website => [:verify_user, :website] do
unless Spec::VERSION::RELEASE_CANDIDATE
publisher = Rake::SshDirPublisher.new(
"rspec-website@rubyforge.org",
"/var/www/gforge-projects/#{PKG_NAME}",
"../doc/output"
)
publisher.upload
else
puts "** Not publishing packages to RubyForge - this is a prerelease"
end
end
desc "Upload Website archive to RubyForge"
task :archive_website => [:verify_user, :website] do
publisher = Rake::SshDirPublisher.new(
"rspec-website@rubyforge.org",
"/var/www/gforge-projects/#{PKG_NAME}/#{Spec::VERSION::TAG}",
"../doc/output"
)
publisher.upload
end
desc "Package the Rails plugin"
task :package_rspec_on_rails do
mkdir 'pkg' rescue nil
rm_rf "pkg/rspec-rails-#{PKG_VERSION}" rescue nil
`git clone ../rspec-rails pkg/rspec-rails-#{PKG_VERSION}`
rm_rf "pkg/rspec-rails-#{PKG_VERSION}/.git"
Dir.chdir 'pkg' do
`tar cvzf rspec-rails-#{PKG_VERSION}.tgz rspec-rails-#{PKG_VERSION}`
end
end
task :pkg => :package_rspec_on_rails
desc "Package the RSpec.tmbundle"
task :package_tmbundle do
mkdir 'pkg' rescue nil
rm_rf "pkg/RSpec-#{PKG_VERSION}.tmbundle" rescue nil
`git clone ../../../../RSpec.tmbundle pkg/RSpec-#{PKG_VERSION}.tmbundle`
rm_rf "pkg/RSpec-#{PKG_VERSION}.tmbundle/.git"
Dir.chdir 'pkg' do
`tar cvzf RSpec-#{PKG_VERSION}.tmbundle.tgz RSpec-#{PKG_VERSION}.tmbundle`
end
end
task :pkg => :package_tmbundle
desc "Publish gem+tgz+zip on RubyForge. You must make sure lib/version.rb is aligned with the CHANGELOG file"
task :publish_packages => [:verify_user, :package, :pkg] do
release_files = FileList[
"pkg/#{PKG_FILE_NAME}.gem",
"pkg/#{PKG_FILE_NAME}.tgz",
"pkg/rspec-rails-#{PKG_VERSION}.tgz",
"pkg/#{PKG_FILE_NAME}.zip",
"pkg/RSpec-#{PKG_VERSION}.tmbundle.tgz"
]
unless Spec::VERSION::RELEASE_CANDIDATE
require 'meta_project'
require 'rake/contrib/xforge'
Rake::XForge::Release.new(MetaProject::Project::XForge::RubyForge.new(PKG_NAME)) do |xf|
# Never hardcode user name and password in the Rakefile!
xf.user_name = ENV['RUBYFORGE_USER']
xf.files = release_files.to_a
xf.release_name = "RSpec #{PKG_VERSION}"
end
else
puts "SINCE THIS IS A PRERELEASE, FILES ARE UPLOADED WITH SSH, NOT TO THE RUBYFORGE FILE SECTION"
puts "YOU MUST TYPE THE PASSWORD #{release_files.length} TIMES..."
host = "rspec-website@rubyforge.org"
remote_dir = "/var/www/gforge-projects/#{PKG_NAME}"
publisher = Rake::SshFilePublisher.new(
host,
remote_dir,
File.dirname(__FILE__),
*release_files
)
publisher.upload
puts "UPLADED THE FOLLOWING FILES:"
release_files.each do |file|
name = file.match(/pkg\/(.*)/)[1]
puts "* http://rspec.rubyforge.org/#{name}"
end
puts "They are not linked to anywhere, so don't forget to tell people!"
end
end
desc "Publish news on RubyForge"
task :publish_news => [:verify_user] do
unless Spec::VERSION::RELEASE_CANDIDATE
require 'meta_project'
require 'rake/contrib/xforge'
Rake::XForge::NewsPublisher.new(MetaProject::Project::XForge::RubyForge.new(PKG_NAME)) do |news|
# Never hardcode user name and password in the Rakefile!
news.user_name = ENV['RUBYFORGE_USER']
end
else
puts "** Not publishing news to RubyForge - this is a prerelease"
end
end

View file

@ -1 +0,0 @@

10
vendor/plugins/rspec/TODO.txt vendored Normal file
View file

@ -0,0 +1,10 @@
== Future
* do SOMETHING with the website
* extract spec/story to rspec-stories (new gem)
* remove the ruby engine adapter unless Rubinius team plans to use it
* rename top level namespace to Rspec and commands to 'rspec' and 'autorspec'
* continue to support Spec 'spec' and 'autospec' as aliases for a reasonable time
* separate the underlying framework from the DSL
* be able to do everything with classes and methods
* tweak raise_error rdoc to show only one arg

View file

@ -1,7 +0,0 @@
== Spec::Rails
script/generate rspec
Or modify spec_helper.rb based on the template, which can be found at:
vendor/plugins/rspec_on_rails/generators/rspec/templates/spec_helper.rb

4
vendor/plugins/rspec/bin/autospec vendored Executable file
View file

@ -0,0 +1,4 @@
#!/usr/bin/env ruby
ENV['RSPEC'] = 'true' # allows autotest to discover rspec
ENV['AUTOTEST'] = 'true' # allows autotest to run w/ color on linux
system (RUBY_PLATFORM =~ /mswin|mingw/ ? 'autotest.bat' : 'autotest'), *ARGV

View file

@ -1,4 +1,4 @@
#!/usr/bin/env ruby
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
require 'spec'
exit ::Spec::Runner::CommandLine.run(rspec_options)
exit ::Spec::Runner::CommandLine.run

View file

@ -1,8 +0,0 @@
#!/usr/bin/env ruby
raise "\n\nUsage: spec_translator from_dir to_dir\n\n" if ARGV.size != 2
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
require 'spec/translator'
t = ::Spec::Translator.new
from = ARGV[0]
to = ARGV[1]
t.translate(from, to)

View file

@ -5,15 +5,15 @@ require File.dirname(__FILE__) + '/spec_helper'
describe "Examples with no descriptions" do
# description is auto-generated as "should equal(5)" based on the last #should
it do
specify do
3.should equal(3)
5.should equal(5)
end
it { 3.should be < 5 }
specify { 3.should be < 5 }
it { ["a"].should include("a") }
specify { ["a"].should include("a") }
it { [1,2,3].should respond_to(:size) }
specify { [1,2,3].should respond_to(:size) }
end

View file

@ -0,0 +1,33 @@
require File.dirname(__FILE__) + '/spec_helper'
class MessageAppender
def initialize(appendage)
@appendage = appendage
end
def append_to(message)
if_told_to_yield do
message << @appendage
end
end
end
describe "a message expectation yielding to a block" do
it "should yield if told to" do
appender = MessageAppender.new("appended to")
appender.should_receive(:if_told_to_yield).and_yield
message = ""
appender.append_to(message)
message.should == "appended to"
end
it "should not yield if not told to" do
appender = MessageAppender.new("appended to")
appender.should_receive(:if_told_to_yield)
message = ""
appender.append_to(message)
message.should == ""
end
end

View file

@ -1,21 +1,21 @@
Story: cells with less than two neighbours die
As a game producer
I want cells with less than two neighbours to die
So that I can illustrate how the game works to people with money
Scenario: cells with zero or one neighbour die
Given the grid looks like
........
.XX.XX..
.XX.....
....X...
........
When the next step occurs
Then the grid should look like
........
.XX.....
.XX.....
........
........
Story: cells with less than two neighbours die
As a game producer
I want cells with less than two neighbours to die
So that I can illustrate how the game works to people with money
Scenario: cells with zero or one neighbour die
Given the grid looks like
........
.XX.XX..
.XX.....
....X...
........
When the next step occurs
Then the grid should look like
........
.XX.....
.XX.....
........
........

View file

@ -1,21 +1,21 @@
Story: cells with more than three neighbours die
As a game producer
I want cells with more than three neighbours to die
So that I can show the people with money how we are getting on
Scenario: blink
Given the grid looks like
.....
...XX
...XX
.XX..
.XX..
When the next step occurs
Then the grid should look like
.....
...XX
....X
.X...
.XX..
Story: cells with more than three neighbours die
As a game producer
I want cells with more than three neighbours to die
So that I can show the people with money how we are getting on
Scenario: blink
Given the grid looks like
.....
...XX
...XX
.XX..
.XX..
When the next step occurs
Then the grid should look like
.....
...XX
....X
.X...
.XX..

View file

@ -1,42 +1,42 @@
Story: Empty spaces with three neighbours create a cell
As a game producer
I want empty cells with three neighbours to die
So that I have a minimum feature set to ship
Scenario: the glider
Given the grid looks like
...X..
..X...
..XXX.
......
......
When the next step occurs
Then the grid should look like
......
..X.X.
..XX..
...X..
......
When the next step occurs
Then the grid should look like
......
..X...
..X.X.
..XX..
......
When the next step occurs
Then the grid should look like
......
...X..
.XX...
..XX..
......
When the next step occurs
Then the grid should look like
......
..X...
.X....
.XXX..
......
Story: Empty spaces with three neighbours create a cell
As a game producer
I want empty cells with three neighbours to die
So that I have a minimum feature set to ship
Scenario: the glider
Given the grid looks like
...X..
..X...
..XXX.
......
......
When the next step occurs
Then the grid should look like
......
..X.X.
..XX..
...X..
......
When the next step occurs
Then the grid should look like
......
..X...
..X.X.
..XX..
......
When the next step occurs
Then the grid should look like
......
...X..
.XX...
..XX..
......
When the next step occurs
Then the grid should look like
......
..X...
.X....
.XXX..
......

View file

@ -1,42 +1,42 @@
Story: I can create a cell
As a game producer
I want to create a cell
So that I can show the grid to people
Scenario: nothing to see here
Given a 3 x 3 game
Then the grid should look like
...
...
...
Scenario: all on its lonesome
Given a 3 x 3 game
When I create a cell at 1, 1
Then the grid should look like
...
.X.
...
Scenario: the grid has three cells
Given a 3 x 3 game
When I create a cell at 0, 0
and I create a cell at 0, 1
and I create a cell at 2, 2
Then the grid should look like
XX.
...
..X
Scenario: more cells more more
Given the grid has three cells
When I create a celll at 3, 1
Then the grid should look like
XX.
..X
..X
Story: I can create a cell
As a game producer
I want to create a cell
So that I can show the grid to people
Scenario: nothing to see here
Given a 3 x 3 game
Then the grid should look like
...
...
...
Scenario: all on its lonesome
Given a 3 x 3 game
When I create a cell at 1, 1
Then the grid should look like
...
.X.
...
Scenario: the grid has three cells
Given a 3 x 3 game
When I create a cell at 0, 0
and I create a cell at 0, 1
and I create a cell at 2, 2
Then the grid should look like
XX.
...
..X
Scenario: more cells more more
Given the grid has three cells
When I create a celll at 3, 1
Then the grid should look like
XX.
..X
..X

View file

@ -1,17 +1,17 @@
Story: I can kill a cell
As a game producer
I want to kill a cell
So that when I make a mistake I dont have to start again
Scenario: bang youre dead
Given the grid looks like
XX.
.X.
..X
When I destroy the cell at 0, 1
Then the grid should look like
X..
.X.
..X
Story: I can kill a cell
As a game producer
I want to kill a cell
So that when I make a mistake I dont have to start again
Scenario: bang youre dead
Given the grid looks like
XX.
.X.
..X
When I destroy the cell at 0, 1
Then the grid should look like
X..
.X.
..X

View file

@ -1,53 +1,53 @@
Story: The grid wraps
As a game player
I want the grid to wrap
So that untidy stuff at the edges is avoided
Scenario: crowded in the corners
Given the grid looks like
X.X
...
X.X
When the next step is taken
Then the grid should look like
X.X
...
X.X
Scenario: the glider returns
Given the glider
......
..X...
.X....
.XXX..
......
When the next step is taken
and the next step is taken
and the next step is taken
and the next step is taken
Then the grid should look like
......
......
.X....
X.....
XXX...
When the next step is taken
Then the grid should look like
.X....
......
......
X.X...
XX....
When the next step is taken
Then the grid should look like
XX....
......
......
X.....
X.X...
Story: The grid wraps
As a game player
I want the grid to wrap
So that untidy stuff at the edges is avoided
Scenario: crowded in the corners
Given the grid looks like
X.X
...
X.X
When the next step is taken
Then the grid should look like
X.X
...
X.X
Scenario: the glider returns
Given the glider
......
..X...
.X....
.XXX..
......
When the next step is taken
and the next step is taken
and the next step is taken
and the next step is taken
Then the grid should look like
......
......
.X....
X.....
XXX...
When the next step is taken
Then the grid should look like
.X....
......
......
X.X...
XX....
When the next step is taken
Then the grid should look like
XX....
......
......
X.....
X.X...

View file

@ -1,3 +1,3 @@
Autotest.add_discovery do
"rspec" if File.exist?('spec')
"rspec" if File.directory?('spec') && ENV['RSPEC']
end

View file

@ -4,7 +4,7 @@ Autotest.add_hook :initialize do |at|
at.clear_mappings
# watch out: Ruby bug (1.8.6):
# %r(/) != /\//
at.add_mapping(%r%^spec/.*\.rb$%) { |filename, _|
at.add_mapping(%r%^spec/.*_spec.rb$%) { |filename, _|
filename
}
at.add_mapping(%r%^lib/(.*)\.rb$%) { |_, m|
@ -36,37 +36,11 @@ class Autotest::Rspec < Autotest
end
def make_test_cmd(files_to_test)
return "#{ruby} -S #{spec_command} #{add_options_if_present} #{files_to_test.keys.flatten.join(' ')}"
return '' if files_to_test.empty?
return "#{ruby} -S #{files_to_test.keys.flatten.join(' ')} #{add_options_if_present}"
end
def add_options_if_present # :nodoc:
File.exist?("spec/spec.opts") ? "-O spec/spec.opts " : ""
end
# Finds the proper spec command to use. Precendence is set in the
# lazily-evaluated method spec_commands. Alias + Override that in
# ~/.autotest to provide a different spec command then the default
# paths provided.
def spec_command(separator=File::ALT_SEPARATOR)
unless defined? @spec_command then
@spec_command = spec_commands.find { |cmd| File.exists? cmd }
raise RspecCommandError, "No spec command could be found!" unless @spec_command
@spec_command.gsub! File::SEPARATOR, separator if separator
end
@spec_command
end
# Autotest will look for spec commands in the following
# locations, in this order:
#
# * bin/spec
# * default spec bin/loader installed in Rubygems
def spec_commands
[
File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'bin', 'spec')),
File.join(Config::CONFIG['bindir'], 'spec')
]
end
end

View file

@ -1,10 +1,10 @@
require 'spec/version'
require 'spec/matchers'
require 'spec/expectations'
require 'spec/example'
require 'spec/extensions'
require 'spec/runner'
require 'spec/adapters'
require 'spec/version'
if Object.const_defined?(:Test)
require 'spec/interop/test'
@ -13,19 +13,20 @@ end
module Spec
class << self
def run?
@run || rspec_options.examples_run?
Runner.options.examples_run?
end
def run
return true if run?
result = rspec_options.run_examples
@run = true
result
Runner.options.run_examples
end
attr_writer :run
def exit?
!Object.const_defined?(:Test) || Test::Unit.run?
end
def spec_command?
$0.split('/').last == 'spec'
end
end
end
end

View file

@ -11,8 +11,8 @@ module Spec
}
def self.engine
if const_defined?(:RUBY_ENGINE)
return RUBY_ENGINE
if Object.const_defined?('RUBY_ENGINE')
return Object.const_get('RUBY_ENGINE')
else
return 'mri'
end

View file

@ -1,9 +1,30 @@
module Spec
module Example
class ExamplePendingError < StandardError
attr_reader :pending_caller
def initialize(message=nil)
super
@pending_caller = caller[2]
end
end
class NotYetImplementedError < ExamplePendingError
MESSAGE = "Not Yet Implemented"
RSPEC_ROOT_LIB = File.expand_path(File.dirname(__FILE__) + "/../..")
def initialize(backtrace)
super(MESSAGE)
@pending_caller = pending_caller_from(backtrace)
end
private
def pending_caller_from(backtrace)
backtrace.detect {|line| !line.include?(RSPEC_ROOT_LIB) }
end
end
class PendingExampleFixedError < StandardError
end
class PendingExampleFixedError < StandardError; end
end
end

View file

@ -6,9 +6,17 @@ module Spec
extend Spec::Example::ExampleGroupMethods
include Spec::Example::ExampleMethods
def initialize(defined_description, &implementation)
def initialize(defined_description, options={}, &implementation)
@_options = options
@_defined_description = defined_description
@_implementation = implementation
@_implementation = implementation || pending_implementation
end
private
def pending_implementation
error = NotYetImplementedError.new(caller)
lambda { raise(error) }
end
end
end

View file

@ -14,6 +14,7 @@ module Spec
end
attr_reader :description_text, :description_args, :description_options, :spec_path, :registration_binding_block
alias :options :description_options
def inherited(klass)
super
@ -38,24 +39,30 @@ module Spec
def describe(*args, &example_group_block)
args << {} unless Hash === args.last
if example_group_block
params = args.last
params[:spec_path] = eval("caller(0)[1]", example_group_block) unless params[:spec_path]
if params[:shared]
SharedExampleGroup.new(*args, &example_group_block)
options = args.last
options[:spec_path] = eval("caller(0)[1]", example_group_block) unless options[:spec_path]
if options[:shared]
create_shared_example_group(args, example_group_block)
else
self.subclass("Subclass") do
describe(*args)
module_eval(&example_group_block)
end
create_nested_example_group(args, example_group_block)
end
else
set_description(*args)
before_eval
self
end
end
alias :context :describe
def create_shared_example_group(args, example_group_block)
SharedExampleGroup.new(*args, &example_group_block)
end
def create_nested_example_group(args, example_group_block)
self.subclass("Subclass") do
describe(*args)
module_eval(&example_group_block)
end
end
# Use this to pull in examples from shared example groups.
# See Spec::Runner for information about shared example groups.
def it_should_behave_like(shared_example_group)
@ -103,21 +110,24 @@ module Spec
@predicate_matchers ||= {:an_instance_of => :is_a?}
end
# Creates an instance of Spec::Example::Example and adds
# it to a collection of examples of the current example group.
def it(description=nil, &implementation)
e = new(description, &implementation)
# Creates an instance of the current example group class and adds it to
# a collection of examples of the current example group.
def example(description=nil, options={}, &implementation)
e = new(description, options, &implementation)
example_objects << e
e
end
alias_method :specify, :it
alias_method :it, :example
alias_method :specify, :example
# Use this to temporarily disable an example.
def xit(description=nil, opts={}, &block)
def xexample(description=nil, opts={}, &block)
Kernel.warn("Example disabled: #{description}")
end
alias_method :xspecify, :xit
alias_method :xit, :xexample
alias_method :xspecify, :xexample
def run
examples = examples_to_run
@ -171,7 +181,7 @@ module Spec
def examples #:nodoc:
examples = example_objects.dup
add_method_examples(examples)
rspec_options.reverse ? examples.reverse : examples
Spec::Runner.options.reverse ? examples.reverse : examples
end
def number_of_examples #:nodoc:
@ -252,11 +262,11 @@ module Spec
def register(&registration_binding_block)
@registration_binding_block = registration_binding_block
rspec_options.add_example_group self
Spec::Runner.options.add_example_group self
end
def unregister #:nodoc:
rspec_options.remove_example_group self
Spec::Runner.options.remove_example_group self
end
def registration_backtrace
@ -278,8 +288,8 @@ module Spec
private
def dry_run(examples)
examples.each do |example|
rspec_options.reporter.example_started(example)
rspec_options.reporter.example_finished(example)
Spec::Runner.options.reporter.example_started(example)
Spec::Runner.options.reporter.example_finished(example)
end
return true
end
@ -302,7 +312,7 @@ module Spec
after_all_instance_variables = instance_variables
examples.each do |example_group_instance|
success &= example_group_instance.execute(rspec_options, instance_variables)
success &= example_group_instance.execute(Spec::Runner.options, instance_variables)
after_all_instance_variables = example_group_instance.instance_variable_hash
end
return [success, after_all_instance_variables]
@ -335,15 +345,15 @@ module Spec
end
def specified_examples
rspec_options.examples
Spec::Runner.options.examples
end
def reporter
rspec_options.reporter
Spec::Runner.options.reporter
end
def dry_run?
rspec_options.dry_run
Spec::Runner.options.dry_run
end
def example_objects
@ -398,7 +408,7 @@ module Spec
case scope
when :each; before_each_parts
when :all; before_all_parts
when :suite; rspec_options.before_suite_parts
when :suite; Spec::Runner.options.before_suite_parts
end
end
@ -406,13 +416,10 @@ module Spec
case scope
when :each; after_each_parts
when :all; after_all_parts
when :suite; rspec_options.after_suite_parts
when :suite; Spec::Runner.options.after_suite_parts
end
end
def before_eval
end
def add_method_examples(examples)
instance_methods.sort.each do |method_name|
if example_method?(method_name)

View file

@ -5,11 +5,6 @@ module Spec
extend ModuleReopeningFix
include ModuleInclusionWarnings
PENDING_EXAMPLE_BLOCK = lambda {
raise Spec::Example::ExamplePendingError.new("Not Yet Implemented")
}
def execute(options, instance_variables)
options.reporter.example_started(self)
set_instance_variables_from_hash(instance_variables)
@ -18,7 +13,7 @@ module Spec
Timeout.timeout(options.timeout) do
begin
before_example
run_with_description_capturing
eval_block
rescue Exception => e
execution_error ||= e
end
@ -63,7 +58,11 @@ module Spec
end
def description
@_defined_description || @_matcher_description || "NO NAME"
@_defined_description || ::Spec::Matchers.generated_description || "NO NAME"
end
def options
@_options
end
def __full_description
@ -79,13 +78,8 @@ module Spec
end
end
def run_with_description_capturing
begin
return instance_eval(&(@_implementation || PENDING_EXAMPLE_BLOCK))
ensure
@_matcher_description = Spec::Matchers.generated_description
Spec::Matchers.clear_generated_description
end
def eval_block
instance_eval(&@_implementation)
end
def implementation_backtrace
@ -109,4 +103,4 @@ module Spec
end
end
end
end
end

View file

@ -22,7 +22,8 @@ module Spec
end
end
def respond_to?(sym)
# NOTE - we don't need the second arg, but extenders do: http://www.ruby-doc.org/core/classes/Object.html#M000604
def respond_to?(sym, include_private_data=false)
MethodDispatcher.new(self.class.described_module).respond_to?(sym) ? true : super
end

View file

@ -27,7 +27,7 @@ module Spec
#
# NOTE that this does NOT support receiver.should != expected.
# Instead, use receiver.should_not == expected
def should(matcher=:use_operator_matcher, &block)
def should(matcher=nil, &block)
ExpectationMatcherHandler.handle_matcher(self, matcher, &block)
end
@ -50,7 +50,7 @@ module Spec
# => Passes unless (receiver =~ regexp)
#
# See Spec::Matchers for more information about matchers
def should_not(matcher=:use_operator_matcher, &block)
def should_not(matcher=nil, &block)
NegativeExpectationMatcherHandler.handle_matcher(self, matcher, &block)
end

View file

@ -2,38 +2,29 @@ module Spec
module Expectations
class InvalidMatcherError < ArgumentError; end
module MatcherHandlerHelper
def describe_matcher(matcher)
matcher.respond_to?(:description) ? matcher.description : "[#{matcher.class.name} does not provide a description]"
end
end
class ExpectationMatcherHandler
class << self
include MatcherHandlerHelper
def handle_matcher(actual, matcher, &block)
if :use_operator_matcher == matcher
return Spec::Matchers::PositiveOperatorMatcher.new(actual)
end
::Spec::Matchers.last_should = "should"
return Spec::Matchers::PositiveOperatorMatcher.new(actual) if matcher.nil?
unless matcher.respond_to?(:matches?)
raise InvalidMatcherError, "Expected a matcher, got #{matcher.inspect}."
end
match = matcher.matches?(actual, &block)
::Spec::Matchers.generated_description = "should #{describe_matcher(matcher)}"
::Spec::Matchers.last_matcher = matcher
Spec::Expectations.fail_with(matcher.failure_message) unless match
match
end
end
end
class NegativeExpectationMatcherHandler
class << self
include MatcherHandlerHelper
def handle_matcher(actual, matcher, &block)
if :use_operator_matcher == matcher
return Spec::Matchers::NegativeOperatorMatcher.new(actual)
end
::Spec::Matchers.last_should = "should not"
return Spec::Matchers::NegativeOperatorMatcher.new(actual) if matcher.nil?
unless matcher.respond_to?(:matches?)
raise InvalidMatcherError, "Expected a matcher, got #{matcher.inspect}."
@ -49,8 +40,9 @@ EOF
)
end
match = matcher.matches?(actual, &block)
::Spec::Matchers.generated_description = "should not #{describe_matcher(matcher)}"
::Spec::Matchers.last_matcher = matcher
Spec::Expectations.fail_with(matcher.negative_failure_message) if match
match
end
end
end

View file

@ -23,7 +23,7 @@ module Spec
raise ArgumentError if args.empty?
raise ArgumentError unless block
args << {} unless Hash === args.last
args.last[:spec_path] = caller(0)[1]
args.last[:spec_path] = File.expand_path(caller(0)[1])
Spec::Example::ExampleGroupFactory.create_example_group(*args, &block)
end
alias :context :describe
@ -80,23 +80,8 @@ module Spec
raise NameError.new(e.message + "\nThe first argument to share_as must be a legal name for a constant\n")
end
end
private
def rspec_options
$rspec_options ||= begin; \
parser = ::Spec::Runner::OptionParser.new(STDERR, STDOUT); \
parser.order!(ARGV); \
$rspec_options = parser.options; \
end
$rspec_options
end
def init_rspec_options(options)
$rspec_options = options if $rspec_options.nil?
end
end
end
end
include Spec::Extensions::Main
include Spec::Extensions::Main

View file

@ -43,9 +43,12 @@ module Test
end
end
def initialize(defined_description, &implementation)
def initialize(defined_description, options={}, &implementation)
@_defined_description = defined_description
@_implementation = implementation
# TODO - examples fail in rspec-rails if we remove "|| pending_implementation"
# - find a way to fail without it in rspec's code examples
@_implementation = implementation || pending_implementation
@_result = ::Test::Unit::TestResult.new
# @method_name is important to set here because it "complies" with Test::Unit's interface.
@ -56,6 +59,13 @@ module Test
def run(ignore_this_argument=nil)
super()
end
private
def pending_implementation
error = Spec::Example::NotYetImplementedError.new(caller)
lambda { raise(error) }
end
end
end
end

View file

@ -134,10 +134,16 @@ module Spec
#
module Matchers
module ModuleMethods
attr_accessor :generated_description
attr_accessor :last_matcher, :last_should
def clear_generated_description
self.generated_description = nil
self.last_matcher = nil
self.last_should = nil
end
def generated_description
last_should.nil? ? nil :
"#{last_should} #{last_matcher.respond_to?(:description) ? last_matcher.description : 'NO NAME'}"
end
end

View file

@ -12,22 +12,19 @@ module Spec
@comparison = ""
end
def matches?(actual)
@actual = actual
def matches?(given)
@given = given
if handling_predicate?
begin
return @result = actual.__send__(predicate, *@args)
return @result = given.__send__(predicate, *@args)
rescue => predicate_error
# This clause should be empty, but rcov will not report it as covered
# unless something (anything) is executed within the clause
rcov_error_report = "http://eigenclass.org/hiki.rb?rcov-0.8.0"
end
# This supports should_exist > target.exists? in the old world.
# We should consider deprecating that ability as in the new world
# you can't write "should exist" unless you have your own custom matcher.
begin
return @result = actual.__send__(present_tense_predicate, *@args)
return @result = given.__send__(present_tense_predicate, *@args)
rescue
raise predicate_error
end
@ -37,12 +34,12 @@ module Spec
end
def failure_message
return "expected #{@comparison}#{expected}, got #{@actual.inspect}" unless handling_predicate?
return "expected #{@comparison}#{expected}, got #{@given.inspect}" unless handling_predicate?
return "expected #{predicate}#{args_to_s} to return true, got #{@result.inspect}"
end
def negative_failure_message
return "expected not #{expected}, got #{@actual.inspect}" unless handling_predicate?
return "expected not #{expected}, got #{@given.inspect}" unless handling_predicate?
return "expected #{predicate}#{args_to_s} to return false, got #{@result.inspect}"
end
@ -55,17 +52,17 @@ module Spec
end
def match_or_compare
return @actual ? true : false if @expected == :satisfy_if
return @actual == true if @expected == :true
return @actual == false if @expected == :false
return @actual.nil? if @expected == :nil
return @actual < @expected if @less_than
return @actual <= @expected if @less_than_or_equal
return @actual >= @expected if @greater_than_or_equal
return @actual > @expected if @greater_than
return @actual == @expected if @double_equal
return @actual === @expected if @triple_equal
return @actual.equal?(@expected)
return @given ? true : false if @expected == :satisfy_if
return @given == true if @expected == :true
return @given == false if @expected == :false
return @given.nil? if @expected == :nil
return @given < @expected if @less_than
return @given <= @expected if @less_than_or_equal
return @given >= @expected if @greater_than_or_equal
return @given > @expected if @greater_than
return @given == @expected if @double_equal
return @given === @expected if @triple_equal
return @given.equal?(@expected)
end
def ==(expected)
@ -192,7 +189,7 @@ module Spec
# should_not be_nil
# should_not be_arbitrary_predicate(*args)
#
# Given true, false, or nil, will pass if actual is
# Given true, false, or nil, will pass if given value is
# true, false or nil (respectively). Given no args means
# the caller should satisfy an if condition (to be or not to be).
#

View file

@ -7,13 +7,13 @@ module Spec
@delta = delta
end
def matches?(actual)
@actual = actual
(@actual - @expected).abs < @delta
def matches?(given)
@given = given
(@given - @expected).abs < @delta
end
def failure_message
"expected #{@expected} +/- (< #{@delta}), got #{@actual}"
"expected #{@expected} +/- (< #{@delta}), got #{@given}"
end
def description
@ -25,7 +25,7 @@ module Spec
# should be_close(expected, delta)
# should_not be_close(expected, delta)
#
# Passes if actual == expected +/- delta
# Passes if given == expected +/- delta
#
# == Example
#

View file

@ -4,60 +4,60 @@ module Spec
#Based on patch from Wilson Bilkovich
class Change #:nodoc:
def initialize(receiver=nil, message=nil, &block)
@receiver = receiver
@message = message
@block = block
@message = message || "result"
@value_proc = block || lambda {
receiver.__send__(message)
}
end
def matches?(target, &block)
if block
raise MatcherError.new(<<-EOF
block passed to should or should_not change must use {} instead of do/end
EOF
)
end
@target = target
execute_change
return false if @from && (@from != @before)
return false if @to && (@to != @after)
def matches?(event_proc)
raise_block_syntax_error if block_given?
@before = evaluate_value_proc
event_proc.call
@after = evaluate_value_proc
return false if @from unless @from == @before
return false if @to unless @to == @after
return (@before + @amount == @after) if @amount
return ((@after - @before) >= @minimum) if @minimum
return ((@after - @before) <= @maximum) if @maximum
return @before != @after
end
def execute_change
@before = @block.nil? ? @receiver.send(@message) : @block.call
@target.call
@after = @block.nil? ? @receiver.send(@message) : @block.call
def raise_block_syntax_error
raise MatcherError.new(<<-MESSAGE
block passed to should or should_not change must use {} instead of do/end
MESSAGE
)
end
def evaluate_value_proc
@value_proc.call
end
def failure_message
if @to
"#{result} should have been changed to #{@to.inspect}, but is now #{@after.inspect}"
"#{@message} should have been changed to #{@to.inspect}, but is now #{@after.inspect}"
elsif @from
"#{result} should have initially been #{@from.inspect}, but was #{@before.inspect}"
"#{@message} should have initially been #{@from.inspect}, but was #{@before.inspect}"
elsif @amount
"#{result} should have been changed by #{@amount.inspect}, but was changed by #{actual_delta.inspect}"
"#{@message} should have been changed by #{@amount.inspect}, but was changed by #{actual_delta.inspect}"
elsif @minimum
"#{result} should have been changed by at least #{@minimum.inspect}, but was changed by #{actual_delta.inspect}"
"#{@message} should have been changed by at least #{@minimum.inspect}, but was changed by #{actual_delta.inspect}"
elsif @maximum
"#{result} should have been changed by at most #{@maximum.inspect}, but was changed by #{actual_delta.inspect}"
"#{@message} should have been changed by at most #{@maximum.inspect}, but was changed by #{actual_delta.inspect}"
else
"#{result} should have changed, but is still #{@before.inspect}"
"#{@message} should have changed, but is still #{@before.inspect}"
end
end
def result
@message || "result"
end
def actual_delta
@after - @before
end
def negative_failure_message
"#{result} should not have changed, but did change from #{@before.inspect} to #{@after.inspect}"
"#{@message} should not have changed, but did change from #{@before.inspect} to #{@after.inspect}"
end
def by(amount)
@ -125,20 +125,24 @@ EOF
# employee.develop_great_new_social_networking_app
# }.should change(employee, :title).from("Mail Clerk").to("CEO")
#
# Evaluates +receiver.message+ or +block+ before and
# after it evaluates the c object (generated by the lambdas in the examples above).
# Evaluates <tt>receiver.message</tt> or <tt>block</tt> before and after
# it evaluates the c object (generated by the lambdas in the examples
# above).
#
# Then compares the values before and after the +receiver.message+ and
# evaluates the difference compared to the expected difference.
# Then compares the values before and after the <tt>receiver.message</tt>
# and evaluates the difference compared to the expected difference.
#
# == Warning
# +should_not+ +change+ only supports the form with no subsequent calls to
# +by+, +by_at_least+, +by_at_most+, +to+ or +from+.
# == WARNING
# <tt>should_not change</tt> only supports the form with no
# subsequent calls to <tt>by</tt>, <tt>by_at_least</tt>,
# <tt>by_at_most</tt>, <tt>to</tt> or <tt>from</tt>.
#
# blocks passed to +should+ +change+ and +should_not+ +change+
# must use the <tt>{}</tt> form (<tt>do/end</tt> is not supported)
def change(target=nil, message=nil, &block)
Matchers::Change.new(target, message, &block)
# blocks passed to <tt>should</tt> <tt>change</tt> and <tt>should_not</tt>
# <tt>change</tt> must use the <tt>{}</tt> form (<tt>do/end</tt> is not
# supported).
#
def change(receiver=nil, message=nil, &block)
Matchers::Change.new(receiver, message, &block)
end
end
end

View file

@ -6,17 +6,17 @@ module Spec
@expected = expected
end
def matches?(actual)
@actual = actual
@actual.eql?(@expected)
def matches?(given)
@given = given
@given.eql?(@expected)
end
def failure_message
return "expected #{@expected.inspect}, got #{@actual.inspect} (using .eql?)", @expected, @actual
return "expected #{@expected.inspect}, got #{@given.inspect} (using .eql?)", @expected, @given
end
def negative_failure_message
return "expected #{@actual.inspect} not to equal #{@expected.inspect} (using .eql?)", @expected, @actual
return "expected #{@given.inspect} not to equal #{@expected.inspect} (using .eql?)", @expected, @given
end
def description
@ -28,7 +28,7 @@ module Spec
# should eql(expected)
# should_not eql(expected)
#
# Passes if actual and expected are of equal value, but not necessarily the same object.
# Passes if given and expected are of equal value, but not necessarily the same object.
#
# See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more information about equality in Ruby.
#

View file

@ -6,17 +6,17 @@ module Spec
@expected = expected
end
def matches?(actual)
@actual = actual
@actual.equal?(@expected)
def matches?(given)
@given = given
@given.equal?(@expected)
end
def failure_message
return "expected #{@expected.inspect}, got #{@actual.inspect} (using .equal?)", @expected, @actual
return "expected #{@expected.inspect}, got #{@given.inspect} (using .equal?)", @expected, @given
end
def negative_failure_message
return "expected #{@actual.inspect} not to equal #{@expected.inspect} (using .equal?)", @expected, @actual
return "expected #{@given.inspect} not to equal #{@expected.inspect} (using .equal?)", @expected, @given
end
def description
@ -28,7 +28,7 @@ module Spec
# should equal(expected)
# should_not equal(expected)
#
# Passes if actual and expected are the same object (object identity).
# Passes if given and expected are the same object (object identity).
#
# See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more information about equality in Ruby.
#

View file

@ -1,17 +1,22 @@
module Spec
module Matchers
class Exist
def matches? actual
@actual = actual
@actual.exist?
def matches?(given)
@given = given
@given.exist?
end
def failure_message
"expected #{@actual.inspect} to exist, but it doesn't."
"expected #{@given.inspect} to exist, but it doesn't."
end
def negative_failure_message
"expected #{@actual.inspect} to not exist, but it does."
"expected #{@given.inspect} to not exist, but it does."
end
end
# :call-seq:
# should exist
# should_not exist
#
# Passes if given.exist?
def exist; Exist.new; end
end
end

View file

@ -7,8 +7,8 @@ module Spec
@args = args
end
def matches?(target)
target.send(predicate, *@args)
def matches?(given)
given.__send__(predicate, *@args)
end
def failure_message

View file

@ -1,6 +1,5 @@
module Spec
module Matchers
class Have #:nodoc:
def initialize(expected, relativity=:exactly)
@expected = (expected == :no ? 0 : expected)
@ -15,34 +14,22 @@ module Spec
}
end
def method_missing(sym, *args, &block)
@collection_name = sym
if defined?(ActiveSupport::Inflector)
@plural_collection_name = ActiveSupport::Inflector.pluralize(sym.to_s)
elsif Object.const_defined?(:Inflector)
@plural_collection_name = Inflector.pluralize(sym.to_s)
end
@args = args
@block = block
self
end
def matches?(collection_owner)
if collection_owner.respond_to?(@collection_name)
collection = collection_owner.send(@collection_name, *@args, &@block)
collection = collection_owner.__send__(@collection_name, *@args, &@block)
elsif (@plural_collection_name && collection_owner.respond_to?(@plural_collection_name))
collection = collection_owner.send(@plural_collection_name, *@args, &@block)
collection = collection_owner.__send__(@plural_collection_name, *@args, &@block)
elsif (collection_owner.respond_to?(:length) || collection_owner.respond_to?(:size))
collection = collection_owner
else
collection_owner.send(@collection_name, *@args, &@block)
collection_owner.__send__(@collection_name, *@args, &@block)
end
@actual = collection.size if collection.respond_to?(:size)
@actual = collection.length if collection.respond_to?(:length)
raise not_a_collection if @actual.nil?
return @actual >= @expected if @relativity == :at_least
return @actual <= @expected if @relativity == :at_most
return @actual == @expected
@given = collection.size if collection.respond_to?(:size)
@given = collection.length if collection.respond_to?(:length)
raise not_a_collection if @given.nil?
return @given >= @expected if @relativity == :at_least
return @given <= @expected if @relativity == :at_most
return @given == @expected
end
def not_a_collection
@ -50,12 +37,12 @@ module Spec
end
def failure_message
"expected #{relative_expectation} #{@collection_name}, got #{@actual}"
"expected #{relative_expectation} #{@collection_name}, got #{@given}"
end
def negative_failure_message
if @relativity == :exactly
return "expected target not to have #{@expected} #{@collection_name}, got #{@actual}"
return "expected target not to have #{@expected} #{@collection_name}, got #{@given}"
elsif @relativity == :at_most
return <<-EOF
Isn't life confusing enough?
@ -79,8 +66,22 @@ EOF
"have #{relative_expectation} #{@collection_name}"
end
def respond_to?(sym)
@expected.respond_to?(sym) || super
end
private
def method_missing(sym, *args, &block)
@collection_name = sym
if inflector = (defined?(ActiveSupport::Inflector) ? ActiveSupport::Inflector : (defined?(Inflector) ? Inflector : nil))
@plural_collection_name = inflector.pluralize(sym.to_s)
end
@args = args
@block = block
self
end
def relative_expectation
"#{relativities[@relativity]}#{@expected}"
end

View file

@ -7,10 +7,10 @@ module Spec
@expecteds = expecteds
end
def matches?(actual)
@actual = actual
def matches?(given)
@given = given
@expecteds.each do |expected|
return false unless actual.include?(expected)
return false unless given.include?(expected)
end
true
end
@ -29,7 +29,7 @@ module Spec
private
def _message(maybe_not="")
"expected #{@actual.inspect} #{maybe_not}to include #{_pretty_print(@expecteds)}"
"expected #{@given.inspect} #{maybe_not}to include #{_pretty_print(@expecteds)}"
end
def _pretty_print(array)
@ -51,7 +51,7 @@ module Spec
# should include(expected)
# should_not include(expected)
#
# Passes if actual includes expected. This works for
# Passes if given includes expected. This works for
# collections and Strings. You can also pass in multiple args
# and it will only pass if all args are found in collection.
#

View file

@ -2,26 +2,26 @@ module Spec
module Matchers
class Match #:nodoc:
def initialize(expected)
@expected = expected
def initialize(regexp)
@regexp = regexp
end
def matches?(actual)
@actual = actual
return true if actual =~ @expected
def matches?(given)
@given = given
return true if given =~ @regexp
return false
end
def failure_message
return "expected #{@actual.inspect} to match #{@expected.inspect}", @expected, @actual
return "expected #{@given.inspect} to match #{@regexp.inspect}", @regexp, @given
end
def negative_failure_message
return "expected #{@actual.inspect} not to match #{@expected.inspect}", @expected, @actual
return "expected #{@given.inspect} not to match #{@regexp.inspect}", @regexp, @given
end
def description
"match #{@expected.inspect}"
"match #{@regexp.inspect}"
end
end
@ -29,7 +29,7 @@ module Spec
# should match(regexp)
# should_not match(regexp)
#
# Given a Regexp, passes if actual =~ regexp
# Given a Regexp, passes if given =~ regexp
#
# == Examples
#

View file

@ -3,68 +3,74 @@ module Spec
class BaseOperatorMatcher
attr_reader :generated_description
def initialize(target)
@target = target
def initialize(given)
@given = given
end
def ==(expected)
@expected = expected
__delegate_method_missing_to_target("==", expected)
__delegate_method_missing_to_given("==", expected)
end
def ===(expected)
@expected = expected
__delegate_method_missing_to_target("===", expected)
__delegate_method_missing_to_given("===", expected)
end
def =~(expected)
@expected = expected
__delegate_method_missing_to_target("=~", expected)
__delegate_method_missing_to_given("=~", expected)
end
def >(expected)
@expected = expected
__delegate_method_missing_to_target(">", expected)
__delegate_method_missing_to_given(">", expected)
end
def >=(expected)
@expected = expected
__delegate_method_missing_to_target(">=", expected)
__delegate_method_missing_to_given(">=", expected)
end
def <(expected)
@expected = expected
__delegate_method_missing_to_target("<", expected)
__delegate_method_missing_to_given("<", expected)
end
def <=(expected)
@expected = expected
__delegate_method_missing_to_target("<=", expected)
__delegate_method_missing_to_given("<=", expected)
end
def fail_with_message(message)
Spec::Expectations.fail_with(message, @expected, @target)
Spec::Expectations.fail_with(message, @expected, @given)
end
def description
"#{@operator} #{@expected.inspect}"
end
end
class PositiveOperatorMatcher < BaseOperatorMatcher #:nodoc:
def __delegate_method_missing_to_target(operator, expected)
::Spec::Matchers.generated_description = "should #{operator} #{expected.inspect}"
return if @target.send(operator, expected)
return fail_with_message("expected: #{expected.inspect},\n got: #{@target.inspect} (using #{operator})") if ['==','===', '=~'].include?(operator)
return fail_with_message("expected: #{operator} #{expected.inspect},\n got: #{operator.gsub(/./, ' ')} #{@target.inspect}")
def __delegate_method_missing_to_given(operator, expected)
@operator = operator
::Spec::Matchers.last_matcher = self
return true if @given.__send__(operator, expected)
return fail_with_message("expected: #{expected.inspect},\n got: #{@given.inspect} (using #{operator})") if ['==','===', '=~'].include?(operator)
return fail_with_message("expected: #{operator} #{expected.inspect},\n got: #{operator.gsub(/./, ' ')} #{@given.inspect}")
end
end
class NegativeOperatorMatcher < BaseOperatorMatcher #:nodoc:
def __delegate_method_missing_to_target(operator, expected)
::Spec::Matchers.generated_description = "should not #{operator} #{expected.inspect}"
return unless @target.send(operator, expected)
return fail_with_message("expected not: #{operator} #{expected.inspect},\n got: #{operator.gsub(/./, ' ')} #{@target.inspect}")
def __delegate_method_missing_to_given(operator, expected)
@operator = operator
::Spec::Matchers.last_matcher = self
return true unless @given.__send__(operator, expected)
return fail_with_message("expected not: #{operator} #{expected.inspect},\n got: #{operator.gsub(/./, ' ')} #{@given.inspect}")
end
end

View file

@ -1,27 +1,27 @@
module Spec
module Matchers
class RaiseError #:nodoc:
def initialize(error_or_message=Exception, message=nil, &block)
def initialize(expected_error_or_message=Exception, expected_message=nil, &block)
@block = block
case error_or_message
case expected_error_or_message
when String, Regexp
@expected_error, @expected_message = Exception, error_or_message
@expected_error, @expected_message = Exception, expected_error_or_message
else
@expected_error, @expected_message = error_or_message, message
@expected_error, @expected_message = expected_error_or_message, expected_message
end
end
def matches?(proc)
def matches?(given_proc)
@raised_expected_error = false
@with_expected_message = false
@eval_block = false
@eval_block_passed = false
begin
proc.call
rescue @expected_error => @actual_error
given_proc.call
rescue @expected_error => @given_error
@raised_expected_error = true
@with_expected_message = verify_message
rescue Exception => @actual_error
rescue Exception => @given_error
# This clause should be empty, but rcov will not report it as covered
# unless something (anything) is executed within the clause
rcov_error_report = "http://eigenclass.org/hiki.rb?rcov-0.8.0"
@ -37,10 +37,10 @@ module Spec
def eval_block
@eval_block = true
begin
@block[@actual_error]
@block[@given_error]
@eval_block_passed = true
rescue Exception => err
@actual_error = err
@given_error = err
end
end
@ -49,22 +49,22 @@ module Spec
when nil
return true
when Regexp
return @expected_message =~ @actual_error.message
return @expected_message =~ @given_error.message
else
return @expected_message == @actual_error.message
return @expected_message == @given_error.message
end
end
def failure_message
if @eval_block
return @actual_error.message
return @given_error.message
else
return "expected #{expected_error}#{actual_error}"
return "expected #{expected_error}#{given_error}"
end
end
def negative_failure_message
"expected no #{expected_error}#{actual_error}"
"expected no #{expected_error}#{given_error}"
end
def description
@ -83,8 +83,8 @@ module Spec
end
end
def actual_error
@actual_error.nil? ? " but nothing was raised" : ", got #{@actual_error.inspect}"
def given_error
@given_error.nil? ? " but nothing was raised" : ", got #{@given_error.inspect}"
end
def negative_expectation?

View file

@ -7,9 +7,10 @@ module Spec
@names_not_responded_to = []
end
def matches?(target)
def matches?(given)
@given = given
@names.each do |name|
unless target.respond_to?(name)
unless given.respond_to?(name)
@names_not_responded_to << name
end
end
@ -17,11 +18,11 @@ module Spec
end
def failure_message
"expected target to respond to #{@names_not_responded_to.collect {|name| name.inspect }.join(', ')}"
"expected #{@given.inspect} to respond to #{@names_not_responded_to.collect {|name| name.inspect }.join(', ')}"
end
def negative_failure_message
"expected target not to respond to #{@names.collect {|name| name.inspect }.join(', ')}"
"expected #{@given.inspect} not to respond to #{@names.collect {|name| name.inspect }.join(', ')}"
end
def description

View file

@ -6,18 +6,18 @@ module Spec
@block = block
end
def matches?(actual, &block)
def matches?(given, &block)
@block = block if block
@actual = actual
@block.call(actual)
@given = given
@block.call(given)
end
def failure_message
"expected #{@actual} to satisfy block"
"expected #{@given} to satisfy block"
end
def negative_failure_message
"expected #{@actual} not to satisfy block"
"expected #{@given} not to satisfy block"
end
end

View file

@ -1,29 +1,132 @@
module Spec
module Matchers
class SimpleMatcher
attr_reader :description
attr_writer :failure_message, :negative_failure_message, :description
def initialize(description, &match_block)
@description = description
@match_block = match_block
end
def matches?(actual)
@actual = actual
return @match_block.call(@actual)
def matches?(given)
@given = given
case @match_block.arity
when 2
@match_block.call(@given, self)
else
@match_block.call(@given)
end
end
def description
@description || explanation
end
def failure_message()
return %[expected #{@description.inspect} but got #{@actual.inspect}]
def failure_message
@failure_message || (@description.nil? ? explanation : %[expected #{@description.inspect} but got #{@given.inspect}])
end
def negative_failure_message()
return %[expected not to get #{@description.inspect}, but got #{@actual.inspect}]
def negative_failure_message
@negative_failure_message || (@description.nil? ? explanation : %[expected not to get #{@description.inspect}, but got #{@given.inspect}])
end
def explanation
"No description provided. See RDoc for simple_matcher()"
end
end
def simple_matcher(message, &match_block)
SimpleMatcher.new(message, &match_block)
# simple_matcher makes it easy for you to create your own custom matchers
# in just a few lines of code when you don't need all the power of a
# completely custom matcher object.
#
# The <tt>description</tt> argument will appear as part of any failure
# message, and is also the source for auto-generated descriptions.
#
# The <tt>match_block</tt> can have an arity of 1 or 2. The first block
# argument will be the given value. The second, if the block accepts it
# will be the matcher itself, giving you access to set custom failure
# messages in favor of the defaults.
#
# The <tt>match_block</tt> should return a boolean: <tt>true</tt>
# indicates a match, which will pass if you use <tt>should</tt> and fail
# if you use <tt>should_not</tt>. false (or nil) indicates no match,
# which will do the reverse: fail if you use <tt>should</tt> and pass if
# you use <tt>should_not</tt>.
#
# An error in the <tt>match_block</tt> will bubble up, resulting in a
# failure.
#
# == Example with default messages
#
# def be_even
# simple_matcher("an even number") { |given| given % 2 == 0 }
# end
#
# describe 2 do
# it "should be even" do
# 2.should be_even
# end
# end
#
# Given an odd number, this example would produce an error message stating:
# expected "an even number", got 3.
#
# Unfortunately, if you're a fan of auto-generated descriptions, this will
# produce "should an even number." Not the most desirable result. You can
# control that using custom messages:
#
# == Example with custom messages
#
# def rhyme_with(expected)
# simple_matcher("rhyme with #{expected.inspect}") do |given, matcher|
# matcher.failure_message = "expected #{given.inspect} to rhyme with #{expected.inspect}"
# matcher.negative_failure_message = "expected #{given.inspect} not to rhyme with #{expected.inspect}"
# given.rhymes_with? expected
# end
# end
#
# # OR
#
# def rhyme_with(expected)
# simple_matcher do |given, matcher|
# matcher.description = "rhyme with #{expected.inspect}"
# matcher.failure_message = "expected #{given.inspect} to rhyme with #{expected.inspect}"
# matcher.negative_failure_message = "expected #{given.inspect} not to rhyme with #{expected.inspect}"
# given.rhymes_with? expected
# end
# end
#
# describe "pecan" do
# it "should rhyme with 'be gone'" do
# nut = "pecan"
# nut.extend Rhymer
# nut.should rhyme_with("be gone")
# end
# end
#
# The resulting messages would be:
# description: rhyme with "be gone"
# failure_message: expected "pecan" to rhyme with "be gone"
# negative failure_message: expected "pecan" not to rhyme with "be gone"
#
# == Wrapped Expectations
#
# Because errors will bubble up, it is possible to wrap other expectations
# in a SimpleMatcher.
#
# def be_even
# simple_matcher("an even number") { |given| (given % 2).should == 0 }
# end
#
# BE VERY CAREFUL when you do this. Only use wrapped expectations for
# matchers that will always be used in only the positive
# (<tt>should</tt>) or negative (<tt>should_not</tt>), but not both.
# The reason is that is you wrap a <tt>should</tt> and call the wrapper
# with <tt>should_not</tt>, the correct result (the <tt>should</tt>
# failing), will fail when you want it to pass.
#
def simple_matcher(description=nil, &match_block)
SimpleMatcher.new(description, &match_block)
end
end
end

View file

@ -7,9 +7,9 @@ module Spec
@actual = nil
end
def matches?(proc)
def matches?(given_proc)
begin
proc.call
given_proc.call
rescue NameError => e
raise e unless e.message =~ /uncaught throw/
@actual = e.name.to_sym
@ -56,7 +56,7 @@ module Spec
# should_not throw_symbol()
# should_not throw_symbol(:sym)
#
# Given a Symbol argument, matches if a proc throws the specified Symbol.
# Given a Symbol argument, matches if the given proc throws the specified Symbol.
#
# Given no argument, matches if a proc throws any Symbol.
#

View file

@ -1,16 +1,5 @@
require 'spec/mocks/framework'
require 'spec/mocks/methods'
require 'spec/mocks/argument_constraint_matchers'
require 'spec/mocks/spec_methods'
require 'spec/mocks/proxy'
require 'spec/mocks/mock'
require 'spec/mocks/argument_expectation'
require 'spec/mocks/message_expectation'
require 'spec/mocks/order_group'
require 'spec/mocks/errors'
require 'spec/mocks/error_generator'
require 'spec/mocks/extensions/object'
require 'spec/mocks/space'
module Spec
# == Mocks and Stubs

View file

@ -1,31 +0,0 @@
module Spec
module Mocks
module ArgumentConstraintMatchers
# Shortcut for creating an instance of Spec::Mocks::DuckTypeArgConstraint
def duck_type(*args)
DuckTypeArgConstraint.new(*args)
end
def any_args
AnyArgsConstraint.new
end
def anything
AnyArgConstraint.new(nil)
end
def boolean
BooleanArgConstraint.new(nil)
end
def hash_including(expected={})
HashIncludingConstraint.new(expected)
end
def no_args
NoArgsConstraint.new
end
end
end
end

View file

@ -0,0 +1,165 @@
module Spec
module Mocks
# ArgumentConstraints are messages that you can include in message
# expectations to match arguments against a broader check than simple
# equality.
#
# With the exception of any_args() and no_args(), the constraints
# are all positional - they match against the arg in the given position.
module ArgumentConstraints
class AnyArgsConstraint
def description
"any args"
end
end
class AnyArgConstraint
def initialize(ignore)
end
def ==(other)
true
end
end
class NoArgsConstraint
def description
"no args"
end
def ==(args)
args == []
end
end
class RegexpConstraint
def initialize(regexp)
@regexp = regexp
end
def ==(value)
return value =~ @regexp unless value.is_a?(Regexp)
value == @regexp
end
end
class BooleanConstraint
def initialize(ignore)
end
def ==(value)
TrueClass === value || FalseClass === value
end
end
class HashIncludingConstraint
def initialize(expected)
@expected = expected
end
def ==(actual)
@expected.each do | key, value |
return false unless actual.has_key?(key) && value == actual[key]
end
true
rescue NoMethodError => ex
return false
end
def description
"hash_including(#{@expected.inspect.sub(/^\{/,"").sub(/\}$/,"")})"
end
end
class DuckTypeConstraint
def initialize(*methods_to_respond_to)
@methods_to_respond_to = methods_to_respond_to
end
def ==(value)
@methods_to_respond_to.all? { |sym| value.respond_to?(sym) }
end
end
class MatcherConstraint
def initialize(matcher)
@matcher = matcher
end
def ==(value)
@matcher.matches?(value)
end
end
class EqualityProxy
def initialize(given)
@given = given
end
def ==(expected)
@given == expected
end
end
# :call-seq:
# object.should_receive(:message).with(any_args())
#
# Passes if object receives :message with any args at all. This is
# really a more explicit variation of object.should_receive(:message)
def any_args
AnyArgsConstraint.new
end
# :call-seq:
# object.should_receive(:message).with(anything())
#
# Passes as long as there is an argument.
def anything
AnyArgConstraint.new(nil)
end
# :call-seq:
# object.should_receive(:message).with(no_args)
#
# Passes if no arguments are passed along with the message
def no_args
NoArgsConstraint.new
end
# :call-seq:
# object.should_receive(:message).with(duck_type(:hello))
# object.should_receive(:message).with(duck_type(:hello, :goodbye))
#
# Passes if the argument responds to the specified messages.
#
# == Examples
#
# array = []
# display = mock('display')
# display.should_receive(:present_names).with(duck_type(:length, :each))
# => passes
def duck_type(*args)
DuckTypeConstraint.new(*args)
end
# :call-seq:
# object.should_receive(:message).with(boolean())
#
# Passes if the argument is boolean.
def boolean
BooleanConstraint.new(nil)
end
# :call-seq:
# object.should_receive(:message).with(hash_including(:this => that))
#
# Passes if the argument is a hash that includes the specified key/value
# pairs. If the hash includes other keys, it will still pass.
def hash_including(expected={})
HashIncludingConstraint.new(expected)
end
end
end
end

View file

@ -1,215 +1,48 @@
module Spec
module Mocks
class MatcherConstraint
def initialize(matcher)
@matcher = matcher
end
def matches?(value)
@matcher.matches?(value)
end
end
class LiteralArgConstraint
def initialize(literal)
@literal_value = literal
end
def matches?(value)
@literal_value == value
end
end
class RegexpArgConstraint
def initialize(regexp)
@regexp = regexp
end
def matches?(value)
return value =~ @regexp unless value.is_a?(Regexp)
value == @regexp
end
end
class AnyArgConstraint
def initialize(ignore)
end
def ==(other)
true
end
# TODO - need this?
def matches?(value)
true
end
end
class AnyArgsConstraint
def description
"any args"
end
end
class NoArgsConstraint
def description
"no args"
end
def ==(args)
args == []
end
end
class NumericArgConstraint
def initialize(ignore)
end
def matches?(value)
value.is_a?(Numeric)
end
end
class BooleanArgConstraint
def initialize(ignore)
end
def ==(value)
matches?(value)
end
def matches?(value)
return true if value.is_a?(TrueClass)
return true if value.is_a?(FalseClass)
false
end
end
class StringArgConstraint
def initialize(ignore)
end
def matches?(value)
value.is_a?(String)
end
end
class DuckTypeArgConstraint
def initialize(*methods_to_respond_to)
@methods_to_respond_to = methods_to_respond_to
end
def matches?(value)
@methods_to_respond_to.all? { |sym| value.respond_to?(sym) }
end
def description
"duck_type"
end
end
class HashIncludingConstraint
def initialize(expected)
@expected = expected
end
def ==(actual)
@expected.each do | key, value |
# check key for case that value evaluates to nil
return false unless actual.has_key?(key) && actual[key] == value
end
true
rescue NoMethodError => ex
return false
end
def matches?(value)
self == value
end
def description
"hash_including(#{@expected.inspect.sub(/^\{/,"").sub(/\}$/,"")})"
end
end
class ArgumentExpectation
attr_reader :args
@@constraint_classes = Hash.new { |hash, key| LiteralArgConstraint}
@@constraint_classes[:anything] = AnyArgConstraint
@@constraint_classes[:numeric] = NumericArgConstraint
@@constraint_classes[:boolean] = BooleanArgConstraint
@@constraint_classes[:string] = StringArgConstraint
def initialize(args, &block)
@args = args
@constraints_block = block
if [:any_args] == args
@expected_params = nil
warn_deprecated(:any_args.inspect, "any_args()")
elsif args.length == 1 && args[0].is_a?(AnyArgsConstraint) then @expected_params = nil
elsif [:no_args] == args
@expected_params = []
warn_deprecated(:no_args.inspect, "no_args()")
elsif args.length == 1 && args[0].is_a?(NoArgsConstraint) then @expected_params = []
else @expected_params = process_arg_constraints(args)
if ArgumentConstraints::AnyArgsConstraint === args.first
@match_any_args = true
elsif ArgumentConstraints::NoArgsConstraint === args.first
@constraints = []
else
@constraints = args.collect {|arg| constraint_for(arg)}
end
end
def process_arg_constraints(constraints)
constraints.collect do |constraint|
convert_constraint(constraint)
end
end
def warn_deprecated(deprecated_method, instead)
Kernel.warn "The #{deprecated_method} constraint is deprecated. Use #{instead} instead."
end
def convert_constraint(constraint)
if [:anything, :numeric, :boolean, :string].include?(constraint)
case constraint
when :anything
instead = "anything()"
when :boolean
instead = "boolean()"
when :numeric
instead = "an_instance_of(Numeric)"
when :string
instead = "an_instance_of(String)"
end
warn_deprecated(constraint.inspect, instead)
return @@constraint_classes[constraint].new(constraint)
end
return MatcherConstraint.new(constraint) if is_matcher?(constraint)
return RegexpArgConstraint.new(constraint) if constraint.is_a?(Regexp)
return LiteralArgConstraint.new(constraint)
def constraint_for(arg)
return ArgumentConstraints::MatcherConstraint.new(arg) if is_matcher?(arg)
return ArgumentConstraints::RegexpConstraint.new(arg) if arg.is_a?(Regexp)
return ArgumentConstraints::EqualityProxy.new(arg)
end
def is_matcher?(obj)
return obj.respond_to?(:matches?) && obj.respond_to?(:description)
end
def check_args(args)
if @constraints_block
@constraints_block.call(*args)
return true
end
return true if @expected_params.nil?
return true if @expected_params == args
return constraints_match?(args)
def args_match?(given_args)
match_any_args? || constraints_block_matches?(given_args) || constraints_match?(given_args)
end
def constraints_match?(args)
return false if args.length != @expected_params.length
@expected_params.each_index { |i| return false unless @expected_params[i].matches?(args[i]) }
return true
def constraints_block_matches?(given_args)
@constraints_block ? @constraints_block.call(*given_args) : nil
end
def constraints_match?(given_args)
@constraints == given_args
end
def match_any_args?
@match_any_args
end
end
end

View file

@ -44,7 +44,7 @@ module Spec
private
def intro
@name ? "Mock '#{@name}'" : @target.inspect
@name ? "Mock '#{@name}'" : @target.class == Class ? "<#{@target.inspect} (class)>" : (@target.nil? ? "nil" : @target.to_s)
end
def __raise(message)

View file

@ -3,7 +3,7 @@
# object in the system.
require 'spec/mocks/methods'
require 'spec/mocks/argument_constraint_matchers'
require 'spec/mocks/argument_constraints'
require 'spec/mocks/spec_methods'
require 'spec/mocks/proxy'
require 'spec/mocks/mock'

View file

@ -3,6 +3,10 @@ module Spec
class BaseExpectation
attr_reader :sym
attr_writer :expected_received_count, :method_block, :expected_from
protected :expected_received_count=, :method_block=, :expected_from=
attr_accessor :error_generator
protected :error_generator, :error_generator=
def initialize(error_generator, expectation_ordering, expected_from, sym, method_block, expected_received_count=1, opts={})
@error_generator = error_generator
@ -13,7 +17,7 @@ module Spec
@return_block = nil
@actual_received_count = 0
@expected_received_count = expected_received_count
@args_expectation = ArgumentExpectation.new([AnyArgsConstraint.new])
@args_expectation = ArgumentExpectation.new([ArgumentConstraints::AnyArgsConstraint.new])
@consecutive = false
@exception_to_raise = nil
@symbol_to_throw = nil
@ -23,6 +27,23 @@ module Spec
@args_to_yield = []
end
def build_child(expected_from, method_block, expected_received_count, opts={})
child = clone
child.expected_from = expected_from
child.method_block = method_block
child.expected_received_count = expected_received_count
new_gen = error_generator.clone
new_gen.opts = opts
child.error_generator = new_gen
child.clone_args_to_yield @args_to_yield
child
end
def error_generator_opts=(opts={})
@error_generator.opts = opts
end
protected :error_generator_opts=
def expected_args
@args_expectation.args
end
@ -63,16 +84,22 @@ module Spec
end
def and_yield(*args)
if @args_to_yield_were_cloned
@args_to_yield.clear
@args_to_yield_were_cloned = false
end
@args_to_yield << args
self
end
def matches(sym, args)
@sym == sym and @args_expectation.check_args(args)
@sym == sym and @args_expectation.args_match?(args)
end
def invoke(args, block)
if @expected_received_count == 0
@failed_fast = true
@actual_received_count += 1
@error_generator.raise_expectation_error @sym, @expected_received_count, @actual_received_count, *args
end
@ -103,6 +130,11 @@ module Spec
@actual_received_count += 1
end
end
def called_max_times?
@expected_received_count != :any && @expected_received_count > 0 &&
@actual_received_count >= @expected_received_count
end
protected
@ -147,16 +179,25 @@ module Spec
@return_block.call(*args)
end
end
def clone_args_to_yield(args)
@args_to_yield = args.clone
@args_to_yield_were_cloned = true
end
def failed_fast?
@failed_fast
end
end
class MessageExpectation < BaseExpectation
def matches_name_but_not_args(sym, args)
@sym == sym and not @args_expectation.check_args(args)
@sym == sym and not @args_expectation.args_match?(args)
end
def verify_messages_received
return if expected_messages_received?
return if expected_messages_received? || failed_fast?
generate_error
rescue Spec::Mocks::MockExpectationError => error

View file

@ -9,8 +9,12 @@ module Spec
__mock_proxy.add_negative_message_expectation(caller(1)[0], sym.to_sym, &block)
end
def stub!(sym, opts={})
__mock_proxy.add_stub(caller(1)[0], sym.to_sym, opts)
def stub!(sym_or_hash, opts={})
if Hash === sym_or_hash
sym_or_hash.each {|method, value| stub!(method).and_return value }
else
__mock_proxy.add_stub(caller(1)[0], sym_or_hash.to_sym, opts)
end
end
def received_message?(sym, *args, &block) #:nodoc:
@ -24,6 +28,14 @@ module Spec
def rspec_reset #:nodoc:
__mock_proxy.reset
end
def as_null_object
__mock_proxy.as_null_object
end
def null_object?
__mock_proxy.null_object?
end
private
@ -31,7 +43,7 @@ module Spec
if Mock === self
@mock_proxy ||= Proxy.new(self, @name, @options)
else
@mock_proxy ||= Proxy.new(self, self.class.name)
@mock_proxy ||= Proxy.new(self)
end
end
end

View file

@ -4,8 +4,18 @@ module Spec
DEFAULT_OPTIONS = {
:null_object => false,
}
@@warn_about_expectations_on_nil = true
def self.allow_message_expectations_on_nil
@@warn_about_expectations_on_nil = false
# ensure nil.rspec_verify is called even if an expectation is not set in the example
# otherwise the allowance would effect subsequent examples
$rspec_mocks.add(nil) unless $rspec_mocks.nil?
end
def initialize(target, name, options={})
def initialize(target, name=nil, options={})
@target = target
@name = name
@error_generator = ErrorGenerator.new target, name
@ -20,15 +30,27 @@ module Spec
def null_object?
@options[:null_object]
end
def as_null_object
@options[:null_object] = true
@target
end
def add_message_expectation(expected_from, sym, opts={}, &block)
def add_message_expectation(expected_from, sym, opts={}, &block)
__add sym
@expectations << MessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, block_given? ? block : nil, 1, opts)
warn_if_nil_class sym
if existing_stub = @stubs.detect {|s| s.sym == sym }
expectation = existing_stub.build_child(expected_from, block_given?? block : nil, 1, opts)
else
expectation = MessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, block_given? ? block : nil, 1, opts)
end
@expectations << expectation
@expectations.last
end
def add_negative_message_expectation(expected_from, sym, &block)
__add sym
warn_if_nil_class sym
@expectations << NegativeMessageExpectation.new(@error_generator, @expectation_ordering, expected_from, sym, block_given? ? block : nil)
@expectations.last
end
@ -50,6 +72,7 @@ module Spec
clear_stubs
reset_proxied_methods
clear_proxied_methods
reset_nil_expectations_warning
end
def received_message?(sym, *args, &block)
@ -61,13 +84,16 @@ module Spec
end
def message_received(sym, *args, &block)
if expectation = find_matching_expectation(sym, *args)
expectation.invoke(args, block)
elsif (stub = find_matching_method_stub(sym, *args))
expectation = find_matching_expectation(sym, *args)
stub = find_matching_method_stub(sym, *args)
if (stub && expectation && expectation.called_max_times?) || (stub && !expectation)
if expectation = find_almost_matching_expectation(sym, *args)
expectation.advise(args, block) unless expectation.expected_messages_received?
end
stub.invoke([], block)
elsif expectation
expectation.invoke(args, block)
elsif expectation = find_almost_matching_expectation(sym, *args)
expectation.advise(args, block) if null_object? unless expectation.expected_messages_received?
raise_unexpected_message_args_error(expectation, *args) unless (has_negative_expectation?(sym) or null_object?)
@ -91,6 +117,12 @@ module Spec
define_expected_method(sym)
end
def warn_if_nil_class(sym)
if proxy_for_nil_class? && @@warn_about_expectations_on_nil
Kernel.warn("An expectation of :#{sym} was set on nil. Called from #{caller[2]}. Use allow_message_expectations_on_nil to disable warnings.")
end
end
def define_expected_method(sym)
visibility_string = "#{visibility(sym)} :#{sym}"
if target_responds_to?(sym) && !target_metaclass.method_defined?(munge(sym))
@ -166,6 +198,14 @@ module Spec
end
end
end
def proxy_for_nil_class?
@target.nil?
end
def reset_nil_expectations_warning
@@warn_about_expectations_on_nil = true if proxy_for_nil_class?
end
def find_matching_expectation(sym, *args)
@expectations.find {|expectation| expectation.matches(sym, args)}

View file

@ -1,7 +1,7 @@
module Spec
module Mocks
module ExampleMethods
include Spec::Mocks::ArgumentConstraintMatchers
include Spec::Mocks::ArgumentConstraints
# Shortcut for creating an instance of Spec::Mocks::Mock.
#
@ -32,6 +32,14 @@ module Spec
def stub_everything(name = 'stub')
mock(name, :null_object => true)
end
# Disables warning messages about expectations being set on nil.
#
# By default warning messages are issued when expectations are set on nil. This is to
# prevent false-positives and to catch potential bugs early on.
def allow_message_expectations_on_nil
Proxy.allow_message_expectations_on_nil
end
end
end

View file

@ -107,7 +107,7 @@ module Spec
# A message to print to stderr when there are failures.
attr_accessor :failure_message
# Where RSpec's output is written. Defaults to STDOUT.
# Where RSpec's output is written. Defaults to $stdout.
# DEPRECATED. Use --format FORMAT:WHERE in spec_opts.
attr_accessor :out

View file

@ -35,11 +35,11 @@ module RCov
def define
desc "Verify that rcov coverage is at least #{threshold}%"
task @name do
total_coverage = nil
total_coverage = 0
File.open(index_html).each_line do |line|
if line =~ /<tt class='coverage_total'>(\d+\.\d+)%<\/tt>/
total_coverage = eval($1)
if line =~ /<tt class='coverage_total'>\s*(\d+\.\d+)%\s*<\/tt>/
total_coverage = $1.to_f
break
end
end

View file

@ -185,17 +185,30 @@ module Spec
end
def register_at_exit_hook # :nodoc:
$spec_runner_at_exit_hook_registered ||= nil
unless $spec_runner_at_exit_hook_registered
@spec_runner_at_exit_hook_registered ||= nil
unless @spec_runner_at_exit_hook_registered
at_exit do
unless $! || Spec.run?
success = Spec.run
exit success if Spec.exit?
end
end
$spec_runner_at_exit_hook_registered = true
@spec_runner_at_exit_hook_registered = true
end
end
def options # :nodoc:
@options ||= begin
parser = ::Spec::Runner::OptionParser.new($stderr, $stdout)
parser.order!(ARGV)
parser.options
end
end
def use options
@options = options
end
end
end
end

View file

@ -40,15 +40,14 @@ module Spec
def tweak_backtrace(error)
return if error.backtrace.nil?
error.backtrace.collect! do |line|
clean_up_double_slashes(line)
IGNORE_PATTERNS.each do |ignore|
if line =~ ignore
line = nil
break
error.backtrace.collect! do |message|
clean_up_double_slashes(message)
kept_lines = message.split("\n").select do |line|
IGNORE_PATTERNS.each do |ignore|
break if line =~ ignore
end
end
line
kept_lines.empty?? nil : kept_lines.join("\n")
end
error.backtrace.compact!
end

View file

@ -2,25 +2,14 @@ require 'spec/runner/option_parser'
module Spec
module Runner
# Facade to run specs without having to fork a new ruby process (using `spec ...`)
class CommandLine
class << self
# Runs specs. +argv+ is the commandline args as per the spec commandline API, +err+
# and +out+ are the streams output will be written to.
def run(instance_rspec_options)
# NOTE - this call to init_rspec_options is not spec'd, but neither is any of this
# swapping of $rspec_options. That is all here to enable rspec to run against itself
# and maintain coverage in a single process. Therefore, DO NOT mess with this stuff
# unless you know what you are doing!
init_rspec_options(instance_rspec_options)
orig_rspec_options = rspec_options
begin
$rspec_options = instance_rspec_options
return $rspec_options.run_examples
ensure
::Spec.run = true
$rspec_options = orig_rspec_options
end
def run(tmp_options=Spec::Runner.options)
orig_options = Spec::Runner.options
Spec::Runner.use tmp_options
tmp_options.run_examples
ensure
Spec::Runner.use orig_options
end
end
end

View file

@ -45,7 +45,9 @@ module Spec
# been provided a block), or when an ExamplePendingError is raised.
# +message+ is the message from the ExamplePendingError, if it exists, or the
# default value of "Not Yet Implemented"
def example_pending(example, message)
# +pending_caller+ is the file and line number of the spec which
# has called the pending method
def example_pending(example, message, pending_caller)
end
# This method is invoked after all of the examples have executed. The next method

View file

@ -15,19 +15,14 @@ module Spec
super
if where.is_a?(String)
@output = File.open(where, 'w')
elsif where == STDOUT
@output = Kernel
def @output.flush
STDOUT.flush
end
else
@output = where
end
@pending_examples = []
end
def example_pending(example, message)
@pending_examples << [example.__full_description, message]
def example_pending(example, message, pending_caller)
@pending_examples << [example.__full_description, message, pending_caller]
end
def dump_failure(counter, failure)
@ -75,13 +70,14 @@ module Spec
@output.puts "Pending:"
@pending_examples.each do |pending_example|
@output.puts "#{pending_example[0]} (#{pending_example[1]})"
@output.puts " Called from #{pending_example[2]}"
end
end
@output.flush
end
def close
if IO === @output
if IO === @output && @output != $stdout
@output.close
end
end
@ -112,7 +108,7 @@ module Spec
def output_to_tty?
begin
@output == Kernel || @output.tty?
@output.tty? || ENV.has_key?("AUTOTEST")
rescue NoMethodError
false
end

View file

@ -85,7 +85,7 @@ module Spec
@output.flush
end
def example_pending(example, message)
def example_pending(example, message, pending_caller)
@output.puts " <script type=\"text/javascript\">makeYellow('rspec-header');</script>" unless @header_red
@output.puts " <script type=\"text/javascript\">makeYellow('example_group_#{example_group_number}');</script>" unless @example_group_red
move_progress

View file

@ -40,7 +40,7 @@ module Spec
output.flush
end
def example_pending(example, message)
def example_pending(example, message, pending_caller)
super
output.puts yellow("#{current_indentation}#{example.description} (PENDING: #{message})")
output.flush

View file

@ -14,9 +14,9 @@ module Spec
@output.flush
end
def example_pending(example, message)
def example_pending(example, message, pending_caller)
super
@output.print yellow('P')
@output.print yellow('*')
@output.flush
end

View file

@ -28,7 +28,7 @@ module Spec
output.flush
end
def example_pending(example, message)
def example_pending(example, message, pending_caller)
super
output.puts yellow("- #{example.description} (PENDING: #{message})")
output.flush

View file

@ -86,6 +86,7 @@ EOF
end
def scenario_started(story_title, scenario_name)
@previous_type = nil
@scenario_failed = false
@scenario_text = <<-EOF
<dt>Scenario: #{h scenario_name}</dt>
@ -149,10 +150,22 @@ EOF
spans = args.map { |arg| "<span class=\"param\">#{arg}</span>" }
desc_string = description.step_name
arg_regexp = description.arg_regexp
inner = if(type == @previous_type)
"And "
else
"#{type.to_s.capitalize} "
end
i = -1
inner = type.to_s.capitalize + ' ' + desc_string.gsub(arg_regexp) { |param| spans[i+=1] }
inner += desc_string.gsub(arg_regexp) { |param| spans[i+=1] }
@scenario_text += " <li class=\"#{klass}\">#{inner}</li>\n"
if type == :'given scenario'
@previous_type = :given
else
@previous_type = type
end
end
end
end

View file

@ -104,7 +104,14 @@ module Spec
end
def run_ended
@output.puts "#@count scenarios: #@successful_scenario_count succeeded, #{@failed_scenarios.size} failed, #@pending_scenario_count pending"
summary_text = "#@count scenarios: #@successful_scenario_count succeeded, #{@failed_scenarios.size} failed, #@pending_scenario_count pending"
if !@failed_scenarios.empty?
@output.puts red(summary_text)
elsif !@pending_steps.empty?
@output.puts yellow(summary_text)
else
@output.puts green(summary_text)
end
unless @pending_steps.empty?
@output.puts "\nPending Steps:"
@pending_steps.each_with_index do |pending, i|
@ -116,11 +123,10 @@ module Spec
@output.print "\nFAILURES:"
@failed_scenarios.each_with_index do |failure, i|
title, scenario_name, err = failure
@output.print %[
#{i+1}) #{title} (#{scenario_name}) FAILED
#{err.class}: #{err.message}
#{err.backtrace.join("\n")}
]
@output.print "\n #{i+1}) "
@output.print red("#{title} (#{scenario_name}) FAILED")
@output.print red("\n #{err.class}: #{err.message}")
@output.print "\n #{err.backtrace.join("\n")}\n"
end
end
end

View file

@ -0,0 +1,42 @@
require 'spec/runner/formatter/story/plain_text_formatter'
module Spec
module Runner
module Formatter
module Story
class ProgressBarFormatter < PlainTextFormatter
def story_started(title, narrative) end
def story_ended(title, narrative) end
def run_started(count)
@start_time = Time.now
super
end
def run_ended
@output.puts
@output.puts
@output.puts "Finished in %f seconds" % (Time.now - @start_time)
@output.puts
super
end
def scenario_ended
if @scenario_failed
@output.print red('F')
@output.flush
elsif @scenario_pending
@output.print yellow('P')
@output.flush
else
@output.print green('.')
@output.flush
end
end
end
end
end
end
end

View file

@ -25,7 +25,7 @@ module Spec
def heckle_method(class_name, method_name)
verify_constant(class_name)
heckle = @heckle_class.new(class_name, method_name, rspec_options)
heckle = @heckle_class.new(class_name, method_name, Spec::Runner.options)
heckle.validate
end
@ -39,7 +39,7 @@ module Spec
classes.each do |klass|
klass.instance_methods(false).each do |method_name|
heckle = @heckle_class.new(klass.name, method_name, rspec_options)
heckle = @heckle_class.new(klass.name, method_name, Spec::Runner.options)
heckle.validate
end
end

View file

@ -34,11 +34,11 @@ module Spec
"an example name directly, causing RSpec to run just the example",
"matching that name"],
:specification => ["-s", "--specification [NAME]", "DEPRECATED - use -e instead", "(This will be removed when autotest works with -e)"],
:line => ["-l", "--line LINE_NUMBER", Integer, "Execute behaviout or specification at given line.",
:line => ["-l", "--line LINE_NUMBER", Integer, "Execute behaviour or specification at given line.",
"(does not work for dynamically generated specs)"],
:format => ["-f", "--format FORMAT[:WHERE]","Specifies what format to use for output. Specify WHERE to tell",
"the formatter where to write the output. All built-in formats",
"expect WHERE to be a file name, and will write to STDOUT if it's",
"expect WHERE to be a file name, and will write to $stdout if it's",
"not specified. The --format option may be specified several times",
"if you want several outputs",
" ",
@ -54,6 +54,7 @@ module Spec
"Builtin formats for stories: ",
"plain|p : Plain Text",
"html|h : A nice HTML report",
"progress|r : Text progress",
" ",
"FORMAT can also be the name of a custom formatter class",
"(in which case you should also specify --require to load it)"],
@ -93,30 +94,30 @@ module Spec
self.banner = "Usage: spec (FILE|DIRECTORY|GLOB)+ [options]"
self.separator ""
on(*OPTIONS[:pattern]) {|pattern| @options.filename_pattern = pattern}
on(*OPTIONS[:diff]) {|diff| @options.parse_diff(diff)}
on(*OPTIONS[:colour]) {@options.colour = true}
on(*OPTIONS[:example]) {|example| @options.parse_example(example)}
on(*OPTIONS[:specification]) {|example| @options.parse_example(example)}
on(*OPTIONS[:line]) {|line_number| @options.line_number = line_number.to_i}
on(*OPTIONS[:format]) {|format| @options.parse_format(format)}
on(*OPTIONS[:require]) {|requires| invoke_requires(requires)}
on(*OPTIONS[:backtrace]) {@options.backtrace_tweaker = NoisyBacktraceTweaker.new}
on(*OPTIONS[:loadby]) {|loadby| @options.loadby = loadby}
on(*OPTIONS[:reverse]) {@options.reverse = true}
on(*OPTIONS[:timeout]) {|timeout| @options.timeout = timeout.to_f}
on(*OPTIONS[:heckle]) {|heckle| @options.load_heckle_runner(heckle)}
on(*OPTIONS[:dry_run]) {@options.dry_run = true}
on(*OPTIONS[:options_file]) {|options_file| parse_options_file(options_file)}
on(*OPTIONS[:pattern]) {|pattern| @options.filename_pattern = pattern}
on(*OPTIONS[:diff]) {|diff| @options.parse_diff(diff)}
on(*OPTIONS[:colour]) {@options.colour = true}
on(*OPTIONS[:example]) {|example| @options.parse_example(example)}
on(*OPTIONS[:specification]) {|example| @options.parse_example(example)}
on(*OPTIONS[:line]) {|line_number| @options.line_number = line_number.to_i}
on(*OPTIONS[:format]) {|format| @options.parse_format(format)}
on(*OPTIONS[:require]) {|requires| invoke_requires(requires)}
on(*OPTIONS[:backtrace]) {@options.backtrace_tweaker = NoisyBacktraceTweaker.new}
on(*OPTIONS[:loadby]) {|loadby| @options.loadby = loadby}
on(*OPTIONS[:reverse]) {@options.reverse = true}
on(*OPTIONS[:timeout]) {|timeout| @options.timeout = timeout.to_f}
on(*OPTIONS[:heckle]) {|heckle| @options.load_heckle_runner(heckle)}
on(*OPTIONS[:dry_run]) {@options.dry_run = true}
on(*OPTIONS[:options_file]) {|options_file| parse_options_file(options_file)}
on(*OPTIONS[:generate_options]) {|options_file|}
on(*OPTIONS[:runner]) {|runner| @options.user_input_for_runner = runner}
on(*OPTIONS[:drb]) {}
on(*OPTIONS[:version]) {parse_version}
on_tail(*OPTIONS[:help]) {parse_help}
on(*OPTIONS[:runner]) {|runner| @options.user_input_for_runner = runner}
on(*OPTIONS[:drb]) {}
on(*OPTIONS[:version]) {parse_version}
on_tail(*OPTIONS[:help]) {parse_help}
end
def order!(argv, &blk)
@argv = argv
@argv = (argv.empty? && Spec.spec_command?) ? ['--help'] : argv
@options.argv = @argv.dup
return if parse_generate_options
return if parse_drb
@ -128,7 +129,7 @@ module Spec
@options
end
protected
def invoke_requires(requires)
requires.split(",").each do |file|
@ -186,7 +187,7 @@ module Spec
end
def parse_version
@out_stream.puts ::Spec::VERSION::DESCRIPTION
@out_stream.puts ::Spec::VERSION::SUMMARY
exit if stdout?
end

View file

@ -24,10 +24,13 @@ module Spec
}
STORY_FORMATTERS = {
'plain' => ['spec/runner/formatter/story/plain_text_formatter', 'Formatter::Story::PlainTextFormatter'],
'p' => ['spec/runner/formatter/story/plain_text_formatter', 'Formatter::Story::PlainTextFormatter'],
'html' => ['spec/runner/formatter/story/html_formatter', 'Formatter::Story::HtmlFormatter'],
'h' => ['spec/runner/formatter/story/html_formatter', 'Formatter::Story::HtmlFormatter']
'plain' => ['spec/runner/formatter/story/plain_text_formatter', 'Formatter::Story::PlainTextFormatter'],
'p' => ['spec/runner/formatter/story/plain_text_formatter', 'Formatter::Story::PlainTextFormatter'],
'html' => ['spec/runner/formatter/story/html_formatter', 'Formatter::Story::HtmlFormatter'],
'h' => ['spec/runner/formatter/story/html_formatter', 'Formatter::Story::HtmlFormatter'],
'progress' => ['spec/runner/formatter/story/progress_bar_formatter', 'Formatter::Story::ProgressBarFormatter'],
'r' => ['spec/runner/formatter/story/progress_bar_formatter', 'Formatter::Story::ProgressBarFormatter']
}
attr_accessor(
@ -54,7 +57,7 @@ module Spec
:argv
)
attr_reader :colour, :differ_class, :files, :example_groups
def initialize(error_stream, output_stream)
@error_stream = error_stream
@output_stream = output_stream
@ -89,9 +92,6 @@ module Spec
return true unless examples_should_be_run?
success = true
begin
before_suite_parts.each do |part|
part.call
end
runner = custom_runner || ExampleGroupRunner.new(self)
unless @files_loaded
@ -99,6 +99,15 @@ module Spec
@files_loaded = true
end
# TODO - this has to happen after the files get loaded,
# otherwise the before_suite_parts are not populated
# from the configuration. There is no spec for this
# directly, but stories/configuration/before_blocks.story
# will fail if this happens before the files are loaded.
before_suite_parts.each do |part|
part.call
end
if example_groups.empty?
true
else
@ -125,10 +134,12 @@ module Spec
def colour=(colour)
@colour = colour
if @colour && RUBY_PLATFORM =~ /win32/ ;\
if @colour && RUBY_PLATFORM =~ /mswin|mingw/ ;\
begin ;\
replace_output = @output_stream.equal?($stdout) ;\
require 'rubygems' ;\
require 'Win32/Console/ANSI' ;\
@output_stream = $stdout if replace_output ;\
rescue LoadError ;\
warn "You must 'gem install win32console' to use colour on Windows" ;\
@colour = false ;\

View file

@ -26,7 +26,7 @@ module Spec
if error.nil?
example_passed(example)
elsif Spec::Example::ExamplePendingError === error
example_pending(example, error.message)
example_pending(example, error.pending_caller, error.message)
else
example_failed(example, error)
end
@ -103,14 +103,34 @@ module Spec
def example_passed(example)
formatters.each{|f| f.example_passed(example)}
end
EXAMPLE_PENDING_DEPRECATION_WARNING = <<-WARNING
DEPRECATION NOTICE: RSpec's formatters have changed example_pending
to accept three arguments instead of just two. Please see the rdoc
for Spec::Runner::Formatter::BaseFormatter#example_pending
for more information.
Please update any custom formatters to accept the third argument
to example_pending. Support for example_pending with two arguments
and this warning message will be removed after the RSpec 1.1.5 release.
WARNING
def example_pending(example, message="Not Yet Implemented")
def example_pending(example, pending_caller, message="Not Yet Implemented")
@pending_count += 1
formatters.each do |f|
f.example_pending(example, message)
formatters.each do |formatter|
if formatter_uses_deprecated_example_pending_method?(formatter)
Kernel.warn EXAMPLE_PENDING_DEPRECATION_WARNING
formatter.example_pending(example, message)
else
formatter.example_pending(example, message, pending_caller)
end
end
end
def formatter_uses_deprecated_example_pending_method?(formatter)
formatter.method(:example_pending).arity == 2
end
class Failure
attr_reader :example, :exception

View file

@ -11,7 +11,7 @@ module Spec
def spec_name_for(file, line_number)
best_match.clear
file = File.expand_path(file)
rspec_options.example_groups.each do |example_group|
Spec::Runner.options.example_groups.each do |example_group|
consider_example_groups_for_best_match example_group, file, line_number
example_group.examples.each do |example|

View file

@ -10,8 +10,7 @@ module Spec
module Runner
class << self
def run_options # :nodoc:
rspec_options
# @run_options ||= ::Spec::Runner::OptionParser.parse(ARGV, $stderr, $stdout)
Spec::Runner.options
end
def story_runner # :nodoc:
@ -34,7 +33,7 @@ module Spec
end
def create_story_runner
StoryRunner.new(scenario_runner, world_creator)
Runner::StoryRunner.new(scenario_runner, world_creator)
end
# Use this to register a customer output formatter.

View file

@ -19,11 +19,11 @@ module Spec
end
def matches?(name)
!(matches = name.match(@expression)).nil?
!(name.strip =~ @expression).nil?
end
def parse_args(name)
name.match(@expression)[1..-1]
name.strip.match(@expression)[1..-1]
end
private
@ -60,7 +60,7 @@ module Spec
expression = string_or_regexp.source
end
while expression =~ PARAM_PATTERN
expression.gsub!($2, "(.*?)")
expression.sub!($2, "(.*?)")
end
@expression = Regexp.new("\\A#{expression}\\Z", Regexp::MULTILINE)
end

View file

@ -13,7 +13,8 @@ module Spec
@steps.add(type, step)
end
def find(type, name)
def find(type, unstripped_name)
name = unstripped_name.strip
if @steps.find(type, name).nil?
@steps.add(type,
Step.new(name) do

View file

@ -1,114 +0,0 @@
require 'fileutils'
module Spec
class Translator
def translate(from, to)
from = File.expand_path(from)
to = File.expand_path(to)
if File.directory?(from)
translate_dir(from, to)
elsif(from =~ /\.rb$/)
translate_file(from, to)
end
end
def translate_dir(from, to)
FileUtils.mkdir_p(to) unless File.directory?(to)
Dir["#{from}/*"].each do |sub_from|
path = sub_from[from.length+1..-1]
sub_to = File.join(to, path)
translate(sub_from, sub_to)
end
end
def translate_file(from, to)
translation = ""
File.open(from) do |io|
io.each_line do |line|
translation << translate_line(line)
end
end
File.open(to, "w") do |io|
io.write(translation)
end
end
def translate_line(line)
# Translate deprecated mock constraints
line.gsub!(/:any_args/, 'any_args')
line.gsub!(/:anything/, 'anything')
line.gsub!(/:boolean/, 'boolean')
line.gsub!(/:no_args/, 'no_args')
line.gsub!(/:numeric/, 'an_instance_of(Numeric)')
line.gsub!(/:string/, 'an_instance_of(String)')
return line if line =~ /(should_not|should)_receive/
line.gsub!(/(^\s*)context([\s*|\(]['|"|A-Z])/, '\1describe\2')
line.gsub!(/(^\s*)specify([\s*|\(]['|"|A-Z])/, '\1it\2')
line.gsub!(/(^\s*)context_setup(\s*[do|\{])/, '\1before(:all)\2')
line.gsub!(/(^\s*)context_teardown(\s*[do|\{])/, '\1after(:all)\2')
line.gsub!(/(^\s*)setup(\s*[do|\{])/, '\1before(:each)\2')
line.gsub!(/(^\s*)teardown(\s*[do|\{])/, '\1after(:each)\2')
if line =~ /(.*\.)(should_not|should)(?:_be)(?!_)(.*)/m
pre = $1
should = $2
post = $3
be_or_equal = post =~ /(<|>)/ ? "be" : "equal"
return "#{pre}#{should} #{be_or_equal}#{post}"
end
if line =~ /(.*\.)(should_not|should)_(?!not)\s*(.*)/m
pre = $1
should = $2
post = $3
post.gsub!(/^raise/, 'raise_error')
post.gsub!(/^throw/, 'throw_symbol')
unless standard_matcher?(post)
post = "be_#{post}"
end
# Add parenthesis
post.gsub!(/^(\w+)\s+([\w|\.|\,|\(.*\)|\'|\"|\:|@| ]+)(\})/, '\1(\2)\3') # inside a block
post.gsub!(/^(redirect_to)\s+(.*)/, '\1(\2)') # redirect_to, which often has http:
post.gsub!(/^(\w+)\s+([\w|\.|\,|\(.*\)|\{.*\}|\'|\"|\:|@| ]+)/, '\1(\2)')
post.gsub!(/(\s+\))/, ')')
post.gsub!(/\)\}/, ') }')
post.gsub!(/^(\w+)\s+(\/.*\/)/, '\1(\2)') #regexps
line = "#{pre}#{should} #{post}"
end
line
end
def standard_matcher?(matcher)
patterns = [
/^be/,
/^be_close/,
/^eql/,
/^equal/,
/^has/,
/^have/,
/^change/,
/^include/,
/^match/,
/^raise_error/,
/^respond_to/,
/^redirect_to/,
/^satisfy/,
/^throw_symbol/,
# Extra ones that we use in spec_helper
/^pass/,
/^fail/,
/^fail_with/,
]
matched = patterns.detect{ |p| matcher =~ p }
!matched.nil?
end
end
end

View file

@ -3,20 +3,11 @@ module Spec
unless defined? MAJOR
MAJOR = 1
MINOR = 1
TINY = 4
RELEASE_CANDIDATE = nil
BUILD_TIME_UTC = 20080615141040
TINY = 8
STRING = [MAJOR, MINOR, TINY].join('.')
TAG = "REL_#{[MAJOR, MINOR, TINY, RELEASE_CANDIDATE].compact.join('_')}".upcase.gsub(/\.|-/, '_')
FULL_VERSION = "#{[MAJOR, MINOR, TINY, RELEASE_CANDIDATE].compact.join('.')} (build #{BUILD_TIME_UTC})"
NAME = "RSpec"
URL = "http://rspec.rubyforge.org/"
DESCRIPTION = "#{NAME}-#{FULL_VERSION} - BDD for Ruby\n#{URL}"
SUMMARY = "rspec #{STRING}"
end
end
end
end

View file

@ -4,6 +4,6 @@ require 'spec/rake/spectask'
desc "Generate HTML report for failing examples"
Spec::Rake::SpecTask.new('failing_examples_with_html') do |t|
t.spec_files = FileList['failing_examples/**/*.rb']
t.spec_opts = ["--format", "html:../doc/output/documentation/tools/failing_examples.html", "--diff"]
t.spec_opts = ["--format", "html:doc/reports/tools/failing_examples.html", "--diff"]
t.fail_on_error = false
end

View file

@ -2,6 +2,6 @@ require 'rake'
require 'spec/rake/verify_rcov'
RCov::VerifyTask.new(:verify_rcov => :spec) do |t|
t.threshold = 100.0 # Make sure you have rcov 0.7 or higher!
t.index_html = '../doc/output/coverage/index.html'
t.threshold = 100.0
t.index_html = 'coverage/index.html'
end

33
vendor/plugins/rspec/rspec.gemspec vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -1,6 +1,6 @@
require "rubygems"
require 'autotest'
dir = File.dirname(__FILE__)
require "#{dir}/spec_helper"
require File.expand_path("#{dir}/../lib/autotest/rspec")
require "#{dir}/../spec_helper"
require File.expand_path("#{dir}/../../lib/autotest/rspec")
require "#{dir}/autotest_matchers"

View file

@ -1,4 +1,4 @@
require File.dirname(__FILE__) + "/../autotest_helper"
require File.dirname(__FILE__) + "/autotest_helper"
module DiscoveryHelper
def load_discovery

View file

@ -1,4 +1,4 @@
require File.dirname(__FILE__) + "/../autotest_helper"
require File.dirname(__FILE__) + "/autotest_helper"
class Autotest
@ -37,62 +37,6 @@ HERE
end
describe Rspec do
describe "selection of rspec command" do
include AutotestHelper
before(:each) do
common_setup
@rspec_autotest = Rspec.new
end
it "should try to find the spec command if it exists in ./bin and use it above everything else" do
File.stub!(:exists?).and_return true
spec_path = File.expand_path("#{File.dirname(__FILE__)}/../../bin/spec")
File.should_receive(:exists?).with(spec_path).and_return true
@rspec_autotest.spec_command.should == spec_path
end
it "should otherwise select the default spec command in gem_dir/bin/spec" do
@rspec_autotest.stub!(:spec_commands).and_return ["/foo/spec"]
Config::CONFIG.stub!(:[]).and_return "/foo"
File.should_receive(:exists?).with("/foo/spec").and_return(true)
@rspec_autotest.spec_command.should == "/foo/spec"
end
it "should raise an error if no spec command is found at all" do
File.stub!(:exists?).and_return false
lambda {
@rspec_autotest.spec_command
}.should raise_error(RspecCommandError, "No spec command could be found!")
end
end
describe "selection of rspec command (windows compatibility issues)" do
include AutotestHelper
before(:each) do
common_setup
end
it "should use the ALT_SEPARATOR if it is non-nil" do
@rspec_autotest = Rspec.new
spec_command = File.expand_path("#{File.dirname(__FILE__)}/../../bin/spec")
@rspec_autotest.stub!(:spec_commands).and_return [spec_command]
@rspec_autotest.spec_command(@windows_alt_separator).should == spec_command.gsub('/', @windows_alt_separator)
end
it "should not use the ALT_SEPATOR if it is nil" do
@windows_alt_separator = nil
@rspec_autotest = Rspec.new
spec_command = File.expand_path("#{File.dirname(__FILE__)}/../../bin/spec")
@rspec_autotest.stub!(:spec_commands).and_return [spec_command]
@rspec_autotest.spec_command.should == spec_command
end
end
describe "adding spec.opts --options" do
before(:each) do
@rspec_autotest = Rspec.new
@ -116,7 +60,6 @@ HERE
@rspec_autotest.stub!(:add_options_if_present).and_return "-O spec/spec.opts"
@ruby = @rspec_autotest.ruby
@spec_command = @rspec_autotest.spec_command
@options = @rspec_autotest.add_options_if_present
@files_to_test = {
:spec => ["file_one", "file_two"]
@ -126,16 +69,13 @@ HERE
@files_to_test.stub!(:keys).and_return @files_to_test[:spec]
@to_test = @files_to_test.keys.flatten.join ' '
end
it "should contain the various commands, ordered by preference" do
Rspec.new.spec_commands.should == [
File.expand_path("#{File.dirname(__FILE__)}/../../bin/spec"),
"#{Config::CONFIG['bindir']}/spec"
]
end
it "should make the apropriate test command" do
@rspec_autotest.make_test_cmd(@files_to_test).should == "#{@ruby} -S #{@spec_command} #{@options} #{@to_test}"
it "should make the appropriate test command" do
@rspec_autotest.make_test_cmd(@files_to_test).should == "#{@ruby} -S #{@to_test} #{@options}"
end
it "should return a blank command for no files" do
@rspec_autotest.make_test_cmd({}).should == ''
end
end
@ -156,7 +96,11 @@ HERE
@rspec_autotest.should map_specs([@spec_file]).to(@spec_file)
end
it "should only find the file if the file is being tracked (in @file)" do
it "should ignore files in spec dir that aren't specs" do
@rspec_autotest.should map_specs([]).to("spec/spec_helper.rb")
end
it "should ignore untracked files (in @file)" do
@rspec_autotest.should map_specs([]).to("lib/untracked_file")
end
end

View file

@ -1,7 +1,6 @@
if __FILE__ == $0
dir = File.dirname(__FILE__)
Dir["#{dir}/**/*_spec.rb"].reverse.each do |file|
# puts "require '#{file}'"
require file
end
end

View file

@ -7,4 +7,10 @@ describe Spec::Adapters::RubyEngine do
Spec::Adapters::RubyEngine.stub!(:engine).and_return('rbx')
Spec::Adapters::RubyEngine.adapter.should be_an_instance_of(Spec::Adapters::RubyEngine::Rubinius)
end
it "should try to find whatever is defined by the RUBY_ENGINE const" do
Object.stub!(:const_defined?).with('RUBY_ENGINE').and_return(true)
Object.stub!(:const_get).with('RUBY_ENGINE').and_return("xyz")
Spec::Adapters::RubyEngine.engine.should == "xyz"
end
end

View file

@ -125,14 +125,14 @@ module Spec
it "should register ExampleGroup by default" do
example_group = Spec::Example::ExampleGroupFactory.create_example_group("The ExampleGroup") do
end
rspec_options.example_groups.should include(example_group)
Spec::Runner.options.example_groups.should include(example_group)
end
it "should enable unregistering of ExampleGroups" do
example_group = Spec::Example::ExampleGroupFactory.create_example_group("The ExampleGroup") do
unregister
end
rspec_options.example_groups.should_not include(example_group)
Spec::Runner.options.example_groups.should_not include(example_group)
end
after(:each) do

View file

@ -3,10 +3,12 @@ require File.dirname(__FILE__) + '/../../spec_helper'
module Spec
module Example
describe 'ExampleGroupMethods' do
it_should_behave_like "sandboxed rspec_options"
include SandboxedOptions
attr_reader :example_group, :result, :reporter
before(:each) do
options.formatters << mock("formatter", :null_object => true)
# See http://rspec.lighthouseapp.com/projects/5645-rspec/tickets/525-arity-changed-on-partial-mocks#ticket-525-2
method_with_three_args = lambda { |arg1, arg2, arg3| }
options.formatters << mock("formatter", :null_object => true, :example_pending => method_with_three_args)
options.backtrace_tweaker = mock("backtrace_tweaker", :null_object => true)
@reporter = FakeReporter.new(@options)
options.reporter = reporter
@ -25,7 +27,7 @@ module Spec
end
["describe","context"].each do |method|
describe "#{method}" do
describe "##{method}" do
describe "when creating an ExampleGroup" do
attr_reader :child_example_group
before do
@ -567,6 +569,13 @@ module Spec
end
end
end
describe "#options" do
it "should expose the options hash" do
group = describe("group", :this => 'hash') {}
group.options[:this].should == 'hash'
end
end
end
end
end

View file

@ -65,10 +65,11 @@ module Spec
end
describe ExampleGroup, "#run" do
it_should_behave_like "sandboxed rspec_options"
include SandboxedOptions
attr_reader :example_group, :formatter, :reporter
before :each do
@formatter = mock("formatter", :null_object => true)
method_with_three_args = lambda { |arg1, arg2, arg3| }
@formatter = mock("formatter", :null_object => true, :example_pending => method_with_three_args)
options.formatters << formatter
options.backtrace_tweaker = mock("backtrace_tweaker", :null_object => true)
@reporter = FakeReporter.new(options)
@ -233,7 +234,7 @@ module Spec
options.examples = ["should be run"]
end
it "should run only the example, when there in only one" do
it "should run only the example, when there is only one" do
example_group.run
examples_that_were_run.should == ["should be run"]
end

View file

@ -23,9 +23,9 @@ module Spec
describe "lifecycle" do
before do
@original_rspec_options = $rspec_options
@original_rspec_options = Spec::Runner.options
@options = ::Spec::Runner::Options.new(StringIO.new, StringIO.new)
$rspec_options = @options
Spec::Runner.use @options
@options.formatters << mock("formatter", :null_object => true)
@options.backtrace_tweaker = mock("backtrace_tweaker", :null_object => true)
@reporter = FakeReporter.new(@options)
@ -43,7 +43,7 @@ module Spec
end
after do
$rspec_options = @original_rspec_options
Spec::Runner.use @original_rspec_options
ExampleMethods.instance_variable_set("@before_all_parts", [])
ExampleMethods.instance_variable_set("@before_each_parts", [])
ExampleMethods.instance_variable_set("@after_each_parts", [])
@ -83,19 +83,56 @@ module Spec
ExampleMethods.count.should == 7
end
describe "run_with_description_capturing" do
describe "eval_block" do
before(:each) do
@example_group = Class.new(ExampleGroup) do end
@example = @example_group.new("foo", &(lambda { 2.should == 2 }))
@example.run_with_description_capturing
@example_group = Class.new(ExampleGroup)
end
describe "with a given description" do
it "should provide the given description" do
@example = @example_group.it("given description") { 2.should == 2 }
@example.eval_block
@example.description.should == "given description"
end
end
it "should provide the generated description" do
@example.instance_eval { @_matcher_description }.should == "should == 2"
describe "with no given description" do
it "should provide the generated description" do
@example = @example_group.it { 2.should == 2 }
@example.eval_block
@example.description.should == "should == 2"
end
end
it "should clear the global generated_description" do
Spec::Matchers.generated_description.should == nil
describe "with no implementation" do
it "should raise an NotYetImplementedError" do
lambda {
@example = @example_group.it
@example.eval_block
}.should raise_error(Spec::Example::NotYetImplementedError, "Not Yet Implemented")
end
def extract_error(&blk)
begin
blk.call
rescue Exception => e
return e
end
nil
end
it "should use the proper file and line number for the NotYetImplementedError" do
file = __FILE__
line_number = __LINE__ + 3
error = extract_error do
@example = @example_group.it
@example.eval_block
end
error.pending_caller.should == "#{file}:#{line_number}"
end
end
end
end
@ -122,5 +159,14 @@ module Spec
end
end
end
describe "#options" do
it "should expose the options hash" do
example_group = Class.new(ExampleGroup)
example = example_group.example "name", :this => 'that' do; end
example.options[:this].should == 'that'
end
end
end
end
end

View file

@ -1,53 +0,0 @@
require File.dirname(__FILE__) + '/../../spec_helper'
module Spec
module Example
# describe Example do
# before(:each) do
# @example = Example.new "example" do
# foo
# end
# end
#
# it "should tell you its docstring" do
# @example.description.should == "example"
# end
#
# it "should execute its block in the context provided" do
# context = Class.new do
# def foo
# "foo"
# end
# end.new
# @example.run_in(context).should == "foo"
# end
# end
#
# describe Example, "#description" do
# it "should default to NO NAME when not passed anything when there are no matchers" do
# example = Example.new {}
# example.run_in(Object.new)
# example.description.should == "NO NAME"
# end
#
# it "should default to NO NAME description (Because of --dry-run) when passed nil and there are no matchers" do
# example = Example.new(nil) {}
# example.run_in(Object.new)
# example.description.should == "NO NAME"
# end
#
# it "should allow description to be overridden" do
# example = Example.new("Test description")
# example.description.should == "Test description"
# end
#
# it "should use description generated from matcher when there is no passed in description" do
# example = Example.new(nil) do
# 1.should == 1
# end
# example.run_in(Object.new)
# example.description.should == "should == 1"
# end
# end
end
end

View file

@ -18,6 +18,17 @@ module Spec
}.should raise_error(ExamplePendingError, /TODO/)
end
it 'should raise an ExamplePendingError if a supplied block fails as expected with a mock' do
lambda {
include Pending
pending "TODO" do
m = mock('thing')
m.should_receive(:foo)
m.rspec_verify
end
}.should raise_error(ExamplePendingError, /TODO/)
end
it 'should raise a PendingExampleFixedError if a supplied block starts working' do
lambda {
include Pending
@ -26,6 +37,109 @@ module Spec
end
}.should raise_error(PendingExampleFixedError, /TODO/)
end
it "should have the correct file and line number for pending given with a block which fails" do
file = __FILE__
line_number = __LINE__ + 3
begin
include Pending
pending do
raise
end
rescue => error
error.pending_caller.should == "#{file}:#{line_number}"
end
end
it "should have the correct file and line number for pending given with no block" do
file = __FILE__
line_number = __LINE__ + 3
begin
include Pending
pending("TODO")
rescue => error
error.pending_caller.should == "#{file}:#{line_number}"
end
end
end
describe ExamplePendingError do
it "should have the caller (from two calls from initialization)" do
two_calls_ago = caller[0]
ExamplePendingError.new("a message").pending_caller.should == two_calls_ago
end
it "should keep the trace information from initialization" do
two_calls_ago = caller[0]
obj = ExamplePendingError.new("a message")
obj.pending_caller
def another_caller(obj)
obj.pending_caller
end
another_caller(obj).should == two_calls_ago
end
it "should have the message provided" do
ExamplePendingError.new("a message").message.should == "a message"
end
it "should use a 'ExamplePendingError' as it's default message" do
ExamplePendingError.new.message.should == "Spec::Example::ExamplePendingError"
end
end
describe NotYetImplementedError do
def rspec_root
File.expand_path(__FILE__.gsub("/spec/spec/example/pending_module_spec.rb", "/lib"))
end
it "should have the root rspec path" do
NotYetImplementedError::RSPEC_ROOT_LIB.should == rspec_root
end
it "should always have the error 'Not Yet Implemented'" do
NotYetImplementedError.new([]).message.should == "Not Yet Implemented"
end
describe "pending_caller" do
it "should select an element out of the backtrace" do
error = NotYetImplementedError.new(["foo/bar.rb:18"])
error.pending_caller.should == "foo/bar.rb:18"
end
it "should actually report the element from the backtrace" do
error = NotYetImplementedError.new(["bar.rb:18"])
error.pending_caller.should == "bar.rb:18"
end
it "should not use an element with the rspec root path" do
error = NotYetImplementedError.new(["#{rspec_root}:8"])
error.pending_caller.should be_nil
end
it "should select the first line in the backtrace which isn't in the rspec root" do
error = NotYetImplementedError.new([
"#{rspec_root}/foo.rb:2",
"#{rspec_root}/foo/bar.rb:18",
"path1.rb:22",
"path2.rb:33"
])
error.pending_caller.should == "path1.rb:22"
end
it "should cache the caller" do
backtrace = mock('backtrace')
backtrace.should_receive(:detect).once
error = NotYetImplementedError.new(backtrace)
error.pending_caller.should == error.pending_caller
end
end
end
end
end

Some files were not shown because too many files have changed in this diff Show more