rspec 0.6.3 → 0.6.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. data/CHANGES +28 -3
  2. data/EXAMPLES.rd +2 -16
  3. data/README +5 -2
  4. data/Rakefile +8 -4
  5. data/bin/spec +1 -0
  6. data/examples/custom_formatter.rb +2 -1
  7. data/examples/helper_method_spec.rb +12 -0
  8. data/examples/{mocking_spec.rb → mocking_example.rb} +0 -0
  9. data/examples/{bdd_framework_spec.rb → predicate_example.rb} +0 -0
  10. data/examples/stubbing_example.rb +28 -0
  11. data/lib/spec.rb +2 -1
  12. data/lib/spec/expectations.rb +7 -0
  13. data/lib/spec/expectations/diff.rb +56 -0
  14. data/lib/spec/expectations/exceptions.rb +6 -0
  15. data/lib/spec/expectations/expectations.rb +19 -0
  16. data/lib/spec/expectations/have_helper.rb +41 -0
  17. data/lib/spec/expectations/helper.rb +4 -0
  18. data/lib/spec/expectations/should_base.rb +52 -0
  19. data/lib/spec/expectations/should_helper.rb +93 -0
  20. data/lib/spec/expectations/should_negator.rb +71 -0
  21. data/lib/spec/{api → expectations}/sugar.rb +8 -8
  22. data/lib/spec/mocks.rb +5 -0
  23. data/lib/spec/{api/mocks → mocks}/argument_expectation.rb +1 -1
  24. data/lib/spec/{api → mocks}/exceptions.rb +3 -5
  25. data/lib/spec/{api/mocks → mocks}/message_expectation.rb +15 -9
  26. data/lib/spec/{api/mocks → mocks}/mock.rb +44 -26
  27. data/lib/spec/{api/mocks → mocks}/order_group.rb +1 -1
  28. data/lib/spec/runner/backtrace_tweaker.rb +4 -1
  29. data/lib/spec/runner/execution_context.rb +13 -4
  30. data/lib/spec/runner/formatter/base_text_formatter.rb +26 -13
  31. data/lib/spec/runner/formatter/html_formatter.rb +1 -1
  32. data/lib/spec/runner/option_parser.rb +6 -2
  33. data/lib/spec/runner/specification.rb +2 -2
  34. data/lib/spec/test_to_spec/ruby2ruby.rb +1 -1
  35. data/lib/spec/version.rb +1 -1
  36. data/test/spec/expectations/arbitrary_operator_test.rb +55 -0
  37. data/test/spec/expectations/arbitrary_predicate_test.rb +163 -0
  38. data/test/spec/{api/helper → expectations}/containment_test.rb +2 -2
  39. data/test/spec/expectations/diff_test.rb +62 -0
  40. data/test/spec/{api/helper → expectations}/identity_test.rb +2 -2
  41. data/test/spec/{api/helper → expectations}/object_equality_test.rb +2 -2
  42. data/test/spec/{api/helper → expectations}/raising_test.rb +5 -5
  43. data/test/spec/{api/helper → expectations}/regex_matching_test.rb +6 -6
  44. data/test/spec/{api/helper → expectations}/should_have_test.rb +11 -2
  45. data/test/spec/{api/helper → expectations}/should_satisfy_test.rb +2 -4
  46. data/test/spec/{api → expectations}/sugar_test.rb +8 -8
  47. data/test/spec/expectations/supported_symbols_test.rb +33 -0
  48. data/test/spec/{api/helper → expectations}/throwing_test.rb +2 -2
  49. data/test/spec/{api/helper → expectations}/true_false_special_case_test.rb +2 -2
  50. data/test/spec/{api/helper → expectations}/typing_test.rb +2 -2
  51. data/test/spec/{api/mocks → mocks}/mock_arg_constraints_test.rb +4 -4
  52. data/test/spec/{api/mocks → mocks}/mock_counts_test.rb +2 -2
  53. data/test/spec/{api/mocks → mocks}/mock_ordering_test.rb +2 -2
  54. data/test/spec/{api/mocks → mocks}/mock_test.rb +22 -7
  55. data/test/spec/{api/mocks → mocks}/null_object_test.rb +8 -2
  56. data/test/spec/runner/backtrace_tweaker_test.rb +21 -19
  57. data/test/spec/runner/context_matching_test.rb +2 -2
  58. data/test/spec/runner/context_runner_test.rb +6 -6
  59. data/test/spec/runner/context_test.rb +1 -1
  60. data/test/spec/runner/execution_context_test.rb +22 -5
  61. data/test/spec/runner/formatter/failure_dump_test.rb +7 -7
  62. data/test/spec/runner/option_parser_test.rb +20 -0
  63. data/test/spec/runner/reporter_test.rb +3 -3
  64. data/test/spec/runner/specification_test.rb +3 -3
  65. data/test/spec/test_to_spec/sexp_transformer_assertion_test.rb +4 -4
  66. data/test/spec/test_to_spec/sexp_transformer_test.rb +1 -1
  67. data/test/spec/test_to_spec/testfiles/test_unit_api_test.rb +2 -2
  68. data/test/test_classes.rb +21 -1
  69. data/test/test_helper.rb +1 -1
  70. data/vendor/selenium/README.txt +23 -0
  71. data/vendor/selenium/find_rspecs_home_page.rb +23 -0
  72. data/vendor/selenium/rspec_selenium.rb +33 -0
  73. data/vendor/watir/README.txt +32 -0
  74. data/vendor/watir/find_rspecs_home_page.rb +21 -0
  75. data/vendor/watir/find_rspecs_home_page.txt +15 -0
  76. data/vendor/watir/rspec_watir.rb +45 -0
  77. metadata +52 -41
  78. data/examples/airport_spec.rb +0 -33
  79. data/examples/custom_method_spec.rb +0 -24
  80. data/examples/sugar_spec.rb +0 -14
  81. data/lib/spec/api.rb +0 -8
  82. data/lib/spec/api/expectations.rb +0 -17
  83. data/lib/spec/api/helper.rb +0 -4
  84. data/lib/spec/api/helper/diff.rb +0 -54
  85. data/lib/spec/api/helper/have_helper.rb +0 -40
  86. data/lib/spec/api/helper/should_base.rb +0 -31
  87. data/lib/spec/api/helper/should_helper.rb +0 -93
  88. data/lib/spec/api/helper/should_negator.rb +0 -72
  89. data/test/spec/api/helper/arbitrary_predicate_test.rb +0 -112
  90. data/test/spec/api/helper/diff_test.rb +0 -60
