mspec 1.5.17 → 1.5.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (174) hide show
  1. data/.gitignore +27 -0
  2. data/Gemfile +4 -0
  3. data/README +39 -159
  4. data/Rakefile +4 -44
  5. data/bin/mkspec.bat +1 -0
  6. data/bin/mspec-ci.bat +1 -0
  7. data/bin/mspec-run.bat +1 -0
  8. data/bin/mspec-tag.bat +1 -0
  9. data/bin/mspec.bat +1 -0
  10. data/lib/mspec/commands/mkspec.rb +2 -2
  11. data/lib/mspec/commands/mspec-run.rb +4 -0
  12. data/lib/mspec/commands/mspec.rb +18 -3
  13. data/lib/mspec/guards.rb +1 -0
  14. data/lib/mspec/guards/block_device.rb +22 -0
  15. data/lib/mspec/guards/guard.rb +14 -2
  16. data/lib/mspec/helpers.rb +5 -5
  17. data/lib/mspec/helpers/const_lookup.rb +6 -1
  18. data/lib/mspec/helpers/datetime.rb +28 -0
  19. data/lib/mspec/helpers/ducktype.rb +4 -4
  20. data/lib/mspec/helpers/environment.rb +19 -2
  21. data/lib/mspec/helpers/fs.rb +5 -1
  22. data/lib/mspec/helpers/io.rb +39 -1
  23. data/lib/mspec/helpers/numeric.rb +89 -0
  24. data/lib/mspec/helpers/pack.rb +3 -0
  25. data/lib/mspec/helpers/ruby_exe.rb +53 -15
  26. data/lib/mspec/helpers/singleton_class.rb +7 -0
  27. data/lib/mspec/helpers/stasy.rb +33 -0
  28. data/lib/mspec/helpers/tmp.rb +16 -3
  29. data/lib/mspec/matchers.rb +8 -0
  30. data/lib/mspec/matchers/be_computed_by.rb +37 -0
  31. data/lib/mspec/matchers/be_computed_by_function.rb +35 -0
  32. data/lib/mspec/matchers/be_nan.rb +20 -0
  33. data/lib/mspec/matchers/be_valid_dns_name.rb +25 -0
  34. data/lib/mspec/matchers/have_data.rb +6 -5
  35. data/lib/mspec/matchers/have_private_method.rb +24 -0
  36. data/lib/mspec/matchers/have_singleton_method.rb +24 -0
  37. data/lib/mspec/matchers/infinity.rb +28 -0
  38. data/lib/mspec/matchers/match_yaml.rb +5 -5
  39. data/lib/mspec/matchers/raise_error.rb +5 -3
  40. data/lib/mspec/matchers/signed_zero.rb +28 -0
  41. data/lib/mspec/mocks/mock.rb +15 -9
  42. data/lib/mspec/mocks/object.rb +4 -0
  43. data/lib/mspec/mocks/proxy.rb +26 -1
  44. data/lib/mspec/runner/actions.rb +0 -1
  45. data/lib/mspec/runner/context.rb +18 -16
  46. data/lib/mspec/runner/formatters.rb +2 -0
  47. data/lib/mspec/runner/formatters/dotted.rb +13 -1
  48. data/lib/mspec/runner/formatters/junit.rb +96 -0
  49. data/lib/mspec/runner/formatters/profile.rb +70 -0
  50. data/lib/mspec/runner/mspec.rb +11 -0
  51. data/lib/mspec/runner/shared.rb +1 -1
  52. data/lib/mspec/utils/options.rb +33 -9
  53. data/lib/mspec/utils/ruby_name.rb +1 -1
  54. data/lib/mspec/utils/script.rb +2 -1
  55. data/lib/mspec/version.rb +1 -1
  56. data/mspec.gemspec +40 -0
  57. data/spec/commands/mkspec_spec.rb +4 -3
  58. data/spec/commands/mspec_ci_spec.rb +1 -6
  59. data/spec/commands/mspec_run_spec.rb +1 -6
  60. data/spec/commands/mspec_spec.rb +14 -6
  61. data/spec/commands/mspec_tag_spec.rb +28 -27
  62. data/spec/expectations/expectations_spec.rb +1 -1
  63. data/spec/expectations/should_spec.rb +4 -4
  64. data/spec/guards/background_spec.rb +2 -2
  65. data/spec/guards/block_device_spec.rb +46 -0
  66. data/spec/guards/bug_spec.rb +2 -3
  67. data/spec/guards/compliance_spec.rb +2 -2
  68. data/spec/guards/conflict_spec.rb +2 -2
  69. data/spec/guards/endian_spec.rb +2 -2
  70. data/spec/guards/extensions_spec.rb +2 -2
  71. data/spec/guards/feature_spec.rb +2 -2
  72. data/spec/guards/guard_spec.rb +80 -22
  73. data/spec/guards/noncompliance_spec.rb +2 -2
  74. data/spec/guards/platform_spec.rb +2 -2
  75. data/spec/guards/quarantine_spec.rb +2 -2
  76. data/spec/guards/runner_spec.rb +2 -2
  77. data/spec/guards/specified_spec.rb +2 -2
  78. data/spec/guards/superuser_spec.rb +2 -2
  79. data/spec/guards/support_spec.rb +2 -2
  80. data/spec/guards/tty_spec.rb +2 -2
  81. data/spec/guards/user_spec.rb +2 -2
  82. data/spec/guards/version_spec.rb +2 -2
  83. data/spec/helpers/argv_spec.rb +3 -2
  84. data/spec/helpers/const_lookup_spec.rb +3 -2
  85. data/spec/helpers/datetime_spec.rb +44 -0
  86. data/spec/helpers/ducktype_spec.rb +3 -2
  87. data/spec/helpers/encode_spec.rb +3 -2
  88. data/spec/helpers/enumerator_class_spec.rb +5 -5
  89. data/spec/helpers/environment_spec.rb +15 -3
  90. data/spec/helpers/fixture_spec.rb +3 -2
  91. data/spec/helpers/flunk_spec.rb +4 -3
  92. data/spec/helpers/fs_spec.rb +35 -18
  93. data/spec/helpers/hash_spec.rb +3 -2
  94. data/spec/helpers/io_spec.rb +75 -6
  95. data/spec/helpers/language_version_spec.rb +3 -2
  96. data/spec/helpers/mock_to_path_spec.rb +3 -2
  97. data/spec/helpers/numeric_spec.rb +25 -0
  98. data/spec/helpers/ruby_exe_spec.rb +115 -29
  99. data/spec/helpers/scratch_spec.rb +3 -1
  100. data/spec/helpers/stasy_spec.rb +59 -0
  101. data/spec/helpers/tmp_spec.rb +21 -4
  102. data/spec/matchers/base_spec.rb +2 -2
  103. data/spec/matchers/be_an_instance_of_spec.rb +2 -2
  104. data/spec/matchers/be_ancestor_of_spec.rb +2 -2
  105. data/spec/matchers/be_close_spec.rb +2 -2
  106. data/spec/matchers/be_computed_by_function_spec.rb +36 -0
  107. data/spec/matchers/be_computed_by_spec.rb +42 -0
  108. data/spec/matchers/be_empty_spec.rb +2 -2
  109. data/spec/matchers/be_false_spec.rb +3 -3
  110. data/spec/matchers/be_kind_of_spec.rb +2 -2
  111. data/spec/matchers/be_nan_spec.rb +28 -0
  112. data/spec/matchers/be_nil_spec.rb +3 -3
  113. data/spec/matchers/be_true_spec.rb +3 -3
  114. data/spec/matchers/be_valid_dns_name_spec.rb +50 -0
  115. data/spec/matchers/complain_spec.rb +2 -2
  116. data/spec/matchers/eql_spec.rb +2 -2
  117. data/spec/matchers/equal_element_spec.rb +2 -2
  118. data/spec/matchers/equal_spec.rb +2 -2
  119. data/spec/matchers/equal_utf16_spec.rb +2 -2
  120. data/spec/matchers/have_class_variable_spec.rb +3 -3
  121. data/spec/matchers/have_constant_spec.rb +2 -2
  122. data/spec/matchers/have_data_spec.rb +8 -5
  123. data/spec/matchers/have_instance_method_spec.rb +2 -2
  124. data/spec/matchers/have_instance_variable_spec.rb +3 -3
  125. data/spec/matchers/have_method_spec.rb +2 -2
  126. data/spec/matchers/have_private_instance_method_spec.rb +3 -3
  127. data/spec/matchers/have_private_method_spec.rb +44 -0
  128. data/spec/matchers/have_protected_instance_method_spec.rb +2 -2
  129. data/spec/matchers/have_public_instance_method_spec.rb +2 -2
  130. data/spec/matchers/have_singleton_method_spec.rb +45 -0
  131. data/spec/matchers/include_spec.rb +2 -2
  132. data/spec/matchers/infinity_spec.rb +34 -0
  133. data/spec/matchers/match_yaml_spec.rb +3 -3
  134. data/spec/matchers/output_spec.rb +2 -2
  135. data/spec/matchers/output_to_fd_spec.rb +2 -2
  136. data/spec/matchers/raise_error_spec.rb +24 -3
  137. data/spec/matchers/respond_to_spec.rb +2 -2
  138. data/spec/matchers/signed_zero_spec.rb +32 -0
  139. data/spec/matchers/stringsymboladapter_spec.rb +2 -2
  140. data/spec/mocks/mock_spec.rb +12 -12
  141. data/spec/mocks/proxy_spec.rb +1 -1
  142. data/spec/runner/actions/gdb_spec.rb +1 -1
  143. data/spec/runner/actions/tag_spec.rb +1 -1
  144. data/spec/runner/actions/taglist_spec.rb +1 -1
  145. data/spec/runner/context_spec.rb +27 -27
  146. data/spec/runner/example_spec.rb +1 -1
  147. data/spec/runner/exception_spec.rb +1 -1
  148. data/spec/runner/filters/tag_spec.rb +2 -2
  149. data/spec/runner/formatters/describe_spec.rb +1 -1
  150. data/spec/runner/formatters/dotted_spec.rb +2 -2
  151. data/spec/runner/formatters/html_spec.rb +2 -2
  152. data/spec/runner/formatters/junit_spec.rb +147 -0
  153. data/spec/runner/formatters/unit_spec.rb +2 -2
  154. data/spec/runner/formatters/yaml_spec.rb +3 -3
  155. data/spec/runner/mspec_spec.rb +22 -21
  156. data/spec/runner/shared_spec.rb +9 -1
  157. data/spec/runner/tag_spec.rb +1 -1
  158. data/spec/spec_helper.rb +1 -7
  159. data/spec/utils/name_map_spec.rb +1 -2
  160. data/spec/utils/options_spec.rb +58 -27
  161. data/spec/utils/script_spec.rb +5 -13
  162. data/spec/utils/version_spec.rb +1 -1
  163. metadata +254 -64
  164. data/lib/mspec/helpers/bignum.rb +0 -5
  165. data/lib/mspec/helpers/fmode.rb +0 -15
  166. data/lib/mspec/helpers/infinity.rb +0 -5
  167. data/lib/mspec/helpers/metaclass.rb +0 -7
  168. data/lib/mspec/helpers/nan.rb +0 -5
  169. data/lib/mspec/runner/actions/debug.rb +0 -17
  170. data/spec/helpers/bignum_spec.rb +0 -11
  171. data/spec/helpers/fmode_spec.rb +0 -14
  172. data/spec/helpers/infinity_spec.rb +0 -8
  173. data/spec/helpers/nan_spec.rb +0 -8
  174. data/spec/runner/actions/debug_spec.rb +0 -62
