mspec 1.5.11 → 1.5.12

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 (45) hide show
  1. data/Rakefile +1 -1
  2. data/lib/mspec/commands/mspec-ci.rb +1 -0
  3. data/lib/mspec/commands/mspec-run.rb +1 -0
  4. data/lib/mspec/commands/mspec-tag.rb +1 -0
  5. data/lib/mspec/helpers.rb +4 -0
  6. data/lib/mspec/helpers/ducktype.rb +33 -0
  7. data/lib/mspec/helpers/enumerator_class.rb +9 -0
  8. data/lib/mspec/helpers/environment.rb +10 -1
  9. data/lib/mspec/helpers/hash.rb +27 -0
  10. data/lib/mspec/helpers/io.rb +4 -0
  11. data/lib/mspec/helpers/metaclass.rb +7 -0
  12. data/lib/mspec/matchers.rb +5 -0
  13. data/lib/mspec/matchers/have_class_variable.rb +12 -0
  14. data/lib/mspec/matchers/have_constant.rb +6 -24
  15. data/lib/mspec/matchers/have_instance_variable.rb +12 -0
  16. data/lib/mspec/matchers/have_protected_instance_method.rb +24 -0
  17. data/lib/mspec/matchers/have_public_instance_method.rb +24 -0
  18. data/lib/mspec/matchers/stringsymboladapter.rb +1 -1
  19. data/lib/mspec/matchers/variable.rb +28 -0
  20. data/lib/mspec/mocks/mock.rb +70 -47
  21. data/lib/mspec/mocks/object.rb +4 -0
  22. data/lib/mspec/mocks/proxy.rb +17 -3
  23. data/lib/mspec/runner.rb +1 -0
  24. data/lib/mspec/runner/exception.rb +4 -3
  25. data/lib/mspec/utils/options.rb +10 -2
  26. data/lib/mspec/version.rb +1 -1
  27. data/spec/commands/mkspec_spec.rb +1 -1
  28. data/spec/commands/mspec_ci_spec.rb +5 -0
  29. data/spec/commands/mspec_run_spec.rb +5 -0
  30. data/spec/commands/mspec_spec.rb +2 -2
  31. data/spec/commands/mspec_tag_spec.rb +5 -0
  32. data/spec/expectations/should.rb +1 -0
  33. data/spec/helpers/ducktype_spec.rb +44 -0
  34. data/spec/helpers/enumerator_class_spec.rb +19 -0
  35. data/spec/helpers/hash_spec.rb +30 -0
  36. data/spec/helpers/io_spec.rb +5 -0
  37. data/spec/matchers/have_class_variable_spec.rb +75 -0
  38. data/spec/matchers/have_instance_variable_spec.rb +75 -0
  39. data/spec/matchers/have_protected_instance_method_spec.rb +57 -0
  40. data/spec/matchers/have_public_instance_method_spec.rb +53 -0
  41. data/spec/matchers/stringsymboladapter_spec.rb +8 -10
  42. data/spec/mocks/mock_spec.rb +5 -5
  43. data/spec/runner/exception_spec.rb +17 -10
  44. data/spec/utils/options_spec.rb +26 -0
  45. metadata +18 -2
@@ -17,4 +17,8 @@ class Object
17
17
  def mock(name, options={})
18
18
  MockObject.new name, options
19
19
  end
20
+
21
+ def mock_numeric(name, options={})
22
+ NumericMockObject.new name, options
23
+ end
20
24
  end
@@ -9,6 +9,20 @@ class MockObject
9
9
  end
10
10
  end
11
11
 
12
+ class NumericMockObject < Numeric
13
+ def initialize(name, options={})
14
+ @name = name
15
+ @null = options[:null_object]
16
+ end
17
+
18
+ def method_missing(sym, *args, &block)
19
+ @null ? self : super
20
+ end
21
+
22
+ def singleton_method_added(val)
23
+ end
24
+ end
25
+
12
26
  class MockProxy
13
27
  def initialize(type=nil)
14
28
  @multiple_returns = nil
@@ -88,7 +102,7 @@ class MockProxy
88
102
  def with(*args)
89
103
  raise ArgumentError, "you must specify the expected arguments" if args.empty?