data/CHANGES CHANGED
@@ -1,5 +1,30 @@
1
1
  = RSpec Changelog
2
2
 
3
+ == Version 0.6.4
4
+
5
+ In addition to a number of bug fixes and patches, this release begins to formalize the support for
6
+ RSpec on Rails.
7
+
8
+ * Fixed [#5909], once again supporting multi_word_predicates
9
+ * Applied [#5873] - response.should_have_rjs (initial patch from Jake Howerton, based on ARTS by Kevin Clark)
10
+ * Added generation of view specs for rspec_on_rails
11
+ * Applied [#5815] active_record_subclass.should_have(3).records
12
+ * Added support in "rake stats" for view specs (in spec/views)
13
+ * Applied [#5801] QuickRef.pdf should say RSpec, not rSpec
14
+ * Applied [#5728] rails_spec_runner fails on Windows (Patch from Lindsay Evans).
15
+ * Applied [#5708] RSpec Rails plugin rspec_controller generator makes specs that do not parse.
16
+ * Cleaned up RSpec on Rails so it doesn't pollute as much during bootstrapping.
17
+ * Added support for response.should_have_tag and response.should_not_have_tag (works just like assert_tag in rails)
18
+ * Added new -c, --colour, --color option for colourful (red/green) output. Inspired from Pat Eyler's Redgreen gem.
19
+ * Added examples for Watir and Selenium under the gem's vendor directory.
20
+ * Renamed rails_spec_runner to rails_spec_server (as referred to in the docs)
21
+ * Added support for trying a plural for arbitrary predicates. E.g. Album.should_exist(:name => "Hey Jude") will call Album.exists?(:name => "Hey Jude")
22
+ * Added support for should_have to work with methods taking args returning a collection. E.g. @dave.should_have(3).albums_i_have_that_this_guy_doesnt(@aslak)
23
+ * Added [#5570] should_not_receive(:msg).with(:specific, "args")
24
+ * Applied [#5065] to support using define_method rather than method_missing to capture expected messages on mocks. Thanks to Eero Saynatkari for the tip that made it work.
25
+ * 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.
26
+ * Applied [#5620] support any boolean method and arbitrary comparisons (5.should_be < 6) (Patch from Mike Williams)
27
+
3
28
  == Version 0.6.3
4
29
 
5
30
  This release fixes some minor bugs related to RSpec on Rails
@@ -8,7 +33,7 @@ you should remove your lib/tasks/rspec.rake if it exists.
8
33
 
9
34
  * Backtraces from drb (and other standard ruby libraries) are now stripped from backtraces.
10
35
  * Applied [#5557] Put rspec.rake into the task directory of the RSpec on Rails plugin (Patch from Daniel Siemssen)
11
- * Applied [#5556] rails_spec_runner loads environment.rb twice (Patch from Daniel Siemssen)
36
+ * Applied [#5556] rails_spec_server loads environment.rb twice (Patch from Daniel Siemssen)
12
37
 
13
38
  == Version 0.6.2
14
39
  This release fixes a couple of regressions with the rake task that were introduced in the previous version (0.6.1)
@@ -29,7 +54,7 @@ Things that may break backwards compatibility:
29
54
  * Fixed [#5224] Move 'require diff-lcs' from test_helper.rb to diff_test.rb (Tip from Chris Roos)
30
55
  * Applied [#5449] Rake stats for specs (Patch from Nick Sieger)
31
56
  * Applied [#5468, #5058] Fix spec runner to correctly run controller specs (Patch from Daniel Siemssen)
32
- * Applied fixes to rails_spec_runner to improve its ability to run several times. (Patch from Daniel Siemssen)
57
+ * Applied fixes to rails_spec_server to improve its ability to run several times. (Patch from Daniel Siemssen)
33
58
  * Changed RCov::VerifyTask to fail if the coverage is above the threshold. This is to ensure it gets bumped when coverage improves.
34
59
 
35
60
  == Version 0.6.0
@@ -67,7 +92,7 @@ a experimental support for faster rails specs.
67
92
  * Methods can now be defined alongside specs. This obsoletes the need for defining methods in setup. (Patch #5002 from Brian Takita)
68
93
  * Sugar (underscores) now works correctly with should_be_a_kind_of and should_be_an_instance_of
69
94
  * Added support for include and inherit in contexts. (Patch #4971 from Brian Takita)
70
- * Added rails_spec and rails_spec_runner for faster specs on rails (still buggy - help needed)
95
+ * Added rails_spec and rails_spec_server for faster specs on rails (still buggy - help needed)
71
96
  * Fixed bug that caused should_render to break if given a :symbol (in Rails)
72
97
  * Added support for comparing exception message in should_raise and should_not_raise
73
98
 
@@ -1,21 +1,10 @@
1
- # Airport at home
2
- # * should always work
3
- # * not need cables
4
- # * not need electricity
5
- # BDD framework
6
- # * should be adopted quickly
7
- # * should be intuitive
8
- # Rspec allow you to define custom methods
9
- # * Rspec should allow you to define methods
10
- # Rspec allow you to define custom methods
11
- # * Rspec should allow you to define methods
12
1
  # A FileAccessor
13
2
  # * should open a file and pass it to the processor's process method
3
+ # Rspec
4
+ # * should allow you to define helper methods
14
5
  # An IoProcessor
15
6
  # * should raise nothing when the file is exactly 32 bytes
16
7
  # * should raise an exception when the file length is less than 32 bytes
17
- # A consumer of a mock
18
- # * should be able to send messages to the mock
19
8
  # A stack (in general)
20
9
  # * should add to the top when sent 'push'
21
10
  # * should return the top item when sent 'peek'
@@ -39,9 +28,6 @@
39
28
  # * should remain full after 'peek'
40
29
  # * should no longer be full after 'pop'
41
30
  # * should complain on 'push'
42
- # Underscore sugar
43
- # * should be available for regular objects
44
- # * should be available for mocks
45
31
  # Rspec should integrate with Test::Unit::TestCase
46
32
  # * TestCase#setup should be called.
47
33
  # * Rspec should be able to access TestCase methods
data/README CHANGED
@@ -1,5 +1,4 @@
1
- In order to run RSpec's tests and generate the gem and the website, you must have RubyGems.
2
- Then you must install the following gems:
1
+ In order to run RSpec's full test suite (rake pre_commit) you must install the following gems:
3
2
 
4
3
  * rake
5
4
  * rcov
@@ -9,6 +8,10 @@ Then you must install the following gems:
9
8
  * RedCloth
10
9
  * syntax
11
10
  * diff-lcs
11
+ * meta_project
12
+ * sqlite3-ruby
13
+
14
+ You must also install SQLite - which is needed to test the Rails plugin.
12
15
 
13
16
  Note that RSpec itself - once built - doesn't have any dependencies outside the Ruby core
14
17
  and stdlib - with a few exceptions:
data/Rakefile CHANGED
@@ -22,7 +22,11 @@ PKG_FILES = FileList[
22
22
  '[A-Z]*',
23
23
  'lib/**/*.rb',
24
24
  'test/**/*.rb',
25
- 'examples/**/*'
25
+ 'examples/**/*',
26
+ 'vendor/watir/*.rb',
27
+ 'vendor/watir/*.txt',
28
+ 'vendor/selenium/*.rb',
29
+ 'vendor/selenium/*.txt'
26
30
  ]
27
31
 
28
32
  task :default => :test
@@ -39,7 +43,7 @@ Rake::TestTask.new do |t|
39
43
  tests.exclude 'test/spec/test_to_spec/*.rb' if windows
40
44
  t.test_files = tests
41
45
  t.verbose = true
42
- t.warning = true
46
+ # t.warning = true
43
47
  end
44
48
 
45
49
  Rcov::RcovTask.new do |t|
@@ -178,8 +182,8 @@ task :pre_commit => [:verify_warnings, :website, :examples, :failing_examples_wi
178
182
 
179
183
  task :rails_pre_commit do
180
184
  Dir.chdir 'vendor/rspec_on_rails' do
181
- `rake pre_commit --verbose`
182
- raise "RSpec on Rails pre_commit failed\ncd to vendor/rspec_on_rails and run rake pre_commit for more details" if $? != 0
185
+ `rake pre_commit --verbose`
186
+ raise "RSpec on Rails pre_commit failed\n(cd to vendor/rspec_on_rails and run rake pre_commit for more details)" if $? != 0
183
187
  end
184
188
  end
185
189
 
data/bin/spec CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ $LOAD_PATH.push File.dirname(__FILE__) + "/../lib"
2
3
  require File.expand_path(File.dirname(__FILE__) + "/../lib/spec") # better stack traces this way
3
4
 
4
5
  $context_runner = ::Spec::Runner::OptionParser.create_context_runner(ARGV, false, STDERR, STDOUT)
@@ -2,12 +2,13 @@ require 'spec/runner/formatter/base_text_formatter'
2
2
 
3
3
  # Example of a custom formatter. Run me with:
4
4
  # bin/spec examples -r examples/custom_formatter.rb -f CustomFormatter
5
+ # bin/spec failing_examples -r examples/custom_formatter.rb -f CustomFormatter
5
6
  class CustomFormatter < Spec::Runner::Formatter::BaseTextFormatter
6
7
  def add_context(name, first)
7
8
  @output << "\n" if first
8
9
  end
9
10
 
10
- def spec_failed(name, counter)
11
+ def spec_failed(name, counter, failure)
11
12
  @output << 'X'
12
13
  end
13
14
 
@@ -0,0 +1,12 @@
1
+ require File.dirname(__FILE__) + '/../lib/spec'
2
+
3
+ context "Rspec" do
4
+ specify "should allow you to define helper methods" do
5
+ a_method
6
+ @a_method_called.should_be true
7
+ end
8
+
9
+ def a_method
10
+ @a_method_called = true
11
+ end
12
+ end
@@ -0,0 +1,28 @@
1
+ require File.dirname(__FILE__) + '/../lib/spec'
2
+
3
+ context "A consumer of a stub" do
4
+
5
+ specify "should be able to stub objects" do
6
+ obj = Object.new
7
+ stub(obj).method(:foobar).with {:return_value}
8
+ obj.foobar.should_equal :return_value
9
+ end
10
+
11
+ end
12
+
13
+ class StubbableClass
14
+ def self.find id
15
+ return :original_return
16
+ end
17
+ end
18
+
19
+ context "A stub" do
20
+ specify "should work at the class level" do
21
+ stub(StubbableClass).method(:find).with {:stub_return}
22
+ StubbableClass.find(1).should_equal :stub_return
23
+ end
24
+
25
+ specify "should revert to the original after each spec" do
26
+ StubbableClass.find(1).should_equal :original_return
27
+ end
28
+ end
@@ -1,4 +1,5 @@
1
1
  require 'spec/version'
2
- require 'spec/api'
2
+ require 'spec/expectations'
3
+ require 'spec/mocks'
3
4
  require 'spec/runner'
4
5
  require 'spec/runner/kernel_ext'
@@ -0,0 +1,7 @@
1
+ require 'spec/expectations/exceptions'
2
+ require 'spec/expectations/expectations'
3
+ require 'spec/expectations/should_base'
4
+ require 'spec/expectations/have_helper'
5
+ require 'spec/expectations/should_helper'
6
+ require 'spec/expectations/should_negator'
7
+ require 'spec/expectations/sugar'
@@ -0,0 +1,56 @@
1
+ begin
2
+ require 'rubygems'
3
+ require 'diff/lcs' #necessary to do loading bug on some machines - not sure why - DaC
4
+ require 'diff/lcs/hunk'
5
+ rescue LoadError
6
+ raise "You must gem install diff-lcs to use diffing"
7
+ end
8
+
9
+ module Spec
10
+ module Expectations
11
+ class ShouldBase
12
+ unless defined?(RSPEC_TESTING)
13
+ alias old_default_message default_message
14
+ def default_message(expectation, expected=:no_expectation_specified)
15
+ result = old_default_message(expectation, expected)
16
+ if expected.is_a?(String)
17
+ result << "\nDiff:" << diff_as_string(@target.to_s, expected)
18
+ end
19
+ result
20
+ end
21
+ end
22
+
23
+ # This is snagged from diff/lcs/ldiff.rb (which is a commandline tool)
24
+ def diff_as_string(data_old, data_new, format=:unified, context_lines=3)
25
+ data_old = data_old.split(/\n/).map! { |e| e.chomp }
26
+ data_new = data_new.split(/\n/).map! { |e| e.chomp }
27
+ output = ""
28
+ diffs = Diff::LCS.diff(data_old, data_new)
29
+ return output if diffs.empty?
30
+ oldhunk = hunk = nil
31
+ file_length_difference = 0
32
+ diffs.each do |piece|
33
+ begin
34
+ hunk = Diff::LCS::Hunk.new(data_old, data_new, piece, context_lines,
35
+ file_length_difference)
36
+ file_length_difference = hunk.file_length_difference
37
+ next unless oldhunk
38
+ # Hunks may overlap, which is why we need to be careful when our
39
+ # diff includes lines of context. Otherwise, we might print
40
+ # redundant lines.
41
+ if (context_lines > 0) and hunk.overlaps?(oldhunk)
42
+ hunk.unshift(oldhunk)
43
+ else
44
+ output << oldhunk.diff(format)
45
+ end
46
+ ensure
47
+ oldhunk = hunk
48
+ output << "\n"
49
+ end
50
+ end
51
+ #Handle the last remaining hunk
52
+ output << oldhunk.diff(format) << "\n"
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,6 @@
1
+ module Spec
2
+ module Expectations
3
+ class ExpectationNotMetError < StandardError
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,19 @@
1
+ module Spec
2
+ module Expectations
3
+ module ObjectExpectations
4
+ def should
5
+ ShouldHelper.new self
6
+ end
7
+ end
8
+ end
9
+ end
10
+
11
+ class Object
12
+ include Spec::Expectations::ObjectExpectations
13
+ end
14
+
15
+ class Numeric
16
+ def close?(other, precision)
17
+ (self - other).abs < precision
18
+ end
19
+ end
@@ -0,0 +1,41 @@
1
+ module Spec
2
+ module Expectations
3
+ class HaveHelper < ShouldBase
4
+
5
+ def initialize(target, relativity=:exactly, expected=nil)
6
+ @target = target
7
+ @expected = expected == :no ? 0 : expected
8
+ @at_least = (relativity == :at_least)
9
+ @at_most = (relativity == :at_most)
10
+ end
11
+
12
+ def method_missing(sym, *args)
13
+ fail_with_message(build_message(sym, args)) unless as_specified?(sym, args)
14
+ end
15
+
16
+ def collection(sym, args)
17
+ @target.send(sym, *args)
18
+ end
19
+
20
+ def actual_size(collection)
21
+ return collection.length if collection.respond_to? :length
22
+ return collection.size if collection.respond_to? :size
23
+ end
24
+
25
+ def build_message(sym, args)
26
+ message = "#{@target.inspect_for_expectation_not_met_error} should have"
27
+ message += " at least" if @at_least
28
+ message += " at most" if @at_most
29
+ message += " #{@expected} #{sym} (has #{actual_size(collection(sym, args))})"
30
+ end
31
+
32
+ def as_specified?(sym, args)
33
+ return actual_size(collection(sym, args)) >= @expected if @at_least
34
+ return actual_size(collection(sym, args)) <= @expected if @at_most
35
+ return actual_size(collection(sym, args)) == @expected
36
+ end
37
+
38
+ end
39
+ end
40
+
41
+ end
@@ -0,0 +1,4 @@
1
+ require 'spec/expectations/helper/should_base'
2
+ require 'spec/expectations/helper/have_helper'
3
+ require 'spec/expectations/helper/should_helper'
4
+ require 'spec/expectations/helper/should_negator'
@@ -0,0 +1,52 @@
1
+ class Symbol
2
+ def supported_by_rspec?
3
+ return ["<","<=",">=",">","==","=~"].include?(to_s)
4
+ end
5
+ end
6
+ class Object
7
+ def inspect_for_expectation_not_met_error
8
+ return "#{inspect}" if inspect.include? "<"
9
+ return "<#{inspect}>" unless inspect.include? "<"
10
+ end
11
+ end
12
+ class TrueClass; def inspect_for_expectation_not_met_error; "true" end end
13
+ class FalseClass; def inspect_for_expectation_not_met_error; "false" end end
14
+ class NilClass; def inspect_for_expectation_not_met_error; "nil" end end
15
+ class Class; def inspect_for_expectation_not_met_error; "<#{name}>" end end
16
+ class Proc; def inspect_for_expectation_not_met_error; "<Proc>" end end
17
+ class Array; def inspect_for_expectation_not_met_error; inspect end end
18
+ class String; def inspect_for_expectation_not_met_error; inspect end end
19
+ class Numeric; def inspect_for_expectation_not_met_error; inspect end end
20
+
21
+ module Spec
22
+ module Expectations
23
+ class ShouldBase
24
+
25
+ instance_methods.each { |m| undef_method m unless m =~ /^(__|\w)/ }
26
+
27
+ def default_message(expectation, expected=:no_expectation_specified)
28
+ message = "#{@target.inspect_for_expectation_not_met_error} #{expectation}"
29
+ if (expected != :no_expectation_specified)
30
+ message << " " << expected.inspect_for_expectation_not_met_error
31
+ end
32
+ message
33
+ end
34
+
35
+ def fail_with_message(message)
36
+ Kernel::raise(Spec::Expectations::ExpectationNotMetError.new(message))
37
+ end
38
+
39
+ def respond_to? sym
40
+ return true if super
41
+ return true if @target.respond_to? "#{sym.to_s}?"
42
+ end
43
+
44
+ def find_supported_sym(original_sym)
45
+ ["#{original_sym}?", "#{original_sym}s?"].each do |alternate_sym|
46
+ return alternate_sym.to_s if @target.respond_to?(alternate_sym.to_s)
47
+ end
48
+ return original_sym.supported_by_rspec? ? original_sym : "#{original_sym}?"
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,93 @@
1
+ module Spec
2
+ module Expectations
3
+ class ShouldHelper < ShouldBase
4
+
5
+ def initialize(target)
6
+ @target = target
7
+ @be_seen = false
8
+ end
9
+
10
+ def not
11
+ ShouldNegator.new(@target)
12
+ end
13
+
14
+ def have(expected_number=nil)
15
+ HaveHelper.new(@target, :exactly, expected_number)
16
+ end
17
+
18
+ def have_exactly(expected_number=nil)
19
+ HaveHelper.new(@target, :exactly, expected_number)
20
+ end
21
+
22
+ def have_at_least(expected_number=nil)
23
+ HaveHelper.new(@target, :at_least, expected_number)
24
+ end
25
+
26
+ def have_at_most(expected_number=nil)
27
+ HaveHelper.new(@target, :at_most, expected_number)
28
+ end
29
+
30
+ def satisfy(&block)
31
+ return if block.call(@target)
32
+ fail_with_message "Supplied expectation was not satisfied"
33
+ end
34
+
35
+ def equal(expected)
36
+ fail_with_message(default_message("should equal", expected)) unless (@target == expected)
37
+ end
38
+
39
+ def be(expected = :___no_arg)
40
+ @be_seen = true
41
+ return self if (expected == :___no_arg)
42
+ return if (expected == false and @target.nil?)
43
+ return if (expected == true and (!@target.nil?) and (@target != false))
44
+ fail_with_message(default_message("should be", expected)) unless (@target.equal?(expected))
45
+ end
46
+
47
+ def an_instance_of expected_class
48
+ fail_with_message(default_message("should be an instance of", expected_class)) unless @target.instance_of? expected_class
49
+ end
50
+
51
+ def a_kind_of expected_class
52
+ fail_with_message(default_message("should be a kind of", expected_class)) unless @target.kind_of? expected_class
53
+ end
54
+
55
+ def respond_to message
56
+ fail_with_message(default_message("should respond to", message)) unless @target.respond_to? message
57
+ end
58
+
59
+ def method_missing(original_sym, *args)
60
+ actual_sym = find_supported_sym(original_sym)
61
+ return if @target.send(actual_sym, *args)
62
+ fail_with_message(default_message("should#{@be_seen ? ' be' : ''} #{original_sym}" + (args.empty? ? '' : (' ' + args.join(', ')))))
63
+ end
64
+
65
+ def match(expected)
66
+ fail_with_message(default_message("should match", expected)) unless (@target =~ expected)
67
+ end
68
+
69
+ def raise(exception=Exception, message=nil)
70
+ begin
71
+ @target.call
72
+ rescue exception => e
73
+ e.message.should_equal message unless message.nil?
74
+ return
75
+ rescue => e
76
+ fail_with_message("#{default_message("should raise", exception)} but raised #{e.inspect}")
77
+ end
78
+ fail_with_message("#{default_message("should raise", exception)} but raised nothing")
79
+ end
80
+
81
+ def throw(symbol)
82
+ begin
83
+ catch symbol do
84
+ @target.call
85
+ fail_with_message(default_message("should throw", symbol.inspect))
86
+ end
87
+ rescue NameError
88
+ fail_with_message(default_message("should throw", symbol.inspect))
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end