@@ -0,0 +1,7 @@
1
+ class Object
2
+ unless method_defined? :singleton_class
3
+ def singleton_class
4
+ class << self; self; end
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,33 @@
1
+ require 'mspec/utils/version'
2
+ require 'mspec/guards/guard'
3
+
4
+ class Object
5
+ # Accepts either a single argument or an Array of arguments. If RUBY_VERSION
6
+ # is less than 1.9, converts the argument(s) to Strings; otherwise, converts
7
+ # the argument(s) to Symbols.
8
+ #
9
+ # If one argument is passed, the converted argument is returned. If an Array
10
+ # is passed, an Array is returned.
11
+ #
12
+ # For example, if RUBY_VERSION == 1.8.7
13
+ #
14
+ # stasy(:some) => "some"
15
+ # stasy("nom") => "nom"
16
+ #
17
+ # while if RUBY_VERSION == 1.9.0
18
+ #
19
+ # stasy(:some) => :some
20
+ # stasy("nom") => :nom
21
+
22
+ def stasy(one, *rest)
23
+ era = SpecVersion.new(SpecGuard.ruby_version) < "1.9"
24
+ convert = era ? :to_s : :to_sym
25
+
26
+ one = one.send convert
27
+ if rest.empty?
28
+ one
29
+ else
30
+ [one].concat rest.map { |x| x.send convert }
31
+ end
32
+ end
33
+ end
@@ -5,15 +5,22 @@
5
5
 
