summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spec/ruby/README.md10
-rw-r--r--spec/ruby/command_line/feature_spec.rb9
-rw-r--r--spec/ruby/core/complex/to_c_spec.rb12
-rw-r--r--spec/ruby/core/hash/except_spec.rb33
-rw-r--r--spec/ruby/core/nil/case_compare_spec.rb13
-rw-r--r--spec/ruby/core/numeric/clone_spec.rb25
-rw-r--r--spec/ruby/core/numeric/dup_spec.rb16
-rw-r--r--spec/ruby/core/string/end_with_spec.rb52
-rw-r--r--spec/ruby/core/string/start_with_spec.rb70
-rw-r--r--spec/ruby/core/string/uminus_spec.rb7
-rw-r--r--spec/ruby/core/symbol/end_with_spec.rb10
-rw-r--r--spec/ruby/core/symbol/start_with_spec.rb10
-rw-r--r--spec/ruby/core/true/case_compare_spec.rb13
-rw-r--r--spec/ruby/library/net/http/http/get2_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/head2_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/post2_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/put2_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/request_get_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/request_head_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/request_post_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/request_put_spec.rb2
-rw-r--r--spec/ruby/library/net/http/http/shared/request_get.rb2
-rw-r--r--spec/ruby/library/net/http/http/shared/request_head.rb2
-rw-r--r--spec/ruby/library/net/http/http/shared/request_post.rb2
-rw-r--r--spec/ruby/library/net/http/http/shared/request_put.rb2
-rw-r--r--spec/ruby/shared/string/end_with.rb54
-rw-r--r--spec/ruby/shared/string/start_with.rb72
27 files changed, 296 insertions, 134 deletions
diff --git a/spec/ruby/README.md b/spec/ruby/README.md
index ec744c1165..932cd83061 100644
--- a/spec/ruby/README.md
+++ b/spec/ruby/README.md
@@ -5,6 +5,8 @@
The Ruby Spec Suite, abbreviated `ruby/spec`, is a test suite for the behavior of the Ruby programming language.
+### Description and Motivation
+
It is not a standardized specification like the ISO one, and does not aim to become one.
Instead, it is a practical tool to describe and test the behavior of Ruby with code.
@@ -30,13 +32,15 @@ ruby/spec is known to be tested in these implementations for every commit:
ruby/spec describes the behavior of Ruby 2.5 and more recent Ruby versions.
More precisely, every latest stable MRI release should [pass](https://travis-ci.org/ruby/spec) all specs of ruby/spec (2.5.x, 2.6.x, 2.7.x, etc), and those are tested in TravisCI.
+### Synchronization with Ruby Implementations
+
The specs are synchronized both ways around once a month by @eregon between ruby/spec, MRI, JRuby and TruffleRuby.
Each of these repositories has a full copy of the specs under `spec/ruby` to ease editing specs.
Any of these repositories can be used to add or edit specs, use what is most convenient for you.
-For *testing* a Ruby implementation, one should always test against the implementation's copy of the specs under `spec/ruby`, as that's what the Ruby implementation tests against in their CI.
+For *testing* the development version of a Ruby implementation, one should always test against that implementation's copy of the specs under `spec/ruby`, as that's what the Ruby implementation tests against in their CI.
Also, this repository doesn't always contain the latest spec changes from MRI (it's synchronized monthly), and does not contain tags (specs marked as failing on that Ruby implementation).
-Running specs in a Ruby implementation can be done with:
+Running specs on a Ruby implementation can be done with:
```
$ cd ruby_implementation/spec/ruby
@@ -44,6 +48,8 @@ $ cd ruby_implementation/spec/ruby
$ ../mspec/bin/mspec
```
+### Specs for old Ruby versions
+
For older specs try these commits:
* Ruby 2.0.0-p647 - [Suite](https://github.com/ruby/spec/commit/245862558761d5abc676843ef74f86c9bcc8ea8d) using [MSpec](https://github.com/ruby/mspec/commit/f90efa068791064f955de7a843e96e2d7d3041c2) (may encounter 2 failures)
* Ruby 2.1.9 - [Suite](https://github.com/ruby/spec/commit/f029e65241374386077ac500add557ae65069b55) using [MSpec](https://github.com/ruby/mspec/commit/55568ea3918c6380e64db8c567d732fa5781efed)
diff --git a/spec/ruby/command_line/feature_spec.rb b/spec/ruby/command_line/feature_spec.rb
index 02571ee8c6..8848249c64 100644
--- a/spec/ruby/command_line/feature_spec.rb
+++ b/spec/ruby/command_line/feature_spec.rb
@@ -37,11 +37,16 @@ describe "The --enable and --disable flags" do
ruby_exe("p 'foo'.frozen?", options: "--disable-frozen-string-literal").chomp.should == "false"
end
- it "can be used with all" do
+ it "can be used with all for enable" do
e = "p [defined?(Gem), defined?(DidYouMean), $VERBOSE, 'foo'.frozen?]"
env = {'RUBYOPT' => '-w'}
- ruby_exe(e, options: "--enable=all", env: env).chomp.should == "[\"constant\", \"constant\", true, true]"
+ # Use a single variant here because it can be quite slow as it might enable jit, etc
ruby_exe(e, options: "--enable-all", env: env).chomp.should == "[\"constant\", \"constant\", true, true]"
+ end
+
+ it "can be used with all for disable" do
+ e = "p [defined?(Gem), defined?(DidYouMean), $VERBOSE, 'foo'.frozen?]"
+ env = {'RUBYOPT' => '-w'}
ruby_exe(e, options: "--disable=all", env: env).chomp.should == "[nil, nil, false, false]"
ruby_exe(e, options: "--disable-all", env: env).chomp.should == "[nil, nil, false, false]"
end
diff --git a/spec/ruby/core/complex/to_c_spec.rb b/spec/ruby/core/complex/to_c_spec.rb
new file mode 100644
index 0000000000..5ce01d9d4e
--- /dev/null
+++ b/spec/ruby/core/complex/to_c_spec.rb
@@ -0,0 +1,12 @@
+require_relative '../../spec_helper'
+
+describe "Complex#to_c" do
+ it "returns self" do
+ value = Complex(1, 5)
+ value.to_c.should equal(value)
+ end
+
+ it 'returns the same value' do
+ Complex(1, 5).to_c.should == Complex(1, 5)
+ end
+end
diff --git a/spec/ruby/core/hash/except_spec.rb b/spec/ruby/core/hash/except_spec.rb
new file mode 100644
index 0000000000..cef99b6284
--- /dev/null
+++ b/spec/ruby/core/hash/except_spec.rb
@@ -0,0 +1,33 @@
+require_relative '../../spec_helper'
+
+ruby_version_is "3.0" do
+ describe "Hash#except" do
+ before :each do
+ @hash = { a: 1, b: 2, c: 3 }
+ end
+
+ it "returns a new duplicate hash without arguments" do
+ ret = @hash.except
+ ret.should_not equal(@hash)
+ ret.should == @hash
+ end
+
+ it "returns a hash without the requested subset" do
+ @hash.except(:c, :a).should == { b: 2 }
+ end
+
+ it "ignores keys not present in the original hash" do
+ @hash.except(:a, :chunky_bacon).should == { b: 2, c: 3 }
+ end
+
+ it "returns an instance of a subclass" do
+ klass = Class.new(Hash)
+ h = klass.new
+ h[:bar] = 12
+ h[:foo] = 42
+ r = h.except(:foo)
+ r.should == {bar: 12}
+ r.class.should == klass
+ end
+ end
+end
diff --git a/spec/ruby/core/nil/case_compare_spec.rb b/spec/ruby/core/nil/case_compare_spec.rb
new file mode 100644
index 0000000000..142560c6f5
--- /dev/null
+++ b/spec/ruby/core/nil/case_compare_spec.rb
@@ -0,0 +1,13 @@
+require_relative '../../spec_helper'
+
+describe "NilClass#===" do
+ it "returns true for nil" do
+ (nil === nil).should == true
+ end
+
+ it "returns false for non-nil object" do
+ (nil === 1).should == false
+ (nil === "").should == false
+ (nil === Object).should == false
+ end
+end
diff --git a/spec/ruby/core/numeric/clone_spec.rb b/spec/ruby/core/numeric/clone_spec.rb
new file mode 100644
index 0000000000..e3bf0a9e7c
--- /dev/null
+++ b/spec/ruby/core/numeric/clone_spec.rb
@@ -0,0 +1,25 @@
+require_relative '../../spec_helper'
+
+describe "Numeric#clone" do
+ it "returns self" do
+ value = 1
+ value.clone.should equal(value)
+
+ subclass = Class.new(Numeric)
+ value = subclass.new
+ value.clone.should equal(value)
+ end
+
+ it "does not change frozen status" do
+ 1.clone.frozen?.should == true
+ end
+
+ it "accepts optonal keyword argument :freeze" do
+ value = 1
+ value.clone(freeze: true).should equal(value)
+ end
+
+ it "raises ArgumentError if passed freeze: false" do
+ -> { 1.clone(freeze: false) }.should raise_error(ArgumentError, /can't unfreeze/)
+ end
+end
diff --git a/spec/ruby/core/numeric/dup_spec.rb b/spec/ruby/core/numeric/dup_spec.rb
new file mode 100644
index 0000000000..189a7ef44d
--- /dev/null
+++ b/spec/ruby/core/numeric/dup_spec.rb
@@ -0,0 +1,16 @@
+require_relative '../../spec_helper'
+
+describe "Numeric#dup" do
+ it "returns self" do
+ value = 1
+ value.dup.should equal(value)
+
+ subclass = Class.new(Numeric)
+ value = subclass.new
+ value.dup.should equal(value)
+ end
+
+ it "does not change frozen status" do
+ 1.dup.frozen?.should == true
+ end
+end
diff --git a/spec/ruby/core/string/end_with_spec.rb b/spec/ruby/core/string/end_with_spec.rb
index 9ced0ca3d2..ac4fff72ad 100644
--- a/spec/ruby/core/string/end_with_spec.rb
+++ b/spec/ruby/core/string/end_with_spec.rb
@@ -1,56 +1,8 @@
# -*- encoding: utf-8 -*-
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
+require_relative '../../shared/string/end_with'
describe "String#end_with?" do
- it "returns true only if ends match" do
- s = "hello"
- s.should.end_with?('o')
- s.should.end_with?('llo')
- end
-
- it 'returns false if the end does not match' do
- s = 'hello'
- s.should_not.end_with?('ll')
- end
-
- it "returns true if the search string is empty" do
- "hello".should.end_with?("")
- "".should.end_with?("")
- end
-
- it "returns true only if any ending match" do
- "hello".should.end_with?('x', 'y', 'llo', 'z')
- end
-
- it "converts its argument using :to_str" do
- s = "hello"
- find = mock('o')
- find.should_receive(:to_str).and_return("o")
- s.should.end_with?(find)
- end
-
- it "ignores arguments not convertible to string" do
- "hello".should_not.end_with?()
- -> { "hello".end_with?(1) }.should raise_error(TypeError)
- -> { "hello".end_with?(["o"]) }.should raise_error(TypeError)
- -> { "hello".end_with?(1, nil, "o") }.should raise_error(TypeError)
- end
-
- it "uses only the needed arguments" do
- find = mock('h')
- find.should_not_receive(:to_str)
- "hello".should.end_with?("o",find)
- end
-
- it "works for multibyte strings" do
- "céréale".should.end_with?("réale")
- end
-
- it "raises an Encoding::CompatibilityError if the encodings are incompatible" do
- pat = "ア".encode Encoding::EUC_JP
- -> do
- "あれ".end_with?(pat)
- end.should raise_error(Encoding::CompatibilityError)
- end
+ it_behaves_like :end_with, :to_s
end
diff --git a/spec/ruby/core/string/start_with_spec.rb b/spec/ruby/core/string/start_with_spec.rb
index 11c8041925..aaed197ff3 100644
--- a/spec/ruby/core/string/start_with_spec.rb
+++ b/spec/ruby/core/string/start_with_spec.rb
@@ -1,74 +1,8 @@
# -*- encoding: utf-8 -*-
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
+require_relative '../../shared/string/start_with'
describe "String#start_with?" do
- it "returns true only if beginning match" do
- s = "hello"
- s.should.start_with?('h')
- s.should.start_with?('hel')
- s.should_not.start_with?('el')
- end
-
- it "returns true only if any beginning match" do
- "hello".should.start_with?('x', 'y', 'he', 'z')
- end
-
- it "returns true if the search string is empty" do
- "hello".should.start_with?("")
- "".should.start_with?("")
- end
-
- it "converts its argument using :to_str" do
- s = "hello"
- find = mock('h')
- find.should_receive(:to_str).and_return("h")
- s.should.start_with?(find)
- end
-
- it "ignores arguments not convertible to string" do
- "hello".should_not.start_with?()
- -> { "hello".start_with?(1) }.should raise_error(TypeError)
- -> { "hello".start_with?(["h"]) }.should raise_error(TypeError)
- -> { "hello".start_with?(1, nil, "h") }.should raise_error(TypeError)
- end
-
- it "uses only the needed arguments" do
- find = mock('h')
- find.should_not_receive(:to_str)
- "hello".should.start_with?("h",find)
- end
-
- it "works for multibyte strings" do
- "céréale".should.start_with?("cér")
- end
-
- it "supports regexps" do
- regexp = /[h1]/
- "hello".should.start_with?(regexp)
- "1337".should.start_with?(regexp)
- "foxes are 1337".should_not.start_with?(regexp)
- "chunky\n12bacon".should_not.start_with?(/12/)
- end
-
- it "supports regexps with ^ and $ modifiers" do
- regexp1 = /^\d{2}/
- regexp2 = /\d{2}$/
- "12test".should.start_with?(regexp1)
- "test12".should_not.start_with?(regexp1)
- "12test".should_not.start_with?(regexp2)
- "test12".should_not.start_with?(regexp2)
- end
-
- it "sets Regexp.last_match if it returns true" do
- regexp = /test-(\d+)/
- "test-1337".start_with?(regexp).should be_true
- Regexp.last_match.should_not be_nil
- Regexp.last_match[1].should == "1337"
- $1.should == "1337"
-
- "test-asdf".start_with?(regexp).should be_false
- Regexp.last_match.should be_nil
- $1.should be_nil
- end
+ it_behaves_like :start_with, :to_s
end
diff --git a/spec/ruby/core/string/uminus_spec.rb b/spec/ruby/core/string/uminus_spec.rb
index 91f91fdb1e..3a81b64126 100644
--- a/spec/ruby/core/string/uminus_spec.rb
+++ b/spec/ruby/core/string/uminus_spec.rb
@@ -69,4 +69,11 @@ describe 'String#-@' do
(-dynamic).should equal(-"this string is frozen".freeze)
end
end
+
+ ruby_version_is "3.0" do
+ it "interns the provided string if it is frozen" do
+ dynamic = "this string is unique and frozen #{rand}".freeze
+ (-dynamic).should equal(dynamic)
+ end
+ end
end
diff --git a/spec/ruby/core/symbol/end_with_spec.rb b/spec/ruby/core/symbol/end_with_spec.rb
new file mode 100644
index 0000000000..77dc4caf71
--- /dev/null
+++ b/spec/ruby/core/symbol/end_with_spec.rb
@@ -0,0 +1,10 @@
+# -*- encoding: utf-8 -*-
+
+require_relative '../../spec_helper'
+require_relative '../../shared/string/end_with'
+
+ruby_version_is "2.7" do
+ describe "Symbol#end_with?" do
+ it_behaves_like :end_with, :to_sym
+ end
+end
diff --git a/spec/ruby/core/symbol/start_with_spec.rb b/spec/ruby/core/symbol/start_with_spec.rb
new file mode 100644
index 0000000000..f54b3e499e
--- /dev/null
+++ b/spec/ruby/core/symbol/start_with_spec.rb
@@ -0,0 +1,10 @@
+# -*- encoding: utf-8 -*-
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+require_relative '../../shared/string/start_with'
+
+ruby_version_is "2.7" do
+ describe "Symbol#start_with?" do
+ it_behaves_like :start_with, :to_sym
+ end
+end
diff --git a/spec/ruby/core/true/case_compare_spec.rb b/spec/ruby/core/true/case_compare_spec.rb
new file mode 100644
index 0000000000..dee6dd0227
--- /dev/null
+++ b/spec/ruby/core/true/case_compare_spec.rb
@@ -0,0 +1,13 @@
+require_relative '../../spec_helper'
+
+describe "TrueClass#===" do
+ it "returns true for true" do
+ (true === true).should == true
+ end
+
+ it "returns false for non-true object" do
+ (true === 1).should == false
+ (true === "").should == false
+ (true === Object).should == false
+ end
+end
diff --git a/spec/ruby/library/net/http/http/get2_spec.rb b/spec/ruby/library/net/http/http/get2_spec.rb
index 71dfc3d39b..519e4c2599 100644
--- a/spec/ruby/library/net/http/http/get2_spec.rb
+++ b/spec/ruby/library/net/http/http/get2_spec.rb
@@ -4,5 +4,5 @@ require_relative 'fixtures/http_server'
require_relative 'shared/request_get'
describe "Net::HTTP#get2" do
- it_behaves_like :net_ftp_request_get, :get2
+ it_behaves_like :net_http_request_get, :get2
end
diff --git a/spec/ruby/library/net/http/http/head2_spec.rb b/spec/ruby/library/net/http/http/head2_spec.rb
index 606798e4af..6958204ee1 100644
--- a/spec/ruby/library/net/http/http/head2_spec.rb
+++ b/spec/ruby/library/net/http/http/head2_spec.rb
@@ -4,5 +4,5 @@ require_relative 'fixtures/http_server'
require_relative 'shared/request_head'
describe "Net::HTTP#head2" do
- it_behaves_like :net_ftp_request_head, :head2
+ it_behaves_like :net_http_request_head, :head2
end
diff --git a/spec/ruby/library/net/http/http/post2_spec.rb b/spec/ruby/library/net/http/http/post2_spec.rb
index eab9a6a1d2..ccc95068fb 100644
--- a/spec/ruby/library/net/http/http/post2_spec.rb
+++ b/spec/ruby/library/net/http/http/post2_spec.rb
@@ -4,5 +4,5 @@ require_relative 'fixtures/http_server'
require_relative 'shared/request_post'
describe "Net::HTTP#post2" do
- it_behaves_like :net_ftp_request_post, :post2
+ it_behaves_like :net_http_request_post, :post2
end
diff --git a/spec/ruby/library/net/http/http/put2_spec.rb b/spec/ruby/library/net/http/http/put2_spec.rb
index 0ee3590639..99329a5fd9 100644
--- a/spec/ruby/library/net/http/http/put2_spec.rb
+++ b/spec/ruby/library/net/http/http/put2_spec.rb
@@ -4,5 +4,5 @@ require_relative 'fixtures/http_server'
require_relative 'shared/request_put'
describe "Net::HTTP#put2" do
- it_behaves_like :net_ftp_request_put, :put2
+ it_behaves_like :net_http_request_put, :put2
end
diff --git a/spec/ruby/library/net/http/http/request_get_spec.rb b/spec/ruby/library/net/http/http/request_get_spec.rb
index f53a2e9d65..9932ef0beb 100644
--- a/spec/ruby/library/net/http/http/request_get_spec.rb
+++ b/spec/ruby/library/net/http/http/request_get_spec.rb
@@ -4,5 +4,5 @@ require_relative 'fixtures/http_server'
require_relative 'shared/request_get'
describe "Net::HTTP#request_get" do
- it_behaves_like :net_ftp_request_get, :get2
+ it_behaves_like :net_http_request_get, :get2
end
diff --git a/spec/ruby/library/net/http/http/request_head_spec.rb b/spec/ruby/library/net/http/http/request_head_spec.rb
index dc47557b9d..788101c951 100644
--- a/spec/ruby/library/net/http/http/request_head_spec.rb
+++ b/spec/ruby/library/net/http/http/request_head_spec.rb
@@ -4,5 +4,5 @@ require_relative 'fixtures/http_server'
require_relative 'shared/request_head'
describe "Net::HTTP#request_head" do
- it_behaves_like :net_ftp_request_head, :request_head
+ it_behaves_like :net_http_request_head, :request_head
end
diff --git a/spec/ruby/library/net/http/http/request_post_spec.rb b/spec/ruby/library/net/http/http/request_post_spec.rb
index 0b408fa84d..7ac67cf95d 100644
--- a/spec/ruby/library/net/http/http/request_post_spec.rb
+++ b/spec/ruby/library/net/http/http/request_post_spec.rb
@@ -4,5 +4,5 @@ require_relative 'fixtures/http_server'
require_relative 'shared/request_post'
describe "Net::HTTP#request_post" do
- it_behaves_like :net_ftp_request_post, :request_post
+ it_behaves_like :net_http_request_post, :request_post
end
diff --git a/spec/ruby/library/net/http/http/request_put_spec.rb b/spec/ruby/library/net/http/http/request_put_spec.rb
index 987b52ceb0..110ac43ca6 100644
--- a/spec/ruby/library/net/http/http/request_put_spec.rb
+++ b/spec/ruby/library/net/http/http/request_put_spec.rb
@@ -4,5 +4,5 @@ require_relative 'fixtures/http_server'
require_relative 'shared/request_put'
describe "Net::HTTP#request_put" do
- it_behaves_like :net_ftp_request_put, :request_put
+ it_behaves_like :net_http_request_put, :request_put
end
diff --git a/spec/ruby/library/net/http/http/shared/request_get.rb b/spec/ruby/library/net/http/http/shared/request_get.rb
index b0eca665d6..d25f32049b 100644
--- a/spec/ruby/library/net/http/http/shared/request_get.rb
+++ b/spec/ruby/library/net/http/http/shared/request_get.rb
@@ -1,4 +1,4 @@
-describe :net_ftp_request_get, shared: true do
+describe :net_http_request_get, shared: true do
before :each do
NetHTTPSpecs.start_server
@http = Net::HTTP.start("localhost", NetHTTPSpecs.port)
diff --git a/spec/ruby/library/net/http/http/shared/request_head.rb b/spec/ruby/library/net/http/http/shared/request_head.rb
index 0e669de9ac..78b555884b 100644
--- a/spec/ruby/library/net/http/http/shared/request_head.rb
+++ b/spec/ruby/library/net/http/http/shared/request_head.rb
@@ -1,4 +1,4 @@
-describe :net_ftp_request_head, shared: true do
+describe :net_http_request_head, shared: true do
before :each do
NetHTTPSpecs.start_server
@http = Net::HTTP.start("localhost", NetHTTPSpecs.port)
diff --git a/spec/ruby/library/net/http/http/shared/request_post.rb b/spec/ruby/library/net/http/http/shared/request_post.rb
index 06c5e139f9..e832411c48 100644
--- a/spec/ruby/library/net/http/http/shared/request_post.rb
+++ b/spec/ruby/library/net/http/http/shared/request_post.rb
@@ -1,4 +1,4 @@
-describe :net_ftp_request_post, shared: true do
+describe :net_http_request_post, shared: true do
before :each do
NetHTTPSpecs.start_server
@http = Net::HTTP.start("localhost", NetHTTPSpecs.port)
diff --git a/spec/ruby/library/net/http/http/shared/request_put.rb b/spec/ruby/library/net/http/http/shared/request_put.rb
index 6ae791d7e7..3b902f4957 100644
--- a/spec/ruby/library/net/http/http/shared/request_put.rb
+++ b/spec/ruby/library/net/http/http/shared/request_put.rb
@@ -1,4 +1,4 @@
-describe :net_ftp_request_put, shared: true do
+describe :net_http_request_put, shared: true do
before :each do
NetHTTPSpecs.start_server
@http = Net::HTTP.start("localhost", NetHTTPSpecs.port)
diff --git a/spec/ruby/shared/string/end_with.rb b/spec/ruby/shared/string/end_with.rb
new file mode 100644
index 0000000000..5f2a011235
--- /dev/null
+++ b/spec/ruby/shared/string/end_with.rb
@@ -0,0 +1,54 @@
+describe :end_with, shared: true do
+ # the @method should either be :to_s or :to_sym
+
+ it "returns true only if ends match" do
+ s = "hello".send(@method)
+ s.should.end_with?('o')
+ s.should.end_with?('llo')
+ end
+
+ it 'returns false if the end does not match' do
+ s = 'hello'.send(@method)
+ s.should_not.end_with?('ll')
+ end
+
+ it "returns true if the search string is empty" do
+ "hello".send(@method).should.end_with?("")
+ "".send(@method).should.end_with?("")
+ end
+
+ it "returns true only if any ending match" do
+ "hello".send(@method).should.end_with?('x', 'y', 'llo', 'z')
+ end
+
+ it "converts its argument using :to_str" do
+ s = "hello".send(@method)
+ find = mock('o')
+ find.should_receive(:to_str).and_return("o")
+ s.should.end_with?(find)
+ end
+
+ it "ignores arguments not convertible to string" do
+ "hello".send(@method).should_not.end_with?()
+ -> { "hello".send(@method).end_with?(1) }.should raise_error(TypeError)
+ -> { "hello".send(@method).end_with?(["o"]) }.should raise_error(TypeError)
+ -> { "hello".send(@method).end_with?(1, nil, "o") }.should raise_error(TypeError)
+ end
+
+ it "uses only the needed arguments" do
+ find = mock('h')
+ find.should_not_receive(:to_str)
+ "hello".send(@method).should.end_with?("o",find)
+ end
+
+ it "works for multibyte strings" do
+ "céréale".send(@method).should.end_with?("réale")
+ end
+
+ it "raises an Encoding::CompatibilityError if the encodings are incompatible" do
+ pat = "ア".encode Encoding::EUC_JP
+ -> do
+ "あれ".send(@method).end_with?(pat)
+ end.should raise_error(Encoding::CompatibilityError)
+ end
+end
diff --git a/spec/ruby/shared/string/start_with.rb b/spec/ruby/shared/string/start_with.rb
new file mode 100644
index 0000000000..d8d6e13f6a
--- /dev/null
+++ b/spec/ruby/shared/string/start_with.rb
@@ -0,0 +1,72 @@
+describe :start_with, shared: true do
+ # the @method should either be :to_s or :to_sym
+
+ it "returns true only if beginning match" do
+ s = "hello".send(@method)
+ s.should.start_with?('h')
+ s.should.start_with?('hel')
+ s.should_not.start_with?('el')
+ end
+
+ it "returns true only if any beginning match" do
+ "hello".send(@method).should.start_with?('x', 'y', 'he', 'z')
+ end
+
+ it "returns true if the search string is empty" do
+ "hello".send(@method).should.start_with?("")
+ "".send(@method).should.start_with?("")
+ end
+
+ it "converts its argument using :to_str" do
+ s = "hello".send(@method)
+ find = mock('h')
+ find.should_receive(:to_str).and_return("h")
+ s.should.start_with?(find)
+ end
+
+ it "ignores arguments not convertible to string" do
+ "hello".send(@method).should_not.start_with?()
+ -> { "hello".send(@method).start_with?(1) }.should raise_error(TypeError)
+ -> { "hello".send(@method).start_with?(["h"]) }.should raise_error(TypeError)
+ -> { "hello".send(@method).start_with?(1, nil, "h") }.should raise_error(TypeError)
+ end
+
+ it "uses only the needed arguments" do
+ find = mock('h')
+ find.should_not_receive(:to_str)
+ "hello".send(@method).should.start_with?("h",find)
+ end
+
+ it "works for multibyte strings" do
+ "céréale".send(@method).should.start_with?("cér")
+ end
+
+ it "supports regexps" do
+ regexp = /[h1]/
+ "hello".send(@method).should.start_with?(regexp)
+ "1337".send(@method).should.start_with?(regexp)
+ "foxes are 1337".send(@method).should_not.start_with?(regexp)
+ "chunky\n12bacon".send(@method).should_not.start_with?(/12/)
+ end
+
+ it "supports regexps with ^ and $ modifiers" do
+ regexp1 = /^\d{2}/
+ regexp2 = /\d{2}$/
+ "12test".send(@method).should.start_with?(regexp1)
+ "test12".send(@method).should_not.start_with?(regexp1)
+ "12test".send(@method).should_not.start_with?(regexp2)
+ "test12".send(@method).should_not.start_with?(regexp2)
+ end
+
+ it "sets Regexp.last_match if it returns true" do
+ regexp = /test-(\d+)/
+ "test-1337".send(@method).start_with?(regexp).should be_true
+ Regexp.last_match.should_not be_nil
+ Regexp.last_match[1].should == "1337"
+ $1.should == "1337"
+
+ "test-asdf".send(@method).start_with?(regexp).should be_false
+ Regexp.last_match.should be_nil
+ $1.should be_nil
+ end
+end