90
104
  @arguments = *args
91
- if RUBY_VERSION >= '1.9'
105
+ if (behaves_like_ruby_1_9 = *[])
92
106
  @arguments = @arguments.first if @arguments.length <= 1
93
107
  end
94
108
  self
@@ -112,11 +126,11 @@ class MockProxy
112
126
  @yielding << args
113
127
  self
114
128
  end
115
-
129
+
116
130
  def yielding
117
131
  @yielding
118
132
  end
119
-
133
+
120
134
  def yielding?
121
135
  !@yielding.empty?
122
136
  end
data/lib/mspec/runner.rb CHANGED
@@ -2,6 +2,7 @@ require 'mspec/mocks'
2
2
  require 'mspec/runner/mspec'
3
3
  require 'mspec/runner/context'
4
4
  require 'mspec/runner/example'
5
+ require 'mspec/runner/exception'
5
6
  require 'mspec/runner/object'
6
7
  require 'mspec/runner/formatters'
7
8
  require 'mspec/runner/actions'
@@ -1,8 +1,6 @@
1
1
  class ExceptionState
2
2
  attr_reader :description, :describe, :it, :exception
3
3
 
4
- PATH = /#{File.expand_path(File.dirname(__FILE__) + '/../../..')}/
5
-
6
4
  def initialize(state, location, exception)
7
5
  @exception = exception
8
6
 
@@ -33,11 +31,14 @@ class ExceptionState
33
31
  end
34
32
 
35
33
  def backtrace
34
+ @backtrace_filter ||= MSpecScript.config[:backtrace_filter]
35
+
36
36
  begin
37
37
  bt = @exception.awesome_backtrace.show.split "\n"
38
38
  rescue Exception
39
39
  bt = @exception.backtrace || []
40
40
  end
41
- bt.reject { |line| PATH =~ line }.join("\n")
41
+
42
+ bt.select { |line| $MSPEC_DEBUG or @backtrace_filter !~ line }.join("\n")
42
43
  end
43
44
  end
@@ -207,7 +207,7 @@ class MSpecOptions
207
207
 
208
208
  def targets
209
209
  on("-t", "--target", "TARGET",
210
- "Implementation to run the specs, where:") do |t|
210
+ "Implementation to run the specs, where TARGET is:") do |t|
211
211
  case t
212
212
  when 'r', 'ruby'
213
213
  config[:target] = 'ruby'
@@ -232,7 +232,8 @@ class MSpecOptions
232
232
  doc " x or rubinius invokes ./bin/rbx"
233
233
  doc " X or rbx invokes rbx in PATH"
234
234
  doc " j or jruby invokes jruby in PATH"
235
- doc " i or ironruby invokes ir in PATH\n"
235
+ doc " i or ironruby invokes ir in PATH"
236
+ doc " full path to EXE invokes EXE directly\n"
236
237
 
237
238
  on("-T", "--target-opt", "OPT",
238
239
  "Pass OPT as a flag to the target implementation") do |t|
@@ -440,4 +441,11 @@ class MSpecOptions
440
441
  config[:gdb] = true
441
442
  end
442
443
  end
444
+
445
+ def debug
446
+ on("-d", "--debug",
447
+ "Set MSpec debugging flag for more verbose output") do
448
+ $MSPEC_DEBUG = true
449
+ end
450
+ end
443
451
  end
data/lib/mspec/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  require 'mspec/utils/version'
2
2
 
3
3
  module MSpec
4
- VERSION = SpecVersion.new "1.5.11"
4
+ VERSION = SpecVersion.new "1.5.12"
5
5
  end
@@ -172,7 +172,7 @@ describe MkSpec, "#write_spec" do
172
172
 
173
173
  it "checks if specs exist for the method if the spec file exists" do