6
6
  SPEC_TEMP_DIR = "#{File.expand_path(Dir.pwd)}/rubyspec_temp"
7
7
 
8
+ SPEC_TEMP_UNIQUIFIER = "0"
9
+
10
+ SPEC_TMEM_DIR_PID = Process.pid
11
+
8
12
  at_exit do
9
13
  begin
10
- Dir.delete SPEC_TEMP_DIR if File.directory? SPEC_TEMP_DIR
14
+ if SPEC_TMEM_DIR_PID == Process.pid
15
+ Dir.delete SPEC_TEMP_DIR if File.directory? SPEC_TEMP_DIR
16
+ end
11
17
  rescue SystemCallError
12
18
  STDERR.puts <<-EOM
13
19
 
14
20
  -----------------------------------------------------
15
21
  The rubyspec temp directory is not empty. Ensure that
16
- all specs are cleaning up temporary files.
22
+ all specs are cleaning up temporary files:
23
+ #{SPEC_TEMP_DIR}
17
24
  -----------------------------------------------------
18
25
 
19
26
  EOM
@@ -24,9 +31,15 @@ all specs are cleaning up temporary files.
24
31
  end
25
32
 
26
33
  class Object
27
- def tmp(name)
34
+ def tmp(name, uniquify=true)
28
35
  Dir.mkdir SPEC_TEMP_DIR unless File.exists? SPEC_TEMP_DIR
