Skip to content

Commit

Permalink
Add String.byteslice with range arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
marcandre committed Jan 3, 2024
1 parent 2166a15 commit a2ff3c4
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 0 deletions.
3 changes: 3 additions & 0 deletions lib/backports/3.3.0/string.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
require 'backports/tools/require_relative_dir'

Backports.require_relative_dir
33 changes: 33 additions & 0 deletions lib/backports/3.3.0/string/bytesplice.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
unless ("".bytesplice(0..0, "", 0..0) rescue false)
require 'backports/tools/alias_method_chain'

# Original API
# * bytesplice(index, length, str) -> string
# * bytesplice(range, str) -> string

# Newly supported API:
# * bytesplice(index, length, str, str_index, str_length) -> string
# * bytesplice(range, str, str_range) -> string

class String
def bytesplice_with_range_replacement_support(*args)
case args.size
when 5
index, length, str, str_index, str_length = *args

str = str.byteslice(str_index, str_length) || (raise IndexError, "oops") # if str_index < -str.length
bytesplice_without_range_replacement_support(index, length, str)
when 3
if args[2].is_a?(Range)
str = args[1].byteslice(args[2]) || (raise RangeError, "oops")
bytesplice_without_range_replacement_support(args[0], str)
else
bytesplice_without_range_replacement_support(*args)
end
else
bytesplice_without_range_replacement_support(*args)
end
end
Backports.alias_method_chain self, :bytesplice, :range_replacement_support
end
end
97 changes: 97 additions & 0 deletions test/bytesplice_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
require './test/test_helper'
require 'backports/3.3.0/string/bytesplice'

class BytespliceTest < Test::Unit::TestCase
def test_bytesplice
assert_bytesplice_raise(IndexError, S("hello"), -6, 0, "bye")
assert_bytesplice_result("byehello", S("hello"), -5, 0, "bye")
assert_bytesplice_result("byehello", S("hello"), 0, 0, "bye")
assert_bytesplice_result("byeello", S("hello"), 0, 1, "bye")
assert_bytesplice_result("bye", S("hello"), 0, 5, "bye")
assert_bytesplice_result("bye", S("hello"), 0, 6, "bye")

assert_bytesplice_raise(IndexError, S("hello"), -5, 0, "bye", -4, 0)
assert_bytesplice_result("byehello", S("hello"), 0, 0, "bye", 0, 3)
assert_bytesplice_result("yehello", S("hello"), 0, 0, "bye", 1, 3)
assert_bytesplice_result("yehello", S("hello"), 0, 0, "bye", 1, 2)
assert_bytesplice_result("ehello", S("hello"), 0, 0, "bye", 2, 1)
assert_bytesplice_result("hello", S("hello"), 0, 0, "bye", 3, 0)
assert_bytesplice_result("hello", s = S("hello"), 0, 5, s, 0, 5)
assert_bytesplice_result("elloo", s = S("hello"), 0, 4, s, 1, 4)
assert_bytesplice_result("llolo", s = S("hello"), 0, 3, s, 2, 3)
assert_bytesplice_result("lollo", s = S("hello"), 0, 2, s, 3, 2)
assert_bytesplice_result("oello", s = S("hello"), 0, 1, s, 4, 1)
assert_bytesplice_result("hhell", s = S("hello"), 1, 4, s, 0, 4)
assert_bytesplice_result("hehel", s = S("hello"), 2, 3, s, 0, 3)
assert_bytesplice_result("helhe", s = S("hello"), 3, 2, s, 0, 2)
assert_bytesplice_result("hellh", s = S("hello"), 4, 1, s, 0, 1)

assert_bytesplice_raise(RangeError, S("hello"), -6...-6, "bye")
assert_bytesplice_result("byehello", S("hello"), -5...-5, "bye")
assert_bytesplice_result("byehello", S("hello"), 0...0, "bye")
assert_bytesplice_result("byeello", S("hello"), 0..0, "bye")
assert_bytesplice_result("byeello", S("hello"), 0...1, "bye")
assert_bytesplice_result("byello", S("hello"), 0..1, "bye")
assert_bytesplice_result("bye", S("hello"), 0..-1, "bye")
assert_bytesplice_result("bye", S("hello"), 0...5, "bye")
assert_bytesplice_result("bye", S("hello"), 0...6, "bye")
assert_bytesplice_result("llolo", s = S("hello"), 0..2, s, 2..4)