174
174
  @script.should_receive(:`).with(
175
- /mspec\/bin\/mspec-run --dry-run -fs -e 'Object#inspect' spec\/core\/tcejbo\/inspect_spec.rb/)
175
+ %r"#{@script.ruby} #{MSPEC_HOME}/bin/mspec-run --dry-run -fs -e 'Object#inspect' spec/core/tcejbo/inspect_spec.rb")
176
176
  @script.write_spec("spec/core/tcejbo/inspect_spec.rb", "Object#inspect", true)
177
177
  end
178
178
 
@@ -88,6 +88,11 @@ describe MSpecCI, "#options" do
88
88
  @script.options
89
89
  end
90
90
 
91
+ it "enables the debug option" do
92
+ @options.should_receive(:debug)
93
+ @script.options @argv
94
+ end
95
+
91
96
  it "calls #custom_options" do
92
97
  @script.should_receive(:custom_options).with(@options)
93
98
  @script.options
@@ -118,6 +118,11 @@ describe MSpecRun, "#options" do
118
118
  @script.options @argv
119
119
  end
120
120
 
121
+ it "enables the debug option" do
122
+ @options.should_receive(:debug)
123
+ @script.options @argv
124
+ end
125
+
121
126
  it "exits if there are no files to process" do
122
127
  @options.should_receive(:parse).and_return([])
123
128
  @script.should_receive(:exit)
@@ -239,7 +239,7 @@ describe MSpecMain, "#run" do
239
239
  end
240
240
 
241
241
  it "uses exec to invoke the runner script" do
242
- @script.should_receive(:exec).with("ruby", "-v", %r"mspec/bin/mspec-run$")
242
+ @script.should_receive(:exec).with("ruby", "-v", %r"#{MSPEC_HOME}/bin/mspec-run$")
243
243
  @script.options []
244
244
  @script.run
245
245
  end
@@ -248,7 +248,7 @@ describe MSpecMain, "#run" do
248
248
  @script.should_receive(:multi_exec).and_return do |arg|
249
249
  arg.length.should == 3
250
250
  arg[0].should == "-v"
251
- arg[1].should =~ %r"mspec/bin/mspec-ci$"
251
+ arg[1].should =~ %r"#{MSPEC_HOME}/bin/mspec-ci$"
252
252
  arg[2].should == "-fy"
253
253
  end
254
254
  @script.options ["ci", "-j"]
@@ -98,6 +98,11 @@ describe MSpecTag, "#options" do
98
98
  @script.options @argv
99
99
  end
100
100
 
101
+ it "enables the debug option" do
102
+ @options.should_receive(:debug)
103
+ @script.options @argv
104
+ end
105
+
101
106
  it "calls #custom_options" do
102
107
  @script.should_receive(:custom_options).with(@options)
103
108
  @script.options @argv
@@ -1,5 +1,6 @@
1
1
  $: << File.dirname(__FILE__) + '/../../lib'
2
2
  require 'mspec'
3
+ require 'mspec/utils/script'
3
4
 
4
5
  # The purpose of these specs is to confirm that the #should
5
6
  # and #should_not methods are functioning appropriately. We
@@ -0,0 +1,44 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require 'mspec/helpers/ducktype'
3
+
4
+ describe Object, "#responds_to" do
5
+ it "returns true for specified symbols" do
6
+ obj = mock("obj")
7
+ obj.responds_to(:to_flo)
8
+ obj.should respond_to(:to_flo)
9
+ obj.should respond_to(:to_s)
10
+ end
11
+ end
12
+
13
+ describe Object, "#does_not_respond_to" do
14
+ it "returns false for specified symbols" do
15
+ obj = mock("obj")
16
+ obj.does_not_respond_to(:to_s)
17
+ obj.should_not respond_to(:to_s)
18
+ end
19
+ end
20
+
21
+ describe Object, "#undefine" do
22
+ it "undefines the method" do
23
+ # cannot use a mock here because of the way RSpec handles method_missing
24
+ obj = Object.new
25
+ obj.undefine(:to_s)
26
+ lambda { obj.send :to_s }.should raise_error(NoMethodError)
27
+ end
28
+ end
29
+
30
+ describe Object, "#fake!" do
31
+ before :each do
32
+ @obj = mock("obj")
33
+ end
34
+
35
+ it "makes the object respond to the message" do
36
+ @obj.fake!(:to_flo)
37
+ @obj.should respond_to(:to_flo)
38
+ end
39
+
40
+ it "returns the value when the obj is sent the message" do
41
+ @obj.fake!(:to_flo, 1.2)
42
+ @obj.to_flo.should == 1.2
43
+ end
44
+ end
@@ -0,0 +1,19 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require 'mspec/helpers/enumerator_class'
3
+
4
+ describe "#enumerator_class" do
5
+
6
+ ruby_version_is ''...'1.8.7' do
7
+ it "returns Enumerable::Enumerator in Ruby 1.8.6-" do
8
+ lambda { enumerator_class }.should raise_error(NameError)
9
+ require 'enumerator'
10
+ enumerator_class.should == Enumerable::Enumerator
11
+ end
12
+ end
13
+
14
+ ruby_version_is '1.8.7' do
15
+ it "returns Enumerator in Ruby 1.8.7+" do
16
+ enumerator_class.should == Enumerator
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,30 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require 'mspec/helpers/hash'
3
+
4
+ describe Object, "#hash_class" do
5
+ it "returns the Hash class" do
6
+ hash_class.should == Hash
7
+ end
8
+ end
9
+
10
+ describe Object, "#new_hash" do
11
+ it "returns a default hash" do
12
+ new_hash.should == {}
13
+ end
14
+
15
+ it "returns a hash having a default value" do
16
+ hash = new_hash(5)
17
+ hash[:none].should == 5
18
+ end
19
+
20
+ it "returns a hash having a default proc" do
21
+ hash = new_hash { |h, k| h[k] = :default }
22
+ hash[:none].should == :default
23
+ end
24
+
25
+ it "returns a hash constructed from keys and values" do
26
+ new_hash({:a => 1, :b => 2}).should == { :a => 1, :b => 2 }
27
+ new_hash(1 => 2, 3 => 4).should == { 1 => 2, 3 => 4 }
28
+ new_hash(1, 2, 3, 4).should == { 1 => 2, 3 => 4 }
29
+ end
30
+ end
@@ -32,6 +32,11 @@ describe IOStub do
32
32
  @out.should == "hello\n1\n2\n3\n"
33
33
  end
34
34
 
35
+ it "provides a printf method" do
36
+ @out.printf "%-10s, %03d, %2.1f", "test", 42, 4.2
37
+ @out.should == "test , 042, 4.2"
38
+ end
39
+
35
40
  it "provides a flush method that does nothing and returns self" do
36
41
  @out.flush.should == @out
37
42
  end
@@ -0,0 +1,75 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require 'mspec/expectations/expectations'
3
+ require 'mspec/matchers/have_class_variable'
4
+
5
+ class IVarModMock; end
6
+
7
+ shared_examples_for "have_class_variable, on all Ruby versions" do
8
+ after :all do
9
+ Object.const_set :RUBY_VERSION, @ruby_version
10
+ end
11
+
12
+ it "matches when mod has the class variable, given as string" do
13
+ matcher = HaveClassVariableMatcher.new('@foo')
14
+ matcher.matches?(IVarModMock).should be_true
15
+ end
16
+
17
+ it "matches when mod has the class variable, given as symbol" do
18
+ matcher = HaveClassVariableMatcher.new(:@foo)
19
+ matcher.matches?(IVarModMock).should be_true
20
+ end
21
+
22
+ it "does not match when mod hasn't got the class variable, given as string" do
23
+ matcher = HaveClassVariableMatcher.new('@bar')
24
+ matcher.matches?(IVarModMock).should be_false
25
+ end
26
+
27
+ it "does not match when mod hasn't got the class variable, given as symbol" do
28
+ matcher = HaveClassVariableMatcher.new(:@bar)
29
+ matcher.matches?(IVarModMock).should be_false
30
+ end
31
+
32
+ it "provides a failure message for #should" do
33
+ matcher = HaveClassVariableMatcher.new(:@bar)
34
+ matcher.matches?(IVarModMock)
35
+ matcher.failure_message.should == [
36
+ "Expected IVarModMock to have class variable '@bar'",
37
+ "but it does not"
38
+ ]
39
+ end
40
+
41
+ it "provides a failure messoge for #should_not" do
42
+ matcher = HaveClassVariableMatcher.new(:@bar)
43
+ matcher.matches?(IVarModMock)
44
+ matcher.negative_failure_message.should == [
45
+ "Expected IVarModMock NOT to have class variable '@bar'",
46
+ "but it does"
47
+ ]
48
+ end
49
+ end
50
+
51
+ describe HaveClassVariableMatcher, "on RUBY_VERSION < 1.9" do
52
+ before :all do
53
+ @ruby_version = Object.const_get :RUBY_VERSION
54
+ Object.const_set :RUBY_VERSION, '1.8.6'
55
+
56
+ def IVarModMock.class_variables
57
+ ['@foo']
58
+ end
59
+ end
60
+
61
+ it_should_behave_like "have_class_variable, on all Ruby versions"
62
+ end
63
+
64
+ describe HaveClassVariableMatcher, "on RUBY_VERSION >= 1.9" do
65
+ before :all do
66
+ @ruby_version = Object.const_get :RUBY_VERSION
67
+ Object.const_set :RUBY_VERSION, '1.9.0'
68
+
69
+ def IVarModMock.class_variables
70
+ [:@foo]
71
+ end
72
+ end
73
+
74
+ it_should_behave_like "have_class_variable, on all Ruby versions"
75
+ end
@@ -0,0 +1,75 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require 'mspec/expectations/expectations'
3
+ require 'mspec/matchers/have_instance_variable'
4
+
5
+ shared_examples_for "have_instance_variable, on all Ruby versions" do
6
+ after :all do
7
+ Object.const_set :RUBY_VERSION, @ruby_version
8
+ end
9
+
10
+ it "matches when object has the instance variable, given as string" do
11
+ matcher = HaveInstanceVariableMatcher.new('@foo')
12
+ matcher.matches?(@object).should be_true
13
+ end
14
+
15
+ it "matches when object has the instance variable, given as symbol" do
16
+ matcher = HaveInstanceVariableMatcher.new(:@foo)
17
+ matcher.matches?(@object).should be_true
18
+ end
19
+
20
+ it "does not match when object hasn't got the instance variable, given as string" do
21
+ matcher = HaveInstanceVariableMatcher.new('@bar')
22
+ matcher.matches?(@object).should be_false
23
+ end
24
+
25
+ it "does not match when object hasn't got the instance variable, given as symbol" do
26
+ matcher = HaveInstanceVariableMatcher.new(:@bar)
27
+ matcher.matches?(@object).should be_false
28
+ end
29
+
30
+ it "provides a failure message for #should" do
31
+ matcher = HaveInstanceVariableMatcher.new(:@bar)
32
+ matcher.matches?(@object)
33
+ matcher.failure_message.should == [
34
+ "Expected #{@object.inspect} to have instance variable '@bar'",
35
+ "but it does not"
36
+ ]
37
+ end
38
+
39
+ it "provides a failure messoge for #should_not" do
40
+ matcher = HaveInstanceVariableMatcher.new(:@bar)
41
+ matcher.matches?(@object)
42
+ matcher.negative_failure_message.should == [
43
+ "Expected #{@object.inspect} NOT to have instance variable '@bar'",
44
+ "but it does"
45
+ ]
46
+ end
47
+ end
48
+
49
+ describe HaveInstanceVariableMatcher, "on RUBY_VERSION < 1.9" do
50
+ before :all do
51
+ @ruby_version = Object.const_get :RUBY_VERSION
52
+ Object.const_set :RUBY_VERSION, '1.8.6'
53
+
54
+ @object = Object.new
55
+ def @object.instance_variables
56
+ ['@foo']
57
+ end
58
+ end
59
+
60
+ it_should_behave_like "have_instance_variable, on all Ruby versions"
61
+ end
62
+
63
+ describe HaveInstanceVariableMatcher, "on RUBY_VERSION >= 1.9" do
64
+ before :all do
65
+ @ruby_version = Object.const_get :RUBY_VERSION
66
+ Object.const_set :RUBY_VERSION, '1.9.0'
67
+
68
+ @object = Object.new
69
+ def @object.instance_variables
70
+ [:@foo]
71
+ end
72
+ end
73
+
74
+ it_should_behave_like "have_instance_variable, on all Ruby versions"
75
+ end