29
36
 
37
+ if uniquify and !name.empty?
38
+ slash = name.rindex "/"
39
+ index = slash ? slash + 1 : 0
40
+ name.insert index, "#{SPEC_TEMP_UNIQUIFIER.succ!}-"
41
+ end
42
+
30
43
  File.join SPEC_TEMP_DIR, name
31
44
  end
32
45
  end
@@ -2,11 +2,15 @@ require 'mspec/matchers/base'
2
2
  require 'mspec/matchers/be_an_instance_of'
3
3
  require 'mspec/matchers/be_ancestor_of'
4
4
  require 'mspec/matchers/be_close'
5
+ require 'mspec/matchers/be_computed_by'
6
+ require 'mspec/matchers/be_computed_by_function'
5
7
  require 'mspec/matchers/be_empty'
6
8
  require 'mspec/matchers/be_false'
7
9
  require 'mspec/matchers/be_kind_of'
10
+ require 'mspec/matchers/be_nan'
8
11
  require 'mspec/matchers/be_nil'
9
12
  require 'mspec/matchers/be_true'
13
+ require 'mspec/matchers/be_valid_dns_name'
10
14
  require 'mspec/matchers/complain'
11
15
  require 'mspec/matchers/eql'
12
16
  require 'mspec/matchers/equal'
@@ -19,11 +23,15 @@ require 'mspec/matchers/have_instance_method'
19
23
  require 'mspec/matchers/have_instance_variable'
20
24
  require 'mspec/matchers/have_method'
21
25
  require 'mspec/matchers/have_private_instance_method'
26
+ require 'mspec/matchers/have_private_method'
22
27
  require 'mspec/matchers/have_protected_instance_method'
23
28
  require 'mspec/matchers/have_public_instance_method'
29
+ require 'mspec/matchers/have_singleton_method'
24
30
  require 'mspec/matchers/include'
31
+ require 'mspec/matchers/infinity'
25
32
  require 'mspec/matchers/match_yaml'
26
33
  require 'mspec/matchers/raise_error'
27
34
  require 'mspec/matchers/output'
28
35
  require 'mspec/matchers/output_to_fd'
29
36
  require 'mspec/matchers/respond_to'
