summaryrefslogtreecommitdiff
path: root/spec/ruby/library/stringscanner
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/library/stringscanner')
-rw-r--r--spec/ruby/library/stringscanner/captures_spec.rb36
-rw-r--r--spec/ruby/library/stringscanner/charpos_spec.rb18
-rw-r--r--spec/ruby/library/stringscanner/check_spec.rb68
-rw-r--r--spec/ruby/library/stringscanner/check_until_spec.rb116
-rw-r--r--spec/ruby/library/stringscanner/clear_spec.rb18
-rw-r--r--spec/ruby/library/stringscanner/dup_spec.rb4
-rw-r--r--spec/ruby/library/stringscanner/element_reference_spec.rb19
-rw-r--r--spec/ruby/library/stringscanner/empty_spec.rb18
-rw-r--r--spec/ruby/library/stringscanner/eos_spec.rb17
-rw-r--r--spec/ruby/library/stringscanner/exist_spec.rb95
-rw-r--r--spec/ruby/library/stringscanner/fixed_anchor_spec.rb17
-rw-r--r--spec/ruby/library/stringscanner/get_byte_spec.rb81
-rw-r--r--spec/ruby/library/stringscanner/getbyte_spec.rb21
-rw-r--r--spec/ruby/library/stringscanner/getch_spec.rb63
-rw-r--r--spec/ruby/library/stringscanner/initialize_spec.rb11
-rw-r--r--spec/ruby/library/stringscanner/inspect_spec.rb2
-rw-r--r--spec/ruby/library/stringscanner/match_spec.rb23
-rw-r--r--spec/ruby/library/stringscanner/matched_spec.rb4
-rw-r--r--spec/ruby/library/stringscanner/must_C_version_spec.rb2
-rw-r--r--spec/ruby/library/stringscanner/named_captures_spec.rb28
-rw-r--r--spec/ruby/library/stringscanner/peek_byte_spec.rb35
-rw-r--r--spec/ruby/library/stringscanner/peek_spec.rb39
-rw-r--r--spec/ruby/library/stringscanner/peep_spec.rb18
-rw-r--r--spec/ruby/library/stringscanner/rest_size_spec.rb27
-rw-r--r--spec/ruby/library/stringscanner/rest_spec.rb6
-rw-r--r--spec/ruby/library/stringscanner/restsize_spec.rb18
-rw-r--r--spec/ruby/library/stringscanner/scan_byte_spec.rb98
-rw-r--r--spec/ruby/library/stringscanner/scan_full_spec.rb14
-rw-r--r--spec/ruby/library/stringscanner/scan_integer_spec.rb157
-rw-r--r--spec/ruby/library/stringscanner/scan_spec.rb34
-rw-r--r--spec/ruby/library/stringscanner/scan_until_spec.rb110
-rw-r--r--spec/ruby/library/stringscanner/search_full_spec.rb101
-rw-r--r--spec/ruby/library/stringscanner/shared/bol.rb16
-rw-r--r--spec/ruby/library/stringscanner/shared/concat.rb14
-rw-r--r--spec/ruby/library/stringscanner/shared/eos.rb17
-rw-r--r--spec/ruby/library/stringscanner/shared/extract_range.rb4
-rw-r--r--spec/ruby/library/stringscanner/shared/extract_range_matched.rb4
-rw-r--r--spec/ruby/library/stringscanner/shared/get_byte.rb29
-rw-r--r--spec/ruby/library/stringscanner/shared/peek.rb39
-rw-r--r--spec/ruby/library/stringscanner/shared/pos.rb11
-rw-r--r--spec/ruby/library/stringscanner/shared/rest_size.rb18
-rw-r--r--spec/ruby/library/stringscanner/shared/terminate.rb8
-rw-r--r--spec/ruby/library/stringscanner/skip_spec.rb14
-rw-r--r--spec/ruby/library/stringscanner/skip_until_spec.rb112
-rw-r--r--spec/ruby/library/stringscanner/string_spec.rb2
-rw-r--r--spec/ruby/library/stringscanner/terminate_spec.rb8
-rw-r--r--spec/ruby/library/stringscanner/unscan_spec.rb6
-rw-r--r--spec/ruby/library/stringscanner/values_at_spec.rb68
48 files changed, 1402 insertions, 286 deletions
diff --git a/spec/ruby/library/stringscanner/captures_spec.rb b/spec/ruby/library/stringscanner/captures_spec.rb
new file mode 100644
index 0000000000..bdfb0e0cc5
--- /dev/null
+++ b/spec/ruby/library/stringscanner/captures_spec.rb
@@ -0,0 +1,36 @@
+require_relative '../../spec_helper'
+require 'strscan'
+
+describe "StringScanner#captures" do
+ before do
+ @s = StringScanner.new('Fri Dec 12 1975 14:39')
+ end
+
+ it "returns the array of captured values of the most recent matching" do
+ @s.exist?(/(?<wday>\w+) (?<month>\w+) (?<day>\d+)/)
+ @s.captures.should == ["Fri", "Dec", "12"]
+ end
+
+ it "returns nil if the last match fails" do
+ @s.scan(/nope/)
+ @s.captures.should == nil
+ end
+
+ it "returns nil if there is no any match done" do
+ @s.captures.should == nil
+ end
+
+ version_is StringScanner::Version, ""..."3.0.8" do # ruby_version_is ""..."3.3.3"
+ it "returns '' for an optional capturing group if it doesn't match" do
+ @s.exist?(/(?<wday>\w+) (?<month>\w+) (?<day>\s+)?/)
+ @s.captures.should == ["Fri", "Dec", ""]
+ end
+ end
+
+ version_is StringScanner::Version, "3.0.8" do # ruby_version_is "3.3.3"
+ it "returns nil for an optional capturing group if it doesn't match" do
+ @s.exist?(/(?<wday>\w+) (?<month>\w+) (?<day>\s+)?/)
+ @s.captures.should == ["Fri", "Dec", nil]
+ end
+ end
+end
diff --git a/spec/ruby/library/stringscanner/charpos_spec.rb b/spec/ruby/library/stringscanner/charpos_spec.rb
new file mode 100644
index 0000000000..9aa5b00dd9
--- /dev/null
+++ b/spec/ruby/library/stringscanner/charpos_spec.rb
@@ -0,0 +1,18 @@
+require_relative '../../spec_helper'
+require 'strscan'
+
+describe "StringScanner#charpos" do
+ it "returns character index corresponding to the current position" do
+ s = StringScanner.new("abc")
+
+ s.scan_until(/b/)
+ s.charpos.should == 2
+ end
+
+ it "is multi-byte character sensitive" do
+ s = StringScanner.new("abcädeföghi")
+
+ s.scan_until(/ö/)
+ s.charpos.should == 8
+ end
+end
diff --git a/spec/ruby/library/stringscanner/check_spec.rb b/spec/ruby/library/stringscanner/check_spec.rb
index a97c26af83..232158b09e 100644
--- a/spec/ruby/library/stringscanner/check_spec.rb
+++ b/spec/ruby/library/stringscanner/check_spec.rb
@@ -22,4 +22,72 @@ describe "StringScanner#check" do
@s.matched.should == nil
end
+ describe "#[] successive call with a capture group name" do
+ context "when #check was called with a Regexp pattern" do
+ it "returns matched substring when matching succeeded" do
+ @s.check(/(?<a>This)/)
+ @s.should.matched?
+ @s[:a].should == "This"
+ end
+
+ it "returns nil when matching failed" do
+ @s.check(/(?<a>2008)/)
+ @s.should_not.matched?
+ @s[:a].should == nil
+ end
+ end
+
+ context "when #check was called with a String pattern" do
+ # https://github.com/ruby/strscan/issues/139
+ version_is StringScanner::Version, "3.1.1"..."3.1.3" do # ruby_version_is "3.4.0"..."3.4.3"
+ it "returns nil when matching succeeded" do
+ @s.check("This")
+ @s.should.matched?
+ @s[:a].should == nil
+ end
+ end
+ version_is StringScanner::Version, "3.1.3" do # ruby_version_is "3.4"
+ it "raises IndexError when matching succeeded" do
+ @s.check("This")
+ @s.should.matched?
+ -> { @s[:a] }.should.raise(IndexError)
+ end
+ end
+
+ it "returns nil when matching failed" do
+ @s.check("2008")
+ @s.should_not.matched?
+ @s[:a].should == nil
+ end
+
+ it "returns a matching substring when given Integer index" do
+ @s.check("This")
+ @s[0].should == "This"
+ end
+
+ # https://github.com/ruby/strscan/issues/135
+ version_is StringScanner::Version, "3.1.1"..."3.1.3" do # ruby_version_is "3.4.0"..."3.4.3"
+ it "ignores the previous matching with Regexp" do
+ @s.exist?(/(?<a>This)/)
+ @s.should.matched?
+ @s[:a].should == "This"
+
+ @s.check("This")
+ @s.should.matched?
+ @s[:a].should == nil
+ end
+ end
+ version_is StringScanner::Version, "3.1.3" do # ruby_version_is "3.4.0"..."3.4.3"
+ it "ignores the previous matching with Regexp" do
+ @s.exist?(/(?<a>This)/)
+ @s.should.matched?
+ @s[:a].should == "This"
+
+ @s.check("This")
+ @s.should.matched?
+ -> { @s[:a] }.should.raise(IndexError)
+ end
+ end
+ end
+ end
end
diff --git a/spec/ruby/library/stringscanner/check_until_spec.rb b/spec/ruby/library/stringscanner/check_until_spec.rb
index 1d89f88a25..b4ef35d9f7 100644
--- a/spec/ruby/library/stringscanner/check_until_spec.rb
+++ b/spec/ruby/library/stringscanner/check_until_spec.rb
@@ -2,22 +2,128 @@ require_relative '../../spec_helper'
require 'strscan'
describe "StringScanner#check_until" do
- before :each do
+ before do
@s = StringScanner.new("This is a test")
end
- it "returns the same value of scan_until, but don't advances the scan pointer" do
+ it "returns the same value of #scan_until, but don't advances the scan pointer" do
@s.check_until(/a/).should == "This is a"
@s.pos.should == 0
- @s.matched.should == "a"
@s.check_until(/test/).should == "This is a test"
end
- ruby_version_is ""..."3.4" do
+ it "sets the last match result" do
+ @s.check_until(/a/)
+
+ @s.pre_match.should == "This is "
+ @s.matched.should == "a"
+ @s.post_match.should == " test"
+ end
+
+ version_is StringScanner::Version, ""..."3.1.1" do # ruby_version_is ""..."3.4"
it "raises TypeError if given a String" do
-> {
@s.check_until('T')
- }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)')
+ }.should.raise(TypeError, 'wrong argument type String (expected Regexp)')
+ end
+ end
+
+ version_is StringScanner::Version, "3.1.1" do # ruby_version_is "3.4"
+ it "searches a substring in the rest part of a string if given a String" do
+ @s.check_until("a").should == "This is a"
+ @s.pos.should == 0
+ end
+
+ # https://github.com/ruby/strscan/issues/131
+ version_is StringScanner::Version, "3.1.1"..."3.1.3" do # ruby_version_is "3.4.1"
+ it "sets the last match result if given a String" do
+ @s.check_until("a")
+
+ @s.pre_match.should == ""
+ @s.matched.should == "This is a"
+ @s.post_match.should == " test"
+ end
+ end
+
+ version_is StringScanner::Version, "3.1.3" do # ruby_version_is "3.4"
+ it "sets the last match result if given a String" do
+ @s.check_until("a")
+
+ @s.pre_match.should == "This is "
+ @s.matched.should == "a"
+ @s.post_match.should == " test"
+ end
+ end
+ end
+
+ describe "#[] successive call with a capture group name" do
+ context "when #check_until was called with a Regexp pattern" do
+ it "returns matched substring when matching succeeded" do
+ @s.check_until(/(?<a>This)/)
+ @s.should.matched?
+ @s[:a].should == "This"
+ end
+
+ it "returns nil when matching failed" do
+ @s.check_until(/(?<a>2008)/)
+ @s.should_not.matched?
+ @s[:a].should == nil
+ end
+ end
+
+ version_is StringScanner::Version, "3.1.1" do # ruby_version_is "3.4"
+ context "when #check_until was called with a String pattern" do
+ # https://github.com/ruby/strscan/issues/139
+ version_is StringScanner::Version, "3.1.1"..."3.1.3" do # ruby_version_is "3.4.0"..."3.4.3"
+ it "returns nil when matching succeeded" do
+ @s.check_until("This")
+ @s.should.matched?
+ @s[:a].should == nil
+ end
+ end
+ version_is StringScanner::Version, "3.1.3" do # ruby_version_is "3.4.3"
+ it "raises IndexError when matching succeeded" do
+ @s.check_until("This")
+ @s.should.matched?
+ -> { @s[:a] }.should.raise(IndexError)
+ end
+ end
+
+ it "returns nil when matching failed" do
+ @s.check_until("2008")
+ @s.should_not.matched?
+ @s[:a].should == nil
+ end
+
+ it "returns a matching substring when given Integer index" do
+ @s.check_until("This")
+ @s[0].should == "This"
+ end
+
+ # https://github.com/ruby/strscan/issues/135
+ version_is StringScanner::Version, "3.1.1"..."3.1.3" do # ruby_version_is "3.4.0"..."3.4.3"
+ it "ignores the previous matching with Regexp" do
+ @s.exist?(/(?<a>This)/)
+ @s.should.matched?
+ @s[:a].should == "This"
+
+ @s.check_until("This")
+ @s.should.matched?
+ @s[:a].should == nil
+ end
+ end
+ version_is StringScanner::Version, "3.1.3" do # ruby_version_is "3.4.0"..."3.4.3"
+ it "ignores the previous matching with Regexp" do
+ @s.exist?(/(?<a>This)/)
+ @s.should.matched?
+ @s[:a].should == "This"
+
+ @s.check_until("This")
+ @s.should.matched?
+ -> { @s[:a] }.should.raise(IndexError)
+ end
+ end
+ end
end
end
end
diff --git a/spec/ruby/library/stringscanner/clear_spec.rb b/spec/ruby/library/stringscanner/clear_spec.rb
deleted file mode 100644
index 7ae089704a..0000000000
--- a/spec/ruby/library/stringscanner/clear_spec.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-require_relative '../../spec_helper'
-require_relative 'shared/terminate'
-require 'strscan'
-
-describe "StringScanner#clear" do
- it_behaves_like :strscan_terminate, :clear
-
- it "warns in verbose mode that the method is obsolete" do
- s = StringScanner.new("abc")
- -> {
- s.clear
- }.should complain(/clear.*obsolete.*terminate/, verbose: true)
-
- -> {
- s.clear
- }.should_not complain(verbose: false)
- end
-end
diff --git a/spec/ruby/library/stringscanner/dup_spec.rb b/spec/ruby/library/stringscanner/dup_spec.rb
index 0fc52a1477..0118964526 100644
--- a/spec/ruby/library/stringscanner/dup_spec.rb
+++ b/spec/ruby/library/stringscanner/dup_spec.rb
@@ -15,7 +15,7 @@ describe "StringScanner#dup" do
it "copies the passed StringScanner's position to self" do
@orig_s.pos = 5
s = @orig_s.dup
- s.pos.should eql(5)
+ s.pos.should.eql?(5)
end
it "copies previous match state" do
@@ -34,6 +34,6 @@ describe "StringScanner#dup" do
it "copies the passed StringScanner scan pointer to self" do
@orig_s.terminate
s = @orig_s.dup
- s.eos?.should be_true
+ s.eos?.should == true
end
end
diff --git a/spec/ruby/library/stringscanner/element_reference_spec.rb b/spec/ruby/library/stringscanner/element_reference_spec.rb
index 60fe15d807..bcd48ede61 100644
--- a/spec/ruby/library/stringscanner/element_reference_spec.rb
+++ b/spec/ruby/library/stringscanner/element_reference_spec.rb
@@ -7,7 +7,8 @@ describe "StringScanner#[]" do
end
it "returns nil if there is no current match" do
- @s[0].should be_nil
+ @s[0].should == nil
+ @s[:wday].should == nil
end
it "returns the n-th subgroup in the most recent match" do
@@ -34,18 +35,24 @@ describe "StringScanner#[]" do
it "raises a TypeError if the given index is nil" do
@s.scan(/(\w+) (\w+) (\d+) /)
- -> { @s[nil]}.should raise_error(TypeError)
+ -> { @s[nil]}.should.raise(TypeError)
end
it "raises a TypeError when a Range is as argument" do
@s.scan(/(\w+) (\w+) (\d+) /)
- -> { @s[0..2]}.should raise_error(TypeError)
+ -> { @s[0..2]}.should.raise(TypeError)
end
- it "raises a IndexError when there's no named capture" do
+ it "raises a IndexError when there's no any named capture group in the regexp" do
@s.scan(/(\w+) (\w+) (\d+) /)
- -> { @s["wday"]}.should raise_error(IndexError)
- -> { @s[:wday]}.should raise_error(IndexError)
+ -> { @s["wday"]}.should.raise(IndexError)
+ -> { @s[:wday]}.should.raise(IndexError)
+ end
+
+ it "raises a IndexError when given a not existing capture group name" do
+ @s.scan(/(?<a>\w+) (?<b>\w+) (?<c>\d+) /)
+ -> { @s["wday"]}.should.raise(IndexError)
+ -> { @s[:wday]}.should.raise(IndexError)
end
it "returns named capture" do
diff --git a/spec/ruby/library/stringscanner/empty_spec.rb b/spec/ruby/library/stringscanner/empty_spec.rb
deleted file mode 100644
index d9449bea6e..0000000000
--- a/spec/ruby/library/stringscanner/empty_spec.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-require_relative '../../spec_helper'
-require_relative 'shared/eos'
-require 'strscan'
-
-describe "StringScanner#empty?" do
- it_behaves_like :strscan_eos, :empty?
-
- it "warns in verbose mode that the method is obsolete" do
- s = StringScanner.new("abc")
- -> {
- s.empty?
- }.should complain(/empty?.*obsolete.*eos?/, verbose: true)
-
- -> {
- s.empty?
- }.should_not complain(verbose: false)
- end
-end
diff --git a/spec/ruby/library/stringscanner/eos_spec.rb b/spec/ruby/library/stringscanner/eos_spec.rb
index b58ee1e473..03c2804e5b 100644
--- a/spec/ruby/library/stringscanner/eos_spec.rb
+++ b/spec/ruby/library/stringscanner/eos_spec.rb
@@ -1,7 +1,20 @@
require_relative '../../spec_helper'
-require_relative 'shared/eos'
require 'strscan'
describe "StringScanner#eos?" do
- it_behaves_like :strscan_eos, :eos?
+ before :each do
+ @s = StringScanner.new("This is a test")
+ end
+
+ it "returns true if the scan pointer is at the end of the string" do
+ @s.terminate
+ @s.should.eos?
+
+ s = StringScanner.new('')
+ s.should.eos?
+ end
+
+ it "returns false if the scan pointer is not at the end of the string" do
+ @s.should_not.eos?
+ end
end
diff --git a/spec/ruby/library/stringscanner/exist_spec.rb b/spec/ruby/library/stringscanner/exist_spec.rb
index a18f5ce352..2207622366 100644
--- a/spec/ruby/library/stringscanner/exist_spec.rb
+++ b/spec/ruby/library/stringscanner/exist_spec.rb
@@ -2,11 +2,11 @@ require_relative '../../spec_helper'
require 'strscan'
describe "StringScanner#exist?" do
- before :each do
+ before do
@s = StringScanner.new("This is a test")
end
- it "returns the index of the first occurrence of the given pattern" do
+ it "returns distance in bytes between the current position and the end of the matched substring" do
@s.exist?(/s/).should == 4
@s.scan(/This is/)
@s.exist?(/s/).should == 6
@@ -22,11 +22,98 @@ describe "StringScanner#exist?" do
@s.exist?(/i/).should == nil
end
- ruby_version_is ""..."3.4" do
+ it "does not modify the current position" do
+ @s.pos.should == 0
+ @s.exist?(/s/).should == 4
+ @s.pos.should == 0
+ end
+
+ version_is StringScanner::Version, ""..."3.1.1" do # ruby_version_is ""..."3.4"
it "raises TypeError if given a String" do
-> {
@s.exist?('T')
- }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)')
+ }.should.raise(TypeError, 'wrong argument type String (expected Regexp)')
+ end
+ end
+
+ version_is StringScanner::Version, "3.1.1" do # ruby_version_is "3.4"
+ it "searches a substring in the rest part of a string if given a String" do
+ @s.exist?('a').should == 9
+ end
+
+ it "returns nil if the pattern isn't found in the string" do
+ @s.exist?("S").should == nil
+ end
+ end
+
+ describe "#[] successive call with a capture group name" do
+ context "when #exist? was called with a Regexp pattern" do
+ it "returns matched substring when matching succeeded" do
+ @s.exist?(/(?<a>This)/)
+ @s.should.matched?
+ @s[:a].should == "This"
+ end
+
+ it "returns nil when matching failed" do
+ @s.exist?(/(?<a>2008)/)
+ @s.should_not.matched?
+ @s[:a].should == nil
+ end
+ end
+
+ version_is StringScanner::Version, "3.1.1" do # ruby_version_is "3.4"
+ context "when #exist? was called with a String pattern" do
+ # https://github.com/ruby/strscan/issues/139
+ version_is StringScanner::Version, "3.1.1"..."3.1.3" do # ruby_version_is "3.4.0"..."3.4.3"
+ it "returns nil when matching succeeded" do
+ @s.exist?("This")
+ @s.should.matched?
+ @s[:a].should == nil
+ end
+ end
+ version_is StringScanner::Version, "3.1.3" do # ruby_version_is "3.4.3"
+ it "raises IndexError when matching succeeded" do
+ @s.exist?("This")
+ @s.should.matched?
+ -> { @s[:a] }.should.raise(IndexError)
+ end
+ end
+
+ it "returns nil when matching failed" do
+ @s.exist?("2008")
+ @s.should_not.matched?
+ @s[:a].should == nil
+ end
+
+ it "returns a matching substring when given Integer index" do
+ @s.exist?("This")
+ @s[0].should == "This"
+ end
+
+ # https://github.com/ruby/strscan/issues/135
+ version_is StringScanner::Version, "3.1.1"..."3.1.3" do # ruby_version_is "3.4.0"..."3.4.3"
+ it "ignores the previous matching with Regexp" do
+ @s.exist?(/(?<a>This)/)
+ @s.should.matched?
+ @s[:a].should == "This"
+
+ @s.exist?("This")
+ @s.should.matched?
+ @s[:a].should == nil
+ end
+ end
+ version_is StringScanner::Version, "3.1.3" do # ruby_version_is "3.4.0"..."3.4.3"
+ it "ignores the previous matching with Regexp" do
+ @s.exist?(/(?<a>This)/)
+ @s.should.matched?
+ @s[:a].should == "This"
+
+ @s.exist?("This")
+ @s.should.matched?
+ -> { @s[:a] }.should.raise(IndexError)
+ end
+ end
+ end
end
end
end
diff --git a/spec/ruby/library/stringscanner/fixed_anchor_spec.rb b/spec/ruby/library/stringscanner/fixed_anchor_spec.rb
new file mode 100644
index 0000000000..ce0b714fa8
--- /dev/null
+++ b/spec/ruby/library/stringscanner/fixed_anchor_spec.rb
@@ -0,0 +1,17 @@
+require_relative '../../spec_helper'
+require 'strscan'
+
+describe "StringScanner#fixed_anchor?" do
+ it "returns whether the fixed-anchor property is set" do
+ s = StringScanner.new("foo", fixed_anchor: true)
+ s.should.fixed_anchor?
+
+ s = StringScanner.new("foo", fixed_anchor: false)
+ s.should_not.fixed_anchor?
+ end
+
+ it "is set to false by default" do
+ s = StringScanner.new("foo")
+ s.should_not.fixed_anchor?
+ end
+end
diff --git a/spec/ruby/library/stringscanner/get_byte_spec.rb b/spec/ruby/library/stringscanner/get_byte_spec.rb
index 29e2f557de..b989b73883 100644
--- a/spec/ruby/library/stringscanner/get_byte_spec.rb
+++ b/spec/ruby/library/stringscanner/get_byte_spec.rb
@@ -1,7 +1,84 @@
+# encoding: binary
require_relative '../../spec_helper'
-require_relative 'shared/get_byte'
require 'strscan'
describe "StringScanner#get_byte" do
- it_behaves_like :strscan_get_byte, :get_byte
+ it "scans one byte and returns it" do
+ s = StringScanner.new('abc5.')
+ s.get_byte.should == 'a'
+ s.get_byte.should == 'b'
+ s.get_byte.should == 'c'
+ s.get_byte.should == '5'
+ s.get_byte.should == '.'
+ end
+
+ it "is not multi-byte character sensitive" do
+ s = StringScanner.new("\244\242")
+ s.get_byte.should == "\244"
+ s.get_byte.should == "\242"
+ end
+
+ it "returns nil at the end of the string" do
+ # empty string case
+ s = StringScanner.new('')
+ s.get_byte.should == nil
+ s.get_byte.should == nil
+
+ # non-empty string case
+ s = StringScanner.new('a')
+ s.get_byte # skip one
+ s.get_byte.should == nil
+ end
+
+ describe "#[] successive call with a capture group name" do
+ # https://github.com/ruby/strscan/issues/139
+ version_is StringScanner::Version, "3.1.1"..."3.1.3" do # ruby_version_is "3.4.0"..."3.4.3"
+ it "returns nil" do
+ s = StringScanner.new("This is a test")
+ s.get_byte
+ s.should.matched?
+ s[:a].should == nil
+ end
+ end
+ version_is StringScanner::Version, "3.1.3" do # ruby_version_is "3.4.3"
+ it "raises IndexError" do
+ s = StringScanner.new("This is a test")
+ s.get_byte
+ s.should.matched?
+ -> { s[:a] }.should.raise(IndexError)
+ end
+ end
+
+ it "returns a matching character when given Integer index" do
+ s = StringScanner.new("This is a test")
+ s.get_byte
+ s[0].should == "T"
+ end
+
+ # https://github.com/ruby/strscan/issues/135
+ version_is StringScanner::Version, "3.1.1"..."3.1.3" do # ruby_version_is "3.4.0"..."3.4.3"
+ it "ignores the previous matching with Regexp" do
+ s = StringScanner.new("This is a test")
+ s.exist?(/(?<a>This)/)
+ s.should.matched?
+ s[:a].should == "This"
+
+ s.get_byte
+ s.should.matched?
+ s[:a].should == nil
+ end
+ end
+ version_is StringScanner::Version, "3.1.3" do # ruby_version_is "3.4.3"
+ it "ignores the previous matching with Regexp" do
+ s = StringScanner.new("This is a test")
+ s.exist?(/(?<a>This)/)
+ s.should.matched?
+ s[:a].should == "This"
+
+ s.get_byte
+ s.should.matched?
+ -> { s[:a] }.should.raise(IndexError)
+ end
+ end
+ end
end
diff --git a/spec/ruby/library/stringscanner/getbyte_spec.rb b/spec/ruby/library/stringscanner/getbyte_spec.rb
deleted file mode 100644
index e0659a5829..0000000000
--- a/spec/ruby/library/stringscanner/getbyte_spec.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-require_relative '../../spec_helper'
-require_relative 'shared/get_byte'
-require_relative 'shared/extract_range'
-require 'strscan'
-
-describe "StringScanner#getbyte" do
- it_behaves_like :strscan_get_byte, :getbyte
-
- it "warns in verbose mode that the method is obsolete" do
- s = StringScanner.new("abc")
- -> {
- s.getbyte
- }.should complain(/getbyte.*obsolete.*get_byte/, verbose: true)
-
- -> {
- s.getbyte
- }.should_not complain(verbose: false)
- end
-
- it_behaves_like :extract_range, :getbyte
-end
diff --git a/spec/ruby/library/stringscanner/getch_spec.rb b/spec/ruby/library/stringscanner/getch_spec.rb
index 449c20ad3b..cd41b4336a 100644
--- a/spec/ruby/library/stringscanner/getch_spec.rb
+++ b/spec/ruby/library/stringscanner/getch_spec.rb
@@ -1,4 +1,4 @@
-# -*- encoding: binary -*-
+# encoding: binary
require_relative '../../spec_helper'
require_relative 'shared/extract_range'
require 'strscan'
@@ -11,6 +11,13 @@ describe "StringScanner#getch" do
s.getch.should == "c"
end
+ it "scans newlines too" do
+ s = StringScanner.new("a\nc")
+ s.getch.should == "a"
+ s.getch.should == "\n"
+ s.getch.should == "c"
+ end
+
it "is multi-byte character sensitive" do
# Japanese hiragana "A" in EUC-JP
src = "\244\242".dup.force_encoding("euc-jp")
@@ -31,5 +38,59 @@ describe "StringScanner#getch" do
s.getch.should == nil
end
+ describe "#[] successive call with a capture group name" do
+ # https://github.com/ruby/strscan/issues/139
+ version_is StringScanner::Version, "3.1.1"..."3.1.3" do # ruby_version_is "3.4.0"..."3.4.3"
+ it "returns nil" do
+ s = StringScanner.new("This is a test")
+ s.getch
+ s.should.matched?
+ s[:a].should == nil
+ end
+ end
+ version_is StringScanner::Version, "3.1.3" do # ruby_version_is "3.4.3"
+ it "raises IndexError" do
+ s = StringScanner.new("This is a test")
+ s.getch
+ s.should.matched?
+ -> { s[:a] }.should.raise(IndexError)
+ end
+ end
+
+ it "returns a matching character when given Integer index" do
+ s = StringScanner.new("This is a test")
+ s.getch
+ s[0].should == "T"
+ end
+
+ # https://github.com/ruby/strscan/issues/135
+ version_is StringScanner::Version, "3.1.1"..."3.1.3" do # ruby_version_is "3.4.0"..."3.4.3"
+ it "ignores the previous matching with Regexp" do
+ s = StringScanner.new("This is a test")
+
+ s.exist?(/(?<a>This)/)
+ s.should.matched?
+ s[:a].should == "This"
+
+ s.getch
+ s.should.matched?
+ s[:a].should == nil
+ end
+ end
+ version_is StringScanner::Version, "3.1.3" do # ruby_version_is "3.4.0"..."3.4.3"
+ it "ignores the previous matching with Regexp" do
+ s = StringScanner.new("This is a test")
+
+ s.exist?(/(?<a>This)/)
+ s.should.matched?
+ s[:a].should == "This"
+
+ s.getch
+ s.should.matched?
+ -> { s[:a] }.should.raise(IndexError)
+ end
+ end
+ end
+
it_behaves_like :extract_range, :getch
end
diff --git a/spec/ruby/library/stringscanner/initialize_spec.rb b/spec/ruby/library/stringscanner/initialize_spec.rb
index 047d9d058b..fdab4d381c 100644
--- a/spec/ruby/library/stringscanner/initialize_spec.rb
+++ b/spec/ruby/library/stringscanner/initialize_spec.rb
@@ -7,12 +7,12 @@ describe "StringScanner#initialize" do
end
it "is a private method" do
- StringScanner.should have_private_instance_method(:initialize)
+ StringScanner.private_instance_methods(false).should.include?(:initialize)
end
it "returns an instance of StringScanner" do
- @s.should be_kind_of(StringScanner)
- @s.eos?.should be_false
+ @s.should.is_a?(StringScanner)
+ @s.eos?.should == false
end
it "converts the argument into a string using #to_str" do
@@ -24,4 +24,9 @@ describe "StringScanner#initialize" do
scan = StringScanner.new(m)
scan.string.should == s
end
+
+ it "accepts a fixed_anchor keyword argument" do
+ s = StringScanner.new("foo", fixed_anchor: true)
+ s.should.fixed_anchor?
+ end
end
diff --git a/spec/ruby/library/stringscanner/inspect_spec.rb b/spec/ruby/library/stringscanner/inspect_spec.rb
index ff6b97eb91..570d0b7b10 100644
--- a/spec/ruby/library/stringscanner/inspect_spec.rb
+++ b/spec/ruby/library/stringscanner/inspect_spec.rb
@@ -7,7 +7,7 @@ describe "StringScanner#inspect" do
end
it "returns a String object" do
- @s.inspect.should be_kind_of(String)
+ @s.inspect.should.is_a?(String)
end
it "returns a string that represents the StringScanner object" do
diff --git a/spec/ruby/library/stringscanner/match_spec.rb b/spec/ruby/library/stringscanner/match_spec.rb
index ec59680914..c2bc49324b 100644
--- a/spec/ruby/library/stringscanner/match_spec.rb
+++ b/spec/ruby/library/stringscanner/match_spec.rb
@@ -17,6 +17,15 @@ describe "StringScanner#match?" do
@s.match?(/\s+/).should == nil
end
+ it "sets the last match result" do
+ @s.pos = 8
+ @s.match?(/a/)
+
+ @s.pre_match.should == "This is "
+ @s.matched.should == "a"
+ @s.post_match.should == " test"
+ end
+
it "effects pre_match" do
@s.scan(/\w+/)
@s.scan(/\s/)
@@ -25,4 +34,18 @@ describe "StringScanner#match?" do
@s.match?(/\w+/)
@s.pre_match.should == "This "
end
+
+ describe "#[] successive call with a capture group name" do
+ it "returns matched substring when matching succeeded" do
+ @s.match?(/(?<a>This)/)
+ @s.should.matched?
+ @s[:a].should == "This"
+ end
+
+ it "returns nil when matching failed" do
+ @s.match?(/(?<a>2008)/)
+ @s.should_not.matched?
+ @s[:a].should == nil
+ end
+ end
end
diff --git a/spec/ruby/library/stringscanner/matched_spec.rb b/spec/ruby/library/stringscanner/matched_spec.rb
index c020bd3eae..95b57574c5 100644
--- a/spec/ruby/library/stringscanner/matched_spec.rb
+++ b/spec/ruby/library/stringscanner/matched_spec.rb
@@ -31,11 +31,11 @@ describe "StringScanner#matched?" do
it "returns true if the last match was successful" do
@s.match?(/\w+/)
- @s.matched?.should be_true
+ @s.matched?.should == true
end
it "returns false if there's no match" do
@s.match?(/\d+/)
- @s.matched?.should be_false
+ @s.matched?.should == false
end
end
diff --git a/spec/ruby/library/stringscanner/must_C_version_spec.rb b/spec/ruby/library/stringscanner/must_C_version_spec.rb
index fcc5b596f6..9d6edfe7b6 100644
--- a/spec/ruby/library/stringscanner/must_C_version_spec.rb
+++ b/spec/ruby/library/stringscanner/must_C_version_spec.rb
@@ -3,6 +3,6 @@ require 'strscan'
describe "StringScanner.must_C_version" do
it "returns self" do
- StringScanner.must_C_version.should == StringScanner
+ StringScanner.must_C_version.should == StringScanner
end
end
diff --git a/spec/ruby/library/stringscanner/named_captures_spec.rb b/spec/ruby/library/stringscanner/named_captures_spec.rb
new file mode 100644
index 0000000000..927784a6c4
--- /dev/null
+++ b/spec/ruby/library/stringscanner/named_captures_spec.rb
@@ -0,0 +1,28 @@
+require_relative '../../spec_helper'
+require 'strscan'
+
+describe "StringScanner#named_captures" do
+ before do
+ @s = StringScanner.new('Fri Dec 12 1975 14:39')
+ end
+
+ it "returns a hash of names and matched substrings for named capturing groups in a regular expression of the most recent matching" do
+ @s.exist?(/(?<wday>\w+) (?<month>\w+) (?<day>\d+)/)
+ @s.named_captures.should == {"wday" => "Fri", "month" => "Dec", "day" => "12"}
+ end
+
+ it "returns {} if there are no named capturing groups" do
+ @s.exist?(/(\w+) (\w+) (\d+)/)
+ @s.named_captures.should == {}
+ end
+
+ # https://github.com/ruby/strscan/issues/132 fixed in strscan v3.0.7
+ it "returns {} if there is no any matching done" do
+ @s.named_captures.should == {}
+ end
+
+ it "returns nil for an optional named capturing group if it doesn't match" do
+ @s.exist?(/(?<wday>\w+) (?<month>\w+) (?<day>\s+)?/)
+ @s.named_captures.should == {"wday" => "Fri", "month" => "Dec", "day" => nil}
+ end
+end
diff --git a/spec/ruby/library/stringscanner/peek_byte_spec.rb b/spec/ruby/library/stringscanner/peek_byte_spec.rb
new file mode 100644
index 0000000000..88ef4a2b7c
--- /dev/null
+++ b/spec/ruby/library/stringscanner/peek_byte_spec.rb
@@ -0,0 +1,35 @@
+require_relative '../../spec_helper'
+require 'strscan'
+
+version_is StringScanner::Version, "3.1.1" do # ruby_version_is "3.4"
+ describe "StringScanner#peek_byte" do
+ it "returns a byte at the current position as an Integer" do
+ s = StringScanner.new('This is a test')
+ s.peek_byte.should == 84
+ end
+
+ it "returns nil at the end of the string" do
+ s = StringScanner.new('a')
+ s.getch # skip one
+ s.pos.should == 1
+ s.peek_byte.should == nil
+ end
+
+ it "is not multi-byte character sensitive" do
+ s = StringScanner.new("∂") # "∂".bytes => [226, 136, 130]
+ s.peek_byte.should == 226
+ s.pos = 1
+ s.peek_byte.should == 136
+ s.pos = 2
+ s.peek_byte.should == 130
+ end
+
+ it "doesn't change current position" do
+ s = StringScanner.new('This is a test')
+
+ s.pos.should == 0
+ s.peek_byte.should == 84
+ s.pos.should == 0
+ end
+ end
+end
diff --git a/spec/ruby/library/stringscanner/peek_spec.rb b/spec/ruby/library/stringscanner/peek_spec.rb
index cbb5630ff9..5b54c6be0b 100644
--- a/spec/ruby/library/stringscanner/peek_spec.rb
+++ b/spec/ruby/library/stringscanner/peek_spec.rb
@@ -1,7 +1,42 @@
require_relative '../../spec_helper'
-require_relative 'shared/peek'
require 'strscan'
describe "StringScanner#peek" do
- it_behaves_like :strscan_peek, :peek
+ before :each do
+ @s = StringScanner.new('This is a test')
+ end
+
+ it "returns at most the specified number of bytes from the current position" do
+ @s.peek(4).should == "This"
+ @s.pos.should == 0
+ @s.pos = 5
+ @s.peek(2).should == "is"
+ @s.peek(1000).should == "is a test"
+
+ s = StringScanner.new("été")
+ s.peek(2).should == "é"
+ end
+
+ it "returns an empty string when the passed argument is zero" do
+ @s.peek(0).should == ""
+ end
+
+ it "raises a ArgumentError when the passed argument is negative" do
+ -> { @s.peek(-2) }.should.raise(ArgumentError)
+ end
+
+ it "raises a RangeError when the passed argument is a Bignum" do
+ -> { @s.peek(bignum_value) }.should.raise(RangeError)
+ end
+
+ it "returns an instance of String when passed a String subclass" do
+ cls = Class.new(String)
+ sub = cls.new("abc")
+
+ s = StringScanner.new(sub)
+
+ ch = s.peek(1)
+ ch.should_not.is_a?(cls)
+ ch.should.instance_of?(String)
+ end
end
diff --git a/spec/ruby/library/stringscanner/peep_spec.rb b/spec/ruby/library/stringscanner/peep_spec.rb
deleted file mode 100644
index bf6d579325..0000000000
--- a/spec/ruby/library/stringscanner/peep_spec.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-require_relative '../../spec_helper'
-require_relative 'shared/peek'
-require 'strscan'
-
-describe "StringScanner#peep" do
- it_behaves_like :strscan_peek, :peep
-
- it "warns in verbose mode that the method is obsolete" do
- s = StringScanner.new("abc")
- -> {
- s.peep(1)
- }.should complain(/peep.*obsolete.*peek/, verbose: true)
-
- -> {
- s.peep(1)
- }.should_not complain(verbose: false)
- end
-end
diff --git a/spec/ruby/library/stringscanner/rest_size_spec.rb b/spec/ruby/library/stringscanner/rest_size_spec.rb
index e62e3a8f8c..65d3b50e08 100644
--- a/spec/ruby/library/stringscanner/rest_size_spec.rb
+++ b/spec/ruby/library/stringscanner/rest_size_spec.rb
@@ -1,7 +1,30 @@
require_relative '../../spec_helper'
-require_relative 'shared/rest_size'
require 'strscan'
describe "StringScanner#rest_size" do
- it_behaves_like :strscan_rest_size, :rest_size
+ before :each do
+ @s = StringScanner.new('This is a test')
+ end
+
+ it "returns the length of the rest of the string" do
+ @s.rest_size.should == 14
+ @s.scan(/This/)
+ @s.rest_size.should == 10
+ @s.terminate
+ @s.rest_size.should == 0
+ end
+
+ it "is equivalent to rest.bytesize" do
+ @s.scan(/This/)
+ @s.rest_size.should == @s.rest.bytesize
+
+ s = StringScanner.new('été')
+ s.rest_size.should == 5
+ s.scan(/./)
+ s.rest_size.should == 3
+ s.scan(/./)
+ s.rest_size.should == 2
+ s.scan(/./)
+ s.rest_size.should == 0
+ end
end
diff --git a/spec/ruby/library/stringscanner/rest_spec.rb b/spec/ruby/library/stringscanner/rest_spec.rb
index 67072f880d..40f073058c 100644
--- a/spec/ruby/library/stringscanner/rest_spec.rb
+++ b/spec/ruby/library/stringscanner/rest_spec.rb
@@ -32,14 +32,14 @@ describe "StringScanner#rest?" do
end
it "returns true if there is more data in the string" do
- @s.rest?.should be_true
+ @s.rest?.should == true
@s.scan(/This/)
- @s.rest?.should be_true
+ @s.rest?.should == true
end
it "returns false if there is no more data in the string" do
@s.terminate
- @s.rest?.should be_false
+ @s.rest?.should == false
end
it "is the opposite of eos?" do
diff --git a/spec/ruby/library/stringscanner/restsize_spec.rb b/spec/ruby/library/stringscanner/restsize_spec.rb
deleted file mode 100644
index 710520afae..0000000000
--- a/spec/ruby/library/stringscanner/restsize_spec.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-require_relative '../../spec_helper'
-require_relative 'shared/rest_size'
-require 'strscan'
-
-describe "StringScanner#restsize" do
- it_behaves_like :strscan_rest_size, :restsize
-
- it "warns in verbose mode that the method is obsolete" do
- s = StringScanner.new("abc")
- -> {
- s.restsize
- }.should complain(/restsize.*obsolete.*rest_size/, verbose: true)
-
- -> {
- s.restsize
- }.should_not complain(verbose: false)
- end
-end
diff --git a/spec/ruby/library/stringscanner/scan_byte_spec.rb b/spec/ruby/library/stringscanner/scan_byte_spec.rb
new file mode 100644
index 0000000000..8fd77270e4
--- /dev/null
+++ b/spec/ruby/library/stringscanner/scan_byte_spec.rb
@@ -0,0 +1,98 @@
+require_relative '../../spec_helper'
+require 'strscan'
+
+version_is StringScanner::Version, "3.1.1" do # ruby_version_is "3.4"
+ describe "StringScanner#scan_byte" do
+ it "scans one byte and returns it as on Integer" do
+ s = StringScanner.new('abc') # "abc".bytes => [97, 98, 99]
+ s.scan_byte.should == 97
+ s.scan_byte.should == 98
+ s.scan_byte.should == 99
+ end
+
+ it "is not multi-byte character sensitive" do
+ s = StringScanner.new("あ") # "あ".bytes => [227, 129, 130]
+ s.scan_byte.should == 227
+ s.scan_byte.should == 129
+ s.scan_byte.should == 130
+ end
+
+ it "returns nil at the end of the string" do
+ s = StringScanner.new('a')
+ s.scan_byte # skip one
+ s.scan_byte.should == nil
+ s.pos.should == 1
+ end
+
+ it "changes current position" do
+ s = StringScanner.new('abc')
+ s.pos.should == 0
+ s.scan_byte
+ s.pos.should == 1
+ end
+
+ it "sets the last match result" do
+ s = StringScanner.new('abc')
+ s.pos = 1
+ s.scan_byte
+
+ s.pre_match.should == "a"
+ s.matched.should == "b"
+ s.post_match.should == "c"
+ end
+
+ describe "#[] successive call with a capture group name" do
+ # https://github.com/ruby/strscan/issues/139
+ version_is StringScanner::Version, "3.1.1"..."3.1.3" do # ruby_version_is "3.4.0"..."3.4.3"
+ it "returns nil" do
+ s = StringScanner.new("abc")
+ s.scan_byte
+ s.should.matched?
+ s[:a].should == nil
+ end
+ end
+ version_is StringScanner::Version, "3.1.3" do # ruby_version_is "3.4.3"
+ it "raises IndexError" do
+ s = StringScanner.new("abc")
+ s.scan_byte
+ s.should.matched?
+ -> { s[:a] }.should.raise(IndexError)
+ end
+ end
+
+ it "returns a matching character when given Integer index" do
+ s = StringScanner.new("This is a test")
+ s.scan_byte
+ s[0].should == "T"
+ end
+
+ # https://github.com/ruby/strscan/issues/135
+ version_is StringScanner::Version, "3.1.1"..."3.1.3" do # ruby_version_is "3.4.0"..."3.4.3"
+ it "ignores the previous matching with Regexp" do
+ s = StringScanner.new("abc")
+
+ s.exist?(/(?<a>a)/)
+ s.should.matched?
+ s[:a].should == "a"
+
+ s.scan_byte
+ s.should.matched?
+ s[:a].should == nil
+ end
+ end
+ version_is StringScanner::Version, "3.1.3" do # ruby_version_is "3.4.0"..."3.4.3"
+ it "ignores the previous matching with Regexp" do
+ s = StringScanner.new("abc")
+
+ s.exist?(/(?<a>a)/)
+ s.should.matched?
+ s[:a].should == "a"
+
+ s.scan_byte
+ s.should.matched?
+ -> { s[:a] }.should.raise(IndexError)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/ruby/library/stringscanner/scan_full_spec.rb b/spec/ruby/library/stringscanner/scan_full_spec.rb
index ed34d7d3f6..7633c17860 100644
--- a/spec/ruby/library/stringscanner/scan_full_spec.rb
+++ b/spec/ruby/library/stringscanner/scan_full_spec.rb
@@ -27,4 +27,18 @@ describe "StringScanner#scan_full" do
@s.scan_full(/This/, true, true).should == "This"
@s.pos.should == 4
end
+
+ describe "#[] successive call with a capture group name" do
+ it "returns matched substring when matching succeeded" do
+ @s.scan_full(/(?<a>This)/, false, false)
+ @s.should.matched?
+ @s[:a].should == "This"
+ end
+
+ it "returns nil when matching failed" do
+ @s.scan_full(/(?<a>2008)/, false, false)
+ @s.should_not.matched?
+ @s[:a].should == nil
+ end
+ end
end
diff --git a/spec/ruby/library/stringscanner/scan_integer_spec.rb b/spec/ruby/library/stringscanner/scan_integer_spec.rb
new file mode 100644
index 0000000000..d83149344a
--- /dev/null
+++ b/spec/ruby/library/stringscanner/scan_integer_spec.rb
@@ -0,0 +1,157 @@
+require_relative '../../spec_helper'
+require 'strscan'
+
+version_is StringScanner::Version, "3.1.1" do # ruby_version_is "3.4"
+ describe "StringScanner#scan_integer" do
+ it "returns the matched Integer literal starting from the current position" do
+ s = StringScanner.new("42")
+ s.scan_integer.should == 42
+ end
+
+ it "returns nil when no Integer literal matched starting from the current position" do
+ s = StringScanner.new("a42")
+ s.scan_integer.should == nil
+ end
+
+ it "supports a sign +/-" do
+ StringScanner.new("+42").scan_integer.should == 42
+ StringScanner.new("-42").scan_integer.should == -42
+ end
+
+ it "changes the current position" do
+ s = StringScanner.new("42abc")
+ s.scan_integer
+ s.pos.should == 2
+ end
+
+ # https://github.com/ruby/strscan/issues/130
+ ruby_bug "", "3.4"..."4.0" do # introduced in strscan v3.1.1
+ it "sets the last match result" do
+ s = StringScanner.new("42abc")
+ s.scan_integer
+
+ s.should.matched?
+ s.matched.should == "42"
+ s.pre_match.should == ""
+ s.post_match.should == "abc"
+ s.matched_size.should == 2
+ end
+ end
+
+ it "raises Encoding::CompatibilityError when a scanned string not is ASCII-compatible encoding" do
+ string = "42".encode(Encoding::UTF_16BE)
+ s = StringScanner.new(string)
+
+ -> {
+ s.scan_integer
+ }.should.raise(Encoding::CompatibilityError, /ASCII incompatible encoding: UTF-16BE|incompatible encoding regexp match/)
+ end
+
+ context "given base" do
+ it "supports base: 10" do
+ s = StringScanner.new("42")
+ s.scan_integer(base: 10).should == 42
+ end
+
+ it "supports base: 16" do
+ StringScanner.new("0xff").scan_integer(base: 16).should == 0xff
+ StringScanner.new("-0xff").scan_integer(base: 16).should == -0xff
+ StringScanner.new("0xFF").scan_integer(base: 16).should == 0xff
+ StringScanner.new("-0xFF").scan_integer(base: 16).should == -0xff
+ StringScanner.new("ff").scan_integer(base: 16).should == 0xff
+ StringScanner.new("-ff").scan_integer(base: 16).should == -0xff
+ end
+
+ it "raises ArgumentError when passed not supported base" do
+ -> {
+ StringScanner.new("42").scan_integer(base: 5)
+ }.should.raise(ArgumentError, "Unsupported integer base: 5, expected 10 or 16")
+ end
+
+ version_is StringScanner::Version, "3.1.1"..."3.1.3" do # ruby_version_is "3.4.0"..."3.4.3"
+ it "does not match '0x' prefix on its own" do
+ StringScanner.new("0x").scan_integer(base: 16).should == nil
+ StringScanner.new("-0x").scan_integer(base: 16).should == nil
+ StringScanner.new("+0x").scan_integer(base: 16).should == nil
+ end
+ end
+
+ version_is StringScanner::Version, "3.1.3" do # ruby_version_is "3.4.3"
+ it "matches '0' in a '0x' that is followed by non-hex characters" do
+ StringScanner.new("0x!@#").scan_integer(base: 16).should == 0
+ StringScanner.new("-0x!@#").scan_integer(base: 16).should == 0
+ StringScanner.new("+0x!@#").scan_integer(base: 16).should == 0
+ end
+
+ it "matches '0' in a '0x' located in the end of a string" do
+ StringScanner.new("0x").scan_integer(base: 16).should == 0
+ StringScanner.new("-0x").scan_integer(base: 16).should == 0
+ StringScanner.new("+0x").scan_integer(base: 16).should == 0
+ end
+ end
+ end
+ end
+
+ describe "#[] successive call with a capture group name" do
+ # https://github.com/ruby/strscan/issues/139
+ version_is StringScanner::Version, "3.1.1"..."3.1.3" do # ruby_version_is "3.4.0"..."3.4.3"
+ it "returns nil substring when matching succeeded" do
+ s = StringScanner.new("42")
+ s.scan_integer
+ s.should.matched?
+ s[:a].should == nil
+ end
+ end
+ version_is StringScanner::Version, "3.1.3" do # ruby_version_is "3.4.3"
+ it "raises IndexError when matching succeeded" do
+ s = StringScanner.new("42")
+ s.scan_integer
+ s.should.matched?
+ -> { s[:a] }.should.raise(IndexError)
+ end
+ end
+
+ it "returns nil when matching failed" do
+ s = StringScanner.new("a42")
+ s.scan_integer
+ s.should_not.matched?
+ s[:a].should == nil
+ end
+
+ version_is StringScanner::Version, "3.1.3" do # ruby_version_is "3.4"
+ it "returns a matching substring when given Integer index" do
+ s = StringScanner.new("42")
+ s.scan_integer
+ s[0].should == "42"
+ end
+ end
+
+ # https://github.com/ruby/strscan/issues/135
+ version_is StringScanner::Version, "3.1.1"..."3.1.3" do # ruby_version_is "3.4.0"..."3.4.3"
+ it "does not ignore the previous matching with Regexp" do
+ s = StringScanner.new("42")
+
+ s.exist?(/(?<a>42)/)
+ s.should.matched?
+ s[:a].should == "42"
+
+ s.scan_integer
+ s.should.matched?
+ s[:a].should == "42"
+ end
+ end
+ version_is StringScanner::Version, "3.1.3" do # ruby_version_is "3.4"
+ it "ignores the previous matching with Regexp" do
+ s = StringScanner.new("42")
+
+ s.exist?(/(?<a>42)/)
+ s.should.matched?
+ s[:a].should == "42"
+
+ s.scan_integer
+ s.should.matched?
+ -> { s[:a] }.should.raise(IndexError)
+ end
+ end
+ end
+end
diff --git a/spec/ruby/library/stringscanner/scan_spec.rb b/spec/ruby/library/stringscanner/scan_spec.rb
index ea711767b9..ee8a9eb103 100644
--- a/spec/ruby/library/stringscanner/scan_spec.rb
+++ b/spec/ruby/library/stringscanner/scan_spec.rb
@@ -15,7 +15,7 @@ describe "StringScanner#scan" do
it "treats ^ as matching from the beginning of the current position" do
@s.scan(/\w+/).should == "This"
- @s.scan(/^\d/).should be_nil
+ @s.scan(/^\d/).should == nil
@s.scan(/^\s/).should == " "
end
@@ -26,7 +26,7 @@ describe "StringScanner#scan" do
it "treats \\A as matching from the beginning of the current position" do
@s.scan(/\w+/).should == "This"
- @s.scan(/\A\d/).should be_nil
+ @s.scan(/\A\d/).should == nil
@s.scan(/\A\s/).should == " "
end
@@ -41,24 +41,38 @@ describe "StringScanner#scan" do
it "returns nil when there is no more to scan" do
@s.scan(/[\w\s]+/).should == "This is a test"
- @s.scan(/\w+/).should be_nil
+ @s.scan(/\w+/).should == nil
end
it "returns an empty string when the pattern matches empty" do
@s.scan(/.*/).should == "This is a test"
@s.scan(/.*/).should == ""
- @s.scan(/./).should be_nil
+ @s.scan(/./).should == nil
end
it "treats String as the pattern itself" do
- @s.scan("this").should be_nil
+ @s.scan("this").should == nil
@s.scan("This").should == "This"
end
it "raises a TypeError if pattern isn't a Regexp nor String" do
- -> { @s.scan(5) }.should raise_error(TypeError)
- -> { @s.scan(:test) }.should raise_error(TypeError)
- -> { @s.scan(mock('x')) }.should raise_error(TypeError)
+ -> { @s.scan(5) }.should.raise(TypeError)
+ -> { @s.scan(:test) }.should.raise(TypeError)
+ -> { @s.scan(mock('x')) }.should.raise(TypeError)
+ end
+
+ describe "#[] successive call with a capture group name" do
+ it "returns matched substring when matching succeeded" do
+ @s.scan(/(?<a>This)/)
+ @s.should.matched?
+ @s[:a].should == "This"
+ end
+
+ it "returns nil when matching failed" do
+ @s.scan(/(?<a>2008)/)
+ @s.should_not.matched?
+ @s[:a].should == nil
+ end
end
end
@@ -77,11 +91,11 @@ describe "StringScanner#scan with fixed_anchor: true" do
it "treats ^ as matching from the beginning of line" do
@s.scan(/\w+\n/).should == "This\n"
@s.scan(/^\w/).should == "i"
- @s.scan(/^\w/).should be_nil
+ @s.scan(/^\w/).should == nil
end
it "treats \\A as matching from the beginning of string" do
@s.scan(/\A\w/).should == "T"
- @s.scan(/\A\w/).should be_nil
+ @s.scan(/\A\w/).should == nil
end
end
diff --git a/spec/ruby/library/stringscanner/scan_until_spec.rb b/spec/ruby/library/stringscanner/scan_until_spec.rb
index 1e318d053b..df83f3916a 100644
--- a/spec/ruby/library/stringscanner/scan_until_spec.rb
+++ b/spec/ruby/library/stringscanner/scan_until_spec.rb
@@ -2,13 +2,19 @@ require_relative '../../spec_helper'
require 'strscan'
describe "StringScanner#scan_until" do
- before :each do
+ before do
@s = StringScanner.new("This is a test")
end
it "returns the substring up to and including the end of the match" do
@s.scan_until(/a/).should == "This is a"
+ end
+
+ it "sets the last match result" do
+ @s.scan_until(/a/)
+
@s.pre_match.should == "This is "
+ @s.matched.should == "a"
@s.post_match.should == " test"
end
@@ -21,11 +27,109 @@ describe "StringScanner#scan_until" do
@s.scan_until(/^h/).should == "h"
end
- ruby_version_is ""..."3.4" do
+ version_is StringScanner::Version, ""..."3.1.1" do # ruby_version_is ""..."3.4"
it "raises TypeError if given a String" do
-> {
@s.scan_until('T')
- }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)')
+ }.should.raise(TypeError, 'wrong argument type String (expected Regexp)')
+ end
+ end
+
+ version_is StringScanner::Version, "3.1.1" do # ruby_version_is "3.4"
+ it "searches a substring in the rest part of a string if given a String" do
+ @s.scan_until("a").should == "This is a"
+ end
+
+ # https://github.com/ruby/strscan/issues/131
+ version_is StringScanner::Version, "3.1.1"..."3.1.3" do # ruby_version_is "3.4.1"
+ it "sets the last match result if given a String" do
+ @s.scan_until("a")
+
+ @s.pre_match.should == ""
+ @s.matched.should == "This is a"
+ @s.post_match.should == " test"
+ end
+ end
+
+ version_is StringScanner::Version, "3.1.3" do # ruby_version_is "3.4"
+ it "sets the last match result if given a String" do
+ @s.scan_until("a")
+
+ @s.pre_match.should == "This is "
+ @s.matched.should == "a"
+ @s.post_match.should == " test"
+ end
+ end
+ end
+
+ describe "#[] successive call with a capture group name" do
+ context "when #scan_until was called with a Regexp pattern" do
+ it "returns matched substring when matching succeeded" do
+ @s.scan_until(/(?<a>This)/)
+ @s.should.matched?
+ @s[:a].should == "This"
+ end
+
+ it "returns nil when matching failed" do
+ @s.scan_until(/(?<a>2008)/)
+ @s.should_not.matched?
+ @s[:a].should == nil
+ end
+ end
+
+ version_is StringScanner::Version, "3.1.1" do # ruby_version_is "3.4"
+ context "when #scan_until was called with a String pattern" do
+ # https://github.com/ruby/strscan/issues/139
+ version_is StringScanner::Version, "3.1.1"..."3.1.3" do # ruby_version_is "3.4.0"..."3.4.3"
+ it "returns nil when matching succeeded" do
+ @s.scan_until("This")
+ @s.should.matched?
+ @s[:a].should == nil
+ end
+ end
+ version_is StringScanner::Version, "3.1.3" do # ruby_version_is "3.4.3"
+ it "raises IndexError when matching succeeded" do
+ @s.scan_until("This")
+ @s.should.matched?
+ -> { @s[:a] }.should.raise(IndexError)
+ end
+ end
+
+ it "returns nil when matching failed" do
+ @s.scan_until("2008")
+ @s.should_not.matched?
+ @s[:a].should == nil
+ end
+
+ it "returns a matching substring when given Integer index" do
+ @s.scan_until("This")
+ @s[0].should == "This"
+ end
+
+ # https://github.com/ruby/strscan/issues/135
+ version_is StringScanner::Version, "3.1.1"..."3.1.3" do # ruby_version_is "3.4.0"..."3.4.3"
+ it "ignores the previous matching with Regexp" do
+ @s.exist?(/(?<a>This)/)
+ @s.should.matched?
+ @s[:a].should == "This"
+
+ @s.scan_until("This")
+ @s.should.matched?
+ @s[:a].should == nil
+ end
+ end
+ version_is StringScanner::Version, "3.1.3" do # ruby_version_is "3.4"
+ it "ignores the previous matching with Regexp" do
+ @s.exist?(/(?<a>This)/)
+ @s.should.matched?
+ @s[:a].should == "This"
+
+ @s.scan_until("This")
+ @s.should.matched?
+ -> { @s[:a] }.should.raise(IndexError)
+ end
+ end
+ end
end
end
end
diff --git a/spec/ruby/library/stringscanner/search_full_spec.rb b/spec/ruby/library/stringscanner/search_full_spec.rb
index 713ab00d22..656884f46b 100644
--- a/spec/ruby/library/stringscanner/search_full_spec.rb
+++ b/spec/ruby/library/stringscanner/search_full_spec.rb
@@ -2,7 +2,7 @@ require_relative '../../spec_helper'
require 'strscan'
describe "StringScanner#search_full" do
- before :each do
+ before do
@s = StringScanner.new("This is a test")
end
@@ -28,11 +28,106 @@ describe "StringScanner#search_full" do
@s.pos.should == 4
end
- ruby_version_is ""..."3.4" do
+ it "sets the last match result" do
+ @s.search_full(/is a/, false, false)
+
+ @s.pre_match.should == "This "
+ @s.matched.should == "is a"
+ @s.post_match.should == " test"
+ end
+
+ version_is StringScanner::Version, ""..."3.1.1" do # ruby_version_is ""..."3.4"
it "raises TypeError if given a String" do
-> {
@s.search_full('T', true, true)
- }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)')
+ }.should.raise(TypeError, 'wrong argument type String (expected Regexp)')
+ end
+ end
+
+ version_is StringScanner::Version, "3.1.1" do # ruby_version_is "3.4"
+ it "searches a substring in the rest part of a string if given a String" do
+ @s.search_full("is a", false, false).should == 9
+ end
+
+ # https://github.com/ruby/strscan/issues/131
+ version_is StringScanner::Version, "3.1.1"..."3.1.3" do # ruby_version_is "3.4.1"
+ it "sets the last match result if given a String" do
+ @s.search_full("is a", false, false)
+
+ @s.pre_match.should == ""
+ @s.matched.should == "This is a"
+ @s.post_match.should == " test"
+ end
+ end
+
+ version_is StringScanner::Version, "3.1.3" do # ruby_version_is "3.4"
+ it "sets the last match result if given a String" do
+ @s.search_full("is a", false, false)
+
+ @s.pre_match.should == "This "
+ @s.matched.should == "is a"
+ @s.post_match.should == " test"
+ end
+ end
+ end
+
+ describe "#[] successive call with a capture group name" do
+ context "when #search_full was called with a Regexp pattern" do
+ it "returns matched substring when matching succeeded" do
+ @s.search_full(/(?<a>This)/, false, false)
+ @s.should.matched?
+ @s[:a].should == "This"
+ end
+
+ it "returns nil when matching failed" do
+ @s.search_full(/(?<a>2008)/, false, false)
+ @s.should_not.matched?
+ @s[:a].should == nil
+ end
+ end
+
+ version_is StringScanner::Version, "3.1.1" do # ruby_version_is "3.4"
+ context "when #search_full was called with a String pattern" do
+ # https://github.com/ruby/strscan/issues/139
+ version_is StringScanner::Version, "3.1.1"..."3.1.3" do # ruby_version_is "3.4.0"..."3.4.3"
+ it "returns nil when matching succeeded" do
+ @s.search_full("This", false, false)
+ @s.should.matched?
+ @s[:a].should == nil
+ end
+ end
+ version_is StringScanner::Version, "3.1.3" do # ruby_version_is "3.4.3"
+ it "raises IndexError when matching succeeded" do
+ @s.search_full("This", false, false)
+ @s.should.matched?
+ -> { @s[:a] }.should.raise(IndexError)
+ end
+ end
+
+ it "returns nil when matching failed" do
+ @s.search_full("2008", false, false)
+ @s.should_not.matched?
+ @s[:a].should == nil
+ end
+
+ it "returns a matching substring when given Integer index" do
+ @s.search_full("This", false, false)
+ @s[0].should == "This"
+ end
+
+ # https://github.com/ruby/strscan/issues/135
+ version_is StringScanner::Version, "3.1.3" do # ruby_version_is "3.4"
+ it "ignores the previous matching with Regexp" do
+ @s.exist?(/(?<a>This)/)
+ @s.should.matched?
+ @s[:a].should == "This"
+
+ @s.search_full("This", false, false)
+ @s.should.matched?
+ -> { @s[:a] }.should.raise(IndexError)
+ end
+ end
+ end
end
end
end
diff --git a/spec/ruby/library/stringscanner/shared/bol.rb b/spec/ruby/library/stringscanner/shared/bol.rb
index ebcdd7938f..ec5c2051b5 100644
--- a/spec/ruby/library/stringscanner/shared/bol.rb
+++ b/spec/ruby/library/stringscanner/shared/bol.rb
@@ -1,25 +1,25 @@
describe :strscan_bol, shared: true do
it "returns true if the scan pointer is at the beginning of the line, false otherwise" do
s = StringScanner.new("This is a test")
- s.send(@method).should be_true
+ s.send(@method).should == true
s.scan(/This/)
- s.send(@method).should be_false
+ s.send(@method).should == false
s.terminate
- s.send(@method).should be_false
+ s.send(@method).should == false
s = StringScanner.new("hello\nworld")
- s.bol?.should be_true
+ s.bol?.should == true
s.scan(/\w+/)
- s.bol?.should be_false
+ s.bol?.should == false
s.scan(/\n/)
- s.bol?.should be_true
+ s.bol?.should == true
s.unscan
- s.bol?.should be_false
+ s.bol?.should == false
end
it "returns true if the scan pointer is at the end of the line of an empty string." do
s = StringScanner.new('')
s.terminate
- s.send(@method).should be_true
+ s.send(@method).should == true
end
end
diff --git a/spec/ruby/library/stringscanner/shared/concat.rb b/spec/ruby/library/stringscanner/shared/concat.rb
index 1dbae11f7c..8138b0f8dc 100644
--- a/spec/ruby/library/stringscanner/shared/concat.rb
+++ b/spec/ruby/library/stringscanner/shared/concat.rb
@@ -3,28 +3,28 @@ describe :strscan_concat, shared: true do
s = StringScanner.new(+"hello ")
s.send(@method, 'world').should == s
s.string.should == "hello world"
- s.eos?.should be_false
+ s.eos?.should == false
end
it "raises a TypeError if the given argument can't be converted to a String" do
- -> { StringScanner.new('hello').send(@method, :world) }.should raise_error(TypeError)
- -> { StringScanner.new('hello').send(@method, mock('x')) }.should raise_error(TypeError)
+ -> { StringScanner.new('hello').send(@method, :world) }.should.raise(TypeError)
+ -> { StringScanner.new('hello').send(@method, mock('x')) }.should.raise(TypeError)
end
end
describe :strscan_concat_fixnum, shared: true do
it "raises a TypeError" do
a = StringScanner.new("hello world")
- -> { a.send(@method, 333) }.should raise_error(TypeError)
+ -> { a.send(@method, 333) }.should.raise(TypeError)
b = StringScanner.new("")
- -> { b.send(@method, (256 * 3 + 64)) }.should raise_error(TypeError)
- -> { b.send(@method, -200) }.should raise_error(TypeError)
+ -> { b.send(@method, (256 * 3 + 64)) }.should.raise(TypeError)
+ -> { b.send(@method, -200) }.should.raise(TypeError)
end
it "doesn't call to_int on the argument" do
x = mock('x')
x.should_not_receive(:to_int)
- -> { StringScanner.new("").send(@method, x) }.should raise_error(TypeError)
+ -> { StringScanner.new("").send(@method, x) }.should.raise(TypeError)
end
end
diff --git a/spec/ruby/library/stringscanner/shared/eos.rb b/spec/ruby/library/stringscanner/shared/eos.rb
deleted file mode 100644
index ea04c764a2..0000000000
--- a/spec/ruby/library/stringscanner/shared/eos.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-describe :strscan_eos, shared: true do
- before :each do
- @s = StringScanner.new("This is a test")
- end
-
- it "returns true if the scan pointer is at the end of the string" do
- @s.terminate
- @s.send(@method).should be_true
-
- s = StringScanner.new('')
- s.send(@method).should be_true
- end
-
- it "returns false if the scan pointer is not at the end of the string" do
- @s.send(@method).should be_false
- end
-end
diff --git a/spec/ruby/library/stringscanner/shared/extract_range.rb b/spec/ruby/library/stringscanner/shared/extract_range.rb
index e7404fd0cb..c64cc41fa7 100644
--- a/spec/ruby/library/stringscanner/shared/extract_range.rb
+++ b/spec/ruby/library/stringscanner/shared/extract_range.rb
@@ -5,7 +5,7 @@ describe :extract_range, shared: true do
s = StringScanner.new(sub)
ch = s.send(@method)
- ch.should_not be_kind_of(cls)
- ch.should be_an_instance_of(String)
+ ch.should_not.is_a?(cls)
+ ch.should.instance_of?(String)
end
end
diff --git a/spec/ruby/library/stringscanner/shared/extract_range_matched.rb b/spec/ruby/library/stringscanner/shared/extract_range_matched.rb
index 070a132812..8a6349bec1 100644
--- a/spec/ruby/library/stringscanner/shared/extract_range_matched.rb
+++ b/spec/ruby/library/stringscanner/shared/extract_range_matched.rb
@@ -7,7 +7,7 @@ describe :extract_range_matched, shared: true do
s.scan(/\w{1}/)
ch = s.send(@method)
- ch.should_not be_kind_of(cls)
- ch.should be_an_instance_of(String)
+ ch.should_not.is_a?(cls)
+ ch.should.instance_of?(String)
end
end
diff --git a/spec/ruby/library/stringscanner/shared/get_byte.rb b/spec/ruby/library/stringscanner/shared/get_byte.rb
deleted file mode 100644
index 763ab6f4a4..0000000000
--- a/spec/ruby/library/stringscanner/shared/get_byte.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# -*- encoding: binary -*-
-describe :strscan_get_byte, shared: true do
- it "scans one byte and returns it" do
- s = StringScanner.new('abc5.')
- s.send(@method).should == 'a'
- s.send(@method).should == 'b'
- s.send(@method).should == 'c'
- s.send(@method).should == '5'
- s.send(@method).should == '.'
- end
-
- it "is not multi-byte character sensitive" do
- s = StringScanner.new("\244\242")
- s.send(@method).should == "\244"
- s.send(@method).should == "\242"
- end
-
- it "returns nil at the end of the string" do
- # empty string case
- s = StringScanner.new('')
- s.send(@method).should == nil
- s.send(@method).should == nil
-
- # non-empty string case
- s = StringScanner.new('a')
- s.send(@method) # skip one
- s.send(@method).should == nil
- end
-end
diff --git a/spec/ruby/library/stringscanner/shared/peek.rb b/spec/ruby/library/stringscanner/shared/peek.rb
deleted file mode 100644
index 4c757866c1..0000000000
--- a/spec/ruby/library/stringscanner/shared/peek.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-describe :strscan_peek, shared: true do
- before :each do
- @s = StringScanner.new('This is a test')
- end
-
- it "returns at most the specified number of bytes from the current position" do
- @s.send(@method, 4).should == "This"
- @s.pos.should == 0
- @s.pos = 5
- @s.send(@method, 2).should == "is"
- @s.send(@method, 1000).should == "is a test"
-
- s = StringScanner.new("été")
- s.send(@method, 2).should == "é"
- end
-
- it "returns an empty string when the passed argument is zero" do
- @s.send(@method, 0).should == ""
- end
-
- it "raises a ArgumentError when the passed argument is negative" do
- -> { @s.send(@method, -2) }.should raise_error(ArgumentError)
- end
-
- it "raises a RangeError when the passed argument is a Bignum" do
- -> { @s.send(@method, bignum_value) }.should raise_error(RangeError)
- end
-
- it "returns an instance of String when passed a String subclass" do
- cls = Class.new(String)
- sub = cls.new("abc")
-
- s = StringScanner.new(sub)
-
- ch = s.send(@method, 1)
- ch.should_not be_kind_of(cls)
- ch.should be_an_instance_of(String)
- end
-end
diff --git a/spec/ruby/library/stringscanner/shared/pos.rb b/spec/ruby/library/stringscanner/shared/pos.rb
index 6d540881f2..91f80fdf08 100644
--- a/spec/ruby/library/stringscanner/shared/pos.rb
+++ b/spec/ruby/library/stringscanner/shared/pos.rb
@@ -22,6 +22,13 @@ describe :strscan_pos, shared: true do
@s.terminate
@s.send(@method).should == @s.string.length
end
+
+ it "is not multi-byte character sensitive" do
+ s = StringScanner.new("abcädeföghi")
+
+ s.scan_until(/ö/)
+ s.pos.should == 10
+ end
end
describe :strscan_pos_set, shared: true do
@@ -43,10 +50,10 @@ describe :strscan_pos_set, shared: true do
it "raises a RangeError if position too far backward" do
-> {
@s.send(@method, -20)
- }.should raise_error(RangeError)
+ }.should.raise(RangeError)
end
it "raises a RangeError when the passed argument is out of range" do
- -> { @s.send(@method, 20) }.should raise_error(RangeError)
+ -> { @s.send(@method, 20) }.should.raise(RangeError)
end
end
diff --git a/spec/ruby/library/stringscanner/shared/rest_size.rb b/spec/ruby/library/stringscanner/shared/rest_size.rb
deleted file mode 100644
index 4c4f49e45c..0000000000
--- a/spec/ruby/library/stringscanner/shared/rest_size.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-describe :strscan_rest_size, shared: true do
- before :each do
- @s = StringScanner.new('This is a test')
- end
-
- it "returns the length of the rest of the string" do
- @s.send(@method).should == 14
- @s.scan(/This/)
- @s.send(@method).should == 10
- @s.terminate
- @s.send(@method).should == 0
- end
-
- it "is equivalent to rest.size" do
- @s.scan(/This/)
- @s.send(@method).should == @s.rest.size
- end
-end
diff --git a/spec/ruby/library/stringscanner/shared/terminate.rb b/spec/ruby/library/stringscanner/shared/terminate.rb
deleted file mode 100644
index bf41d097e2..0000000000
--- a/spec/ruby/library/stringscanner/shared/terminate.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-describe :strscan_terminate, shared: true do
- it "set the scan pointer to the end of the string and clear matching data." do
- s = StringScanner.new('This is a test')
- s.send(@method)
- s.bol?.should be_false
- s.eos?.should be_true
- end
-end
diff --git a/spec/ruby/library/stringscanner/skip_spec.rb b/spec/ruby/library/stringscanner/skip_spec.rb
index 473361782c..2b955b3172 100644
--- a/spec/ruby/library/stringscanner/skip_spec.rb
+++ b/spec/ruby/library/stringscanner/skip_spec.rb
@@ -15,4 +15,18 @@ describe "StringScanner#skip" do
@s.skip(/\s+/).should == nil
@s.skip(/\d+/).should == nil
end
+
+ describe "#[] successive call with a capture group name" do
+ it "returns matched substring when matching succeeded" do
+ @s.skip(/(?<a>This)/)
+ @s.should.matched?
+ @s[:a].should == "This"
+ end
+
+ it "returns nil when matching failed" do
+ @s.skip(/(?<a>2008)/)
+ @s.should_not.matched?
+ @s[:a].should == nil
+ end
+ end
end
diff --git a/spec/ruby/library/stringscanner/skip_until_spec.rb b/spec/ruby/library/stringscanner/skip_until_spec.rb
index b6a020f9ba..508db285ba 100644
--- a/spec/ruby/library/stringscanner/skip_until_spec.rb
+++ b/spec/ruby/library/stringscanner/skip_until_spec.rb
@@ -2,25 +2,131 @@ require_relative '../../spec_helper'
require 'strscan'
describe "StringScanner#skip_until" do
- before :each do
+ before do
@s = StringScanner.new("This is a test")
end
it "returns the number of bytes advanced and advances the scan pointer until pattern is matched and consumed" do
@s.skip_until(/a/).should == 9
@s.pos.should == 9
+ end
+
+ it "sets the last match result" do
+ @s.skip_until(/a/)
+
+ @s.pre_match.should == "This is "
@s.matched.should == "a"
+ @s.post_match.should == " test"
end
it "returns nil if no match was found" do
@s.skip_until(/d+/).should == nil
end
- ruby_version_is ""..."3.4" do
+ version_is StringScanner::Version, ""..."3.1.1" do # ruby_version_is ""..."3.4"
it "raises TypeError if given a String" do
-> {
@s.skip_until('T')
- }.should raise_error(TypeError, 'wrong argument type String (expected Regexp)')
+ }.should.raise(TypeError, 'wrong argument type String (expected Regexp)')
+ end
+ end
+
+ version_is StringScanner::Version, "3.1.1" do # ruby_version_is "3.4"
+ it "searches a substring in the rest part of a string if given a String" do
+ @s.skip_until("a").should == 9
+ @s.pos.should == 9
+ end
+
+ # https://github.com/ruby/strscan/issues/131
+ version_is StringScanner::Version, "3.1.1"..."3.1.3" do # ruby_version_is "3.4.1"
+ it "sets the last match result if given a String" do
+ @s.skip_until("a")
+
+ @s.pre_match.should == ""
+ @s.matched.should == "This is a"
+ @s.post_match.should == " test"
+ end
+ end
+
+ version_is StringScanner::Version, "3.1.3" do # ruby_version_is "3.4"
+ it "sets the last match result if given a String" do
+ @s.skip_until("a")
+
+ @s.pre_match.should == "This is "
+ @s.matched.should == "a"
+ @s.post_match.should == " test"
+ end
+ end
+ end
+
+ describe "#[] successive call with a capture group name" do
+ context "when #scan_until was called with a Regexp pattern" do
+ it "returns matched substring when matching succeeded" do
+ @s.skip_until(/(?<a>This)/)
+ @s.should.matched?
+ @s[:a].should == "This"
+ end
+
+ it "returns nil when matching failed" do
+ @s.skip_until(/(?<a>2008)/)
+ @s.should_not.matched?
+ @s[:a].should == nil
+ end
+ end
+
+ version_is StringScanner::Version, "3.1.1" do # ruby_version_is "3.4"
+ context "when #skip_until was called with a String pattern" do
+ # https://github.com/ruby/strscan/issues/139
+ version_is StringScanner::Version, "3.1.1"..."3.1.3" do # ruby_version_is "3.4.0"..."3.4.3"
+ it "returns nil when matching succeeded" do
+ @s.skip_until("This")
+ @s.should.matched?
+ @s[:a].should == nil
+ end
+ end
+ version_is StringScanner::Version, "3.1.3" do # ruby_version_is "3.4.3"
+ it "raises IndexError when matching succeeded" do
+ @s.skip_until("This")
+ @s.should.matched?
+ -> { @s[:a] }.should.raise(IndexError)
+ end
+ end
+
+ it "returns nil when matching failed" do
+ @s.skip_until("2008")
+ @s.should_not.matched?
+ @s[:a].should == nil
+ end
+
+ it "returns a matching substring when given Integer index" do
+ @s.skip_until("This")
+ @s[0].should == "This"
+ end
+
+ # https://github.com/ruby/strscan/issues/135
+ version_is StringScanner::Version, "3.1.1"..."3.1.3" do # ruby_version_is "3.4.0"..."3.4.3"
+ it "ignores the previous matching with Regexp" do
+ @s.exist?(/(?<a>This)/)
+ @s.should.matched?
+ @s[:a].should == "This"
+
+ @s.skip_until("This")
+ @s.should.matched?
+ @s[:a].should == nil
+ end
+ end
+ version_is StringScanner::Version, "3.1.3" do # ruby_version_is "3.4"
+ it "ignores the previous matching with Regexp" do
+ @s.exist?(/(?<a>This)/)
+ @s.should.matched?
+ @s[:a].should == "This"
+
+ @s.skip_until("This")
+ @s.should.matched?
+ -> { @s[:a] }.should.raise(IndexError)
+ end
+ end
+ end
end
end
end
diff --git a/spec/ruby/library/stringscanner/string_spec.rb b/spec/ruby/library/stringscanner/string_spec.rb
index cba6bd51dd..6cbbff4822 100644
--- a/spec/ruby/library/stringscanner/string_spec.rb
+++ b/spec/ruby/library/stringscanner/string_spec.rb
@@ -14,7 +14,7 @@ describe "StringScanner#string" do
end
it "returns the identical object passed in" do
- @s.string.equal?(@string).should be_true
+ @s.string.equal?(@string).should == true
end
end
diff --git a/spec/ruby/library/stringscanner/terminate_spec.rb b/spec/ruby/library/stringscanner/terminate_spec.rb
index 249023f1ab..3cff5c010c 100644
--- a/spec/ruby/library/stringscanner/terminate_spec.rb
+++ b/spec/ruby/library/stringscanner/terminate_spec.rb
@@ -1,7 +1,11 @@
require_relative '../../spec_helper'
-require_relative 'shared/terminate'
require 'strscan'
describe "StringScanner#terminate" do
- it_behaves_like :strscan_terminate, :terminate
+ it "set the scan pointer to the end of the string and clear matching data." do
+ s = StringScanner.new('This is a test')
+ s.terminate
+ s.should_not.bol?
+ s.should.eos?
+ end
end
diff --git a/spec/ruby/library/stringscanner/unscan_spec.rb b/spec/ruby/library/stringscanner/unscan_spec.rb
index df0ea43367..f738778273 100644
--- a/spec/ruby/library/stringscanner/unscan_spec.rb
+++ b/spec/ruby/library/stringscanner/unscan_spec.rb
@@ -21,8 +21,8 @@ describe "StringScanner#unscan" do
@s.pos.should == pos
end
- it "raises a ScanError when the previous match had failed" do
- -> { @s.unscan }.should raise_error(ScanError)
- -> { @s.scan(/\d/); @s.unscan }.should raise_error(ScanError)
+ it "raises a StringScanner::Error when the previous match had failed" do
+ -> { @s.unscan }.should.raise(StringScanner::Error)
+ -> { @s.scan(/\d/); @s.unscan }.should.raise(StringScanner::Error)
end
end
diff --git a/spec/ruby/library/stringscanner/values_at_spec.rb b/spec/ruby/library/stringscanner/values_at_spec.rb
new file mode 100644
index 0000000000..b00cce0ffa
--- /dev/null
+++ b/spec/ruby/library/stringscanner/values_at_spec.rb
@@ -0,0 +1,68 @@
+require_relative '../../spec_helper'
+require 'strscan'
+
+describe "StringScanner#captures" do
+ before do
+ @s = StringScanner.new('Fri Dec 12 1975 14:39')
+ end
+
+ context "when passed a list of Integers" do
+ it "returns an array containing each value given by one of integers" do
+ @s.exist?(/(?<wday>\w+) (?<month>\w+) (?<day>\d+)/)
+ @s.values_at(0, 1, 2, 3).should == ["Fri Dec 12", "Fri", "Dec", "12"]
+ end
+
+ it "returns nil value for any integer that is out of range" do
+ @s.exist?(/(?<wday>\w+) (?<month>\w+) (?<day>\d+)/)
+ @s.values_at(4).should == [nil]
+ @s.values_at(-5).should == [nil]
+ end
+ end
+
+ context "when passed names" do
+ it 'slices captures with the given names' do
+ @s.exist?(/(?<wday>\w+) (?<month>\w+) (?<day>\d+)/)
+ @s.values_at(:wday, :month, :day).should == ["Fri", "Dec", "12"]
+ end
+
+ it 'slices captures with the given String names' do
+ @s.exist?(/(?<wday>\w+) (?<month>\w+) (?<day>\d+)/)
+ @s.values_at("wday", "month", "day").should == ["Fri", "Dec", "12"]
+ end
+
+ it "raises IndexError when given unknown name" do
+ @s.exist?(/(?<wday>\w+) (?<month>\w+) (?<day>\d+)/)
+
+ -> {
+ @s.values_at("foo")
+ }.should.raise(IndexError, "undefined group name reference: foo")
+ end
+ end
+
+ it 'supports mixing of names and indices' do
+ @s.exist?(/(?<wday>\w+) (?<month>\w+) (?<day>\d+)/)
+ @s.values_at(1, "wday", 2, "month", 3, "day").should == ["Fri", "Fri", "Dec", "Dec", "12", "12"]
+ end
+
+ it "returns a new empty Array if no arguments given" do
+ @s.exist?(/(?<wday>\w+) (?<month>\w+) (?<day>\d+)/)
+ @s.values_at().should == []
+ end
+
+ it "fails when passed arguments of unsupported types" do
+ @s.exist?(/(?<wday>\w+) (?<month>\w+) (?<day>\d+)/)
+
+ -> {
+ @s.values_at([])
+ }.should.raise(TypeError, "no implicit conversion of Array into Integer")
+ end
+
+ it "returns nil if the most recent matching fails" do
+ @s.exist?(/(?<wday>\w+) (?<month>\w+) (?<day>\s+)/)
+ @s.values_at(1, 2, 3).should == nil
+ end
+
+ it "returns nil if there is no any matching done" do
+ @s.values_at(1, 2, 3).should == nil
+ end
+end