mspec 1.5.17 → 1.5.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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