37
+ require 'mspec/matchers/signed_zero'
@@ -0,0 +1,37 @@
1
+ class BeComputedByMatcher
2
+ def initialize(sym, *args)
3
+ @method = sym
4
+ @args = args
5
+ end
6
+
7
+ def matches?(array)
8
+ array.each do |line|
9
+ @receiver = line.shift
10
+ @value = line.pop
11
+ @arguments = line
12
+ @arguments += @args
13
+ @actual = @receiver.send(@method, *@arguments)
14
+ return false unless @actual == @value
15
+ end
16
+
17
+ return true
18
+ end
19
+
20
+ def method_call
21
+ method_call = "#{@receiver.inspect}.#{@method}"
22
+ unless @arguments.empty?
23
+ method_call << " from #{@arguments.map { |x| x.inspect }.join(", ")}"
24
+ end
25
+ method_call
26
+ end
27
+
28
+ def failure_message
29
+ ["Expected #{@value.inspect}", "to be computed by #{method_call} (computed #{@actual.inspect} instead)"]
30
+ end
31
+ end
32
+
33
+ class Object
34
+ def be_computed_by(sym, *args)
35
+ BeComputedByMatcher.new(sym, *args)
36
+ end
37
+ end
@@ -0,0 +1,35 @@
1
+ class BeComputedByFunctionMatcher
2
+ def initialize(sym, *args)
3
+ @function = sym
4
+ @args = args
5
+ end
6
+
7
+ def matches?(array)
8
+ array.each do |line|
9
+ @value = line.pop
10
+ @arguments = line
11
+ @arguments += @args
12
+ return false unless send(@function, *@arguments) == @value
13
+ end
14
+
15
+ return true
16
+ end
17
+
18
+ def function_call
19
+ function_call = "#{@function}"
20
+ unless @arguments.empty?
21
+ function_call << "(#{@arguments.map { |x| x.inspect }.join(", ")})"
22
+ end
23
+ function_call
24
+ end
25
+
26
+ def failure_message
27
+ ["Expected #{@value.inspect}", "to be computed by #{function_call}"]
28
+ end
29
+ end
30
+
31
+ class Object
32
+ def be_computed_by_function(sym, *args)
33
+ BeComputedByFunctionMatcher.new(sym, *args)
34
+ end
35
+ end
@@ -0,0 +1,20 @@
1
+ class BeNaNMatcher
2
+ def matches?(actual)
3
+ @actual = actual
4
+ @actual.kind_of?(Float) && @actual.nan?
5
+ end
6
+
7
+ def failure_message
8
+ ["Expected #{@actual}", "to be NaN"]
9
+ end
10
+
11
+ def negative_failure_message
12
+ ["Expected #{@actual}", "not to be NaN"]
13
+ end
14
+ end
15
+
16
+ class Object
17
+ def be_nan
18
+ BeNaNMatcher.new
19
+ end
20
+ end
@@ -0,0 +1,25 @@
1
+ class BeValidDNSName
2
+ # http://stackoverflow.com/questions/106179/regular-expression-to-match-hostname-or-ip-address
3
+ # ftp://ftp.rfc-editor.org/in-notes/rfc3696.txt
4
+ # http://domainkeys.sourceforge.net/underscore.html
5
+ VALID_DNS = /^(([a-zA-Z0-9_]|[a-zA-Z0-9_][a-zA-Z0-9\-_]*[a-zA-Z0-9_])\.)*([A-Za-z_]|[A-Za-z_][A-Za-z0-9\-_]*[A-Za-z0-9_])\.?$/
6
+
7
+ def matches?(actual)
8
+ @actual = actual
9
+ (VALID_DNS =~ @actual) == 0
10
+ end
11
+
12
+ def failure_message
13
+ ["Expected '#{@actual}'", "to be a valid DNS name"]
14
+ end
15
+
16
+ def negative_failure_message
17
+ ["Expected '#{@actual}'", "not to be a valid DNS name"]
18
+ end
19
+ end
20
+
21
+ class Object
22
+ def be_valid_DNS_name
23
+ BeValidDNSName.new
24
+ end
25
+ end
@@ -1,9 +1,10 @@
1
1
  require 'mspec/guards/feature'
2
- require 'mspec/helpers/fmode'
2
+ require 'mspec/helpers/io'
3
3
 
4
4
  class HaveDataMatcher
5
- def initialize(data)
5
+ def initialize(data, mode="rb:binary")
6
6
  @data = data
7
+ @mode = mode
7
8
  end
8
9
 
9
10
  def matches?(name)
@@ -15,7 +16,7 @@ class HaveDataMatcher
15
16
  size = @data.size
16
17
  end
17
18
 