assert_bytesplice_raise(RangeError, S("hello"), -5...-5, "bye", -6...-6)
assert_bytesplice_result("byehello", S("hello"), -5...-5, "bye", 0..-1)
assert_bytesplice_result("byehello", S("hello"), 0...0, "bye", 0..-1)
assert_bytesplice_result("bhello", S("hello"), 0...0, "bye", 0..0)
assert_bytesplice_result("byhello", S("hello"), 0...0, "bye", 0..1)
assert_bytesplice_result("byehello", S("hello"), 0...0, "bye", 0..2)
assert_bytesplice_result("yehello", S("hello"), 0...0, "bye", 1..2)

assert_bytesplice_raise(TypeError, S("hello"), 0, "bye")

assert_bytesplice_raise(IndexError, S("こんにちは"), -16, 0, "bye")
assert_bytesplice_result("byeこんにちは", S("こんにちは"), -15, 0, "bye")
assert_bytesplice_result("byeこんにちは", S("こんにちは"), 0, 0, "bye")
assert_bytesplice_raise(IndexError, S("こんにちは"), 1, 0, "bye")
assert_bytesplice_raise(IndexError, S("こんにちは"), 0, 1, "bye")
assert_bytesplice_raise(IndexError, S("こんにちは"), 0, 2, "bye")
assert_bytesplice_result("byeんにちは", S("こんにちは"), 0, 3, "bye")
assert_bytesplice_result("こんにちはbye", S("こんにちは"), 15, 0, "bye")

assert_bytesplice_raise(IndexError, S("こんにちは"), 0, 0, "さようなら", -16, 0)
assert_bytesplice_result("こんにちはさようなら", S("こんにちは"), 15, 0, "さようなら", 0, 15)
assert_bytesplice_result("さようなら", S("こんにちは"), 0, 15, "さようなら", 0, 15)
assert_bytesplice_result("さんにちは", S("こんにちは"), 0, 3, "さようなら", 0, 3)
assert_bytesplice_result("さようちは", S("こんにちは"), 0, 9, "さようなら", 0, 9)
assert_bytesplice_result("ようなちは", S("こんにちは"), 0, 9, "さようなら", 3, 9)
assert_bytesplice_result("ようちは", S("こんにちは"), 0, 9, "さようなら", 3, 6)
assert_bytesplice_result("ようならちは", S("こんにちは"), 0, 9, "さようなら", 3, 12)
assert_bytesplice_raise(IndexError, S("こんにちは"), 0, 15, "さようなら", -16, 0)
# assert_bytesplice_raise(IndexError, S("こんにちは"), 0, 15, "さようなら", 1, 0)
# assert_bytesplice_raise(IndexError, S("こんにちは"), 0, 15, "さようなら", 2, 0)
# assert_bytesplice_raise(IndexError, S("こんにちは"), 0, 15, "さようなら", 0, 1)
# assert_bytesplice_raise(IndexError, S("こんにちは"), 0, 15, "さようなら", 0, 2)
assert_bytesplice_result("にちはちは", s = S("こんにちは"), 0, 9, s, 6, 9)

assert_bytesplice_result("", S(""), 0, 0, "")
assert_bytesplice_result("xxx", S(""), 0, 0, "xxx")

assert_bytesplice_raise(ArgumentError, S("hello"), 0, 5, "bye", 0)
assert_bytesplice_raise(ArgumentError, S("hello"), 0, 5, "bye", 0..-1)
assert_bytesplice_raise(ArgumentError, S("hello"), 0..-1, "bye", 0, 3)
end

private

def assert_bytesplice_result(expected, s, *args)
assert_equal(expected, s.send(:bytesplice, *args))
assert_equal(expected, s)
end

def assert_bytesplice_raise(e, s, *args)
assert_raise(e) { s.send(:bytesplice, *args) }
end

def S(*args, **kw)
String.new(*args, **kw)
end

end

0 comments on commit a2ff3c4

Please sign in to comment.