Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 30 additions & 14 deletions spec/std/indexable_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -61,24 +61,40 @@ private class SafeRecursiveIndexable
end

describe Indexable do
it "does index with big negative offset" do
indexable = SafeIndexable.new(3)
indexable.index(0, -100).should be_nil
end
describe "#index" do
it "does index with big negative offset" do
indexable = SafeIndexable.new(3)
indexable.index(0, -100).should be_nil
end

it "does index with big offset" do
indexable = SafeIndexable.new(3)
indexable.index(0, 100).should be_nil
end
it "does index with big offset" do
indexable = SafeIndexable.new(3)
indexable.index(0, 100).should be_nil
end

it "does rindex with big negative offset" do
indexable = SafeIndexable.new(3)
indexable.rindex(0, -100).should be_nil
it "offset type" do
indexable = SafeIndexable.new(3)
indexable.index(1, 0_i64).should eq 1
indexable.index(1, 0_i64).should be_a(Int64)
end
end

it "does rindex with big offset" do
indexable = SafeIndexable.new(3)
indexable.rindex(0, 100).should be_nil
describe "#rindex" do
it "does rindex with big negative offset" do
indexable = SafeIndexable.new(3)
indexable.rindex(0, -100).should be_nil
end

it "does rindex with big offset" do
indexable = SafeIndexable.new(3)
indexable.rindex(0, 100).should be_nil
end

it "offset type" do
indexable = SafeIndexable.new(3)
indexable.rindex(1, 2_i64).should eq 1
indexable.rindex(1, 2_i64).should be_a(Int64)
end
end

it "does each" do
Expand Down
32 changes: 30 additions & 2 deletions spec/std/string_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -840,7 +840,7 @@ describe "String" do
it { "hello".presence.should eq("hello") }
end

describe "index" do
describe "#index" do
describe "by char" do
it { "foo".index('o').should eq(1) }
it { "foo".index('g').should be_nil }
Expand All @@ -855,6 +855,12 @@ describe "String" do
it { "foo".index('g', 1).should be_nil }
it { "foo".index('g', -20).should be_nil }
it { "日本語日本語".index('本', 2).should eq(4) }

# Check offset type
it { "foobarbaz".index('a', 5_i64).should eq(7) }
it { "foobarbaz".index('a', 5_i64).should be_a(Int32) }
it { "日本語日本語".index('本', 2_i64).should eq(4) }
it { "日本語日本語".index('本', 2_i64).should be_a(Int32) }
end
end

Expand All @@ -877,6 +883,14 @@ describe "String" do
it { "日本語日本語".index("本語", 2).should eq(4) }
it { "\xFD\x9A\xAD\x50NG".index("PNG", 2).should eq(3) }
it { "\xFD\x9A\xAD\x50NG".index("PNG", 4).should be_nil }

# Check offset type
it { "foobarbaz".index("a", 5_i64).should eq(7) }
it { "foobarbaz".index("a", 5_i64).should be_a(Int32) }
it { "日本語日本語".index("本", 2_i64).should eq(4) }
it { "日本語日本語".index("本", 2_i64).should be_a(Int32) }
it { "日本語日本語".index("", 2_i64).should eq 2 }
it { "日本語日本語".index("", 2_i64).should be_a(Int64) }
end
end

Expand All @@ -899,7 +913,7 @@ describe "String" do
end
end

describe "rindex" do
describe "#rindex" do
describe "by char" do
it { "bbbb".rindex('b').should eq(3) }
it { "foobar".rindex('a').should eq(4) }
Expand All @@ -918,6 +932,12 @@ describe "String" do
it { "faobar".rindex('a', 3).should eq(1) }
it { "faobarbaz".rindex('a', -3).should eq(4) }
it { "日本語日本語".rindex('本', 3).should eq(1) }

# Check offset type
it { "bbbb".rindex('b', 2_i64).should eq(2) }
it { "bbbb".rindex('b', 2_i64).should be_a(Int64) }
it { "日本語日本語".rindex('本', 3_i64).should eq(1) }
it { "日本語日本語".rindex('本', 3_i64).should be_a(Int64) }
end
end

Expand All @@ -939,6 +959,14 @@ describe "String" do
it { "foo".rindex("", 3).should eq(3) }
it { "foo".rindex("", 4).should eq(3) }
it { "日本語日本語".rindex("日本", 2).should eq(0) }

# Check offset type
it { "bbbb".rindex("b", 2_i64).should eq(2) }
it { "bbbb".rindex("b", 2_i64).should be_a(Int32) }
it { "日本語日本語".rindex("本", 3_i64).should eq(1) }
it { "日本語日本語".rindex("本", 3_i64).should be_a(Int32) }
it { "日本語日本語".rindex("", 3_i64).should eq(3) }
it { "日本語日本語".rindex("", 3_i64).should be_a(Int32) }
end
end

Expand Down
2 changes: 1 addition & 1 deletion src/array.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2231,7 +2231,7 @@ class Array(T)
end

# :nodoc:
def index(object, offset : Int = 0) : Int32?
def index(object, offset : Int = 0)
# Optimize for the case of looking for a byte in a byte slice
if T.is_a?(UInt8.class) &&
(object.is_a?(UInt8) || (object.is_a?(Int) && 0 <= object < 256))
Expand Down
2 changes: 1 addition & 1 deletion src/indexable.cr
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,7 @@ module Indexable(T)
# [1, 2, 3, 2, 3].rindex(2) # => 3
# [1, 2, 3, 2, 3].rindex(2, offset: 2) # => 1
# ```
def rindex(value, offset = size - 1) : Int32?
def rindex(value, offset = size - 1)
rindex(offset) { |elem| elem == value }
end

Expand Down
6 changes: 3 additions & 3 deletions src/string.cr
Original file line number Diff line number Diff line change
Expand Up @@ -3035,7 +3035,7 @@ class String
def index(search : Char, offset = 0) : Int32?
# If it's ASCII we can delegate to slice
if search.ascii? && single_byte_optimizable?
return to_slice.index(search.ord.to_u8, offset)
return to_slice.fast_index(search.ord.to_u8, offset)
end

offset += size if offset < 0
Expand All @@ -3051,7 +3051,7 @@ class String
end

# :ditto:
def index(search : String, offset = 0) : Int32?
def index(search : String, offset = 0)
offset += size if offset < 0
return if offset < 0

Expand Down Expand Up @@ -3127,7 +3127,7 @@ class String
# "Hello, World".rindex("o", 5) # => 4
# "Hello, World".rindex("W", 2) # => nil
# ```
def rindex(search : Char, offset = size - 1) : Int32?
def rindex(search : Char, offset = size - 1)
# If it's ASCII we can delegate to slice
if search.ascii? && single_byte_optimizable?
return to_slice.rindex(search.ord.to_u8, offset)
Expand Down