18
- File.open @name, fmode("rb:binary") do |f|
19
+ File.open @name, fmode(@mode) do |f|
19
20
  return f.read(size) == @data
20
21
  end
21
22
  end
@@ -42,7 +43,7 @@ class Object
42
43
  # passes if the file @name has "123" as the first 3 bytes. The
43
44
  # file can contain more bytes than +data+. The extra bytes do not
44
45
  # affect the result.
45
- def have_data(data)
46
- HaveDataMatcher.new(data)
46
+ def have_data(data, mode="rb:binary")
47
+ HaveDataMatcher.new(data, mode)
47
48
  end
48
49
  end
@@ -0,0 +1,24 @@
1
+ require 'mspec/matchers/method'
2
+
3
+ class HavePrivateMethodMatcher < MethodMatcher
4
+ def matches?(mod)
5
+ @mod = mod
6
+ mod.private_methods(@include_super).include? @method
7
+ end
8
+
9
+ def failure_message
10
+ ["Expected #{@mod} to have private method '#{@method.to_s}'",
11
+ "but it does not"]
12
+ end
13
+
14
+ def negative_failure_message
15
+ ["Expected #{@mod} NOT to have private method '#{@method.to_s}'",
16
+ "but it does"]
17
+ end
18
+ end
19
+
20
+ class Object
21
+ def have_private_method(method, include_super=true)
22
+ HavePrivateMethodMatcher.new method, include_super
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ require 'mspec/matchers/method'
2
+
3
+ class HaveSingletonMethodMatcher < MethodMatcher
4
+ def matches?(obj)
5
+ @obj = obj
6
+ obj.singleton_methods(@include_super).include? @method
7
+ end
8
+
9
+ def failure_message
10
+ ["Expected #{@obj} to have singleton method '#{@method.to_s}'",
11
+ "but it does not"]
12
+ end
13
+
14
+ def negative_failure_message
15
+ ["Expected #{@obj} NOT to have singleton method '#{@method.to_s}'",
16
+ "but it does"]
17
+ end
18
+ end
19
+
20
+ class Object
21
+ def have_singleton_method(method, include_super=true)
22
+ HaveSingletonMethodMatcher.new method, include_super
23
+ end
24
+ end
@@ -0,0 +1,28 @@
1
+ class InfinityMatcher
2
+ def initialize(expected_sign)
3
+ @expected_sign = expected_sign
4
+ end
5
+
6
+ def matches?(actual)
7
+ @actual = actual
8
+ @actual.kind_of?(Float) && @actual.infinite? == @expected_sign
9
+ end
10
+
11
+ def failure_message
12
+ ["Expected #{@actual}", "to be #{"-" if @expected_sign == -1}Infinity"]
13
+ end
14
+
15
+ def negative_failure_message
16
+ ["Expected #{@actual}", "not to be #{"-" if @expected_sign == -1}Infinity"]
17
+ end
18
+ end
19
+
20
+ class Object
21
+ def be_positive_infinity
22
+ InfinityMatcher.new(1)
23
+ end
24
+
25
+ def be_negative_infinity
26
+ InfinityMatcher.new(-1)
27
+ end
28
+ end
@@ -9,8 +9,8 @@ class MatchYAMLMatcher
9
9
  end
10
10
 
11
11
  def matches?(actual)
12
- @actual = actual
13
- clean_yaml(@actual) == @expected
12
+ @actual = actual
13
+ clean_yaml(@actual) == clean_yaml(@expected)
14
14
  end
15
15
 
16
16
  def failure_message
@@ -20,11 +20,11 @@ class MatchYAMLMatcher
20
20
  def negative_failure_message
21
21
  ["Expected #{@actual.inspect}", " to match #{@expected.inspect}"]
22
22
  end
23
-
23
+
24
24
  protected
25
-
25
+
26
26
  def clean_yaml(yaml)
27
- yaml.gsub(/([^-])\s+\n/, "\\1\n")
27
+ yaml.gsub(/([^-]|^---)\s+\n/, "\\1\n").sub(/\n\.\.\.\n$/, "\n")
28
28
  end
29
29
 
30
30
  def valid_yaml?(obj)
@@ -6,7 +6,7 @@ class RaiseErrorMatcher
6
6
  end
7
7
 
8
8
  def matches?(proc)
9
- proc.call
9
+ @result = proc.call
10
10
  return false
11
11
  rescue Exception => @actual
12
12
  return false unless @exception === @actual
@@ -30,14 +30,16 @@ class RaiseErrorMatcher
30
30
  if @actual then
31
31
  message << "but got #{@actual.class}#{%[ (#{@actual.message})] if @actual.message}"
32
32
  else
33
- message << "but no exception was raised"
33
+ message << "but no exception was raised (#@result was returned)"
34
34
  end
35
35
 
36
36
  message
37
37
  end
38
38
 
39
39
  def negative_failure_message
40
- ["Expected to not get #{@exception}#{%[ (#{@message})] if @message}", ""]
40
+ message = ["Expected to not get #{@exception}#{%[ (#{@message})] if @message}", ""]
41
+ message[1] = "but got #{@actual.class}#{%[ (#{@actual.message})] if @actual.message}" unless @actual.class == @exception
42
+ message
41
43
  end
42
44
  end
43
45
 
@@ -0,0 +1,28 @@
1
+ class SignedZeroMatcher
2
+ def initialize(expected_sign)
3
+ @expected_sign = expected_sign
4
+ end
5
+
6
+ def matches?(actual)
7
+ @actual = actual
8
+ (1.0/actual).infinite? == @expected_sign
9
+ end
10
+
11
+ def failure_message
12
+ ["Expected #{@actual}", "to be #{"-" if @expected_sign == -1}0.0"]
13
+ end
14
+
15
+ def negative_failure_message
16
+ ["Expected #{@actual}", "not to be #{"-" if @expected_sign == -1}0.0"]
17
+ end
18
+ end
19
+
20
+ class Object
21
+ def be_positive_zero
22
+ SignedZeroMatcher.new(1)
23
+ end
24
+
25
+ def be_negative_zero
26
+ SignedZeroMatcher.new(-1)
27
+ end
28
+ end
@@ -1,5 +1,5 @@
1
1
  require 'mspec/expectations/expectations'
2
- require 'mspec/helpers/metaclass'
2
+ require 'mspec/helpers/singleton_class'
3
3
 
4
4
  class Object
5
5
  alias_method :__mspec_object_id__, :object_id
@@ -43,22 +43,22 @@ module Mock
43
43
  stubs.delete key
44
44
  end
45
45
 
46
- def self.mock_respond_to?(obj, sym)
46
+ def self.mock_respond_to?(obj, sym, include_private = false)
47
47
  name = replaced_name(obj, :respond_to?)
48
48
  if replaced? name
49
- obj.__send__ name, sym
49
+ obj.__send__ name, sym, include_private
50
50
  else
51
- obj.respond_to? sym
51
+ obj.respond_to? sym, include_private
52
52
  end
53
53
  end
54
54
 
55
55
  def self.install_method(obj, sym, type=nil)
56
- meta = obj.metaclass
56
+ meta = obj.singleton_class
57
57
 
58
58
  key = replaced_key obj, sym
59
59
  sym = sym.to_sym
60
60
 
61
- if (sym == :respond_to? or mock_respond_to?(obj, sym)) and !replaced?(key.first)
61
+ if (sym == :respond_to? or mock_respond_to?(obj, sym, true)) and !replaced?(key.first)
62
62
  meta.__send__ :alias_method, key.first, sym
63
63
  end
64
64
 
@@ -118,7 +118,8 @@ module Mock
118
118
 
119
119
  def self.verify_call(obj, sym, *args, &block)
120
120
  compare = *args
121
- if (behaves_like_ruby_1_9 = *[])
121
+ behaves_like_ruby_1_9 = *[]
122
+ if (behaves_like_ruby_1_9)
122
123
  compare = compare.first if compare.length <= 1
123
124
  end
124
125
 
@@ -176,11 +177,16 @@ module Mock
176
177
 
177
178
  def self.cleanup
178
179
  objects.each do |key, obj|
180
+ if obj.kind_of? MockIntObject
181
+ clear_replaced key
182
+ next
183
+ end
184
+
179
185
  replaced = key.first
180
186
  sym = key.last
181
- meta = obj.metaclass
187
+ meta = obj.singleton_class
182
188
 
183
- if mock_respond_to? obj, replaced
189
+ if mock_respond_to? obj, replaced, true
184
190
  meta.__send__ :alias_method, sym, replaced
185
191
  meta.__send__ :remove_method, replaced
186
192
  else