From 4a8b88f7757f71d7d88b89764b533dd5ba59fd44 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Fri, 19 Apr 2019 20:14:23 +0900 Subject: Add type check (conversion) in `String#[]=` Before this patch: 'a'[0] = 1 #=> 1 'a'[:a] = '1' #=> ArgumentError 'a'[:a, 0] = '1' #=> ArgumentError 'a'[0, :a] = '1' #=> ArgumentError 'a'[0, 1] = 1 #=> 1 After this patch / Ruby: 'a'[0] = 1 #=> TypeError 'a'[:a] = '1' #=> TypeError 'a'[:a, 0] = '1' #=> TypeError 'a'[0, :a] = '1' #=> TypeError 'a'[0, 1] = 1 #=> TypeError --- test/t/string.rb | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'test/t/string.rb') diff --git a/test/t/string.rb b/test/t/string.rb index cf3702cbe..404cf03e1 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -161,6 +161,9 @@ assert('String#[]=') do assert_equal 'aXc', e end + assert_raise(TypeError) { 'a'[0] = 1 } + assert_raise(TypeError) { 'a'[:a] = '1' } + # length of args is 2 a1 = 'abc' assert_raise(IndexError) do @@ -197,6 +200,10 @@ assert('String#[]=') do assert_raise(IndexError) do b3['XX'] = 'Y' end + + assert_raise(TypeError) { 'a'[:a, 0] = '1' } + assert_raise(TypeError) { 'a'[0, :a] = '1' } + assert_raise(TypeError) { 'a'[0, 1] = 1 } end assert('String#capitalize', '15.2.10.5.7') do -- cgit v1.2.3 From cdb458ed4e07698ecb028bfe397fa273ed454e13 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Sun, 21 Apr 2019 20:34:39 +0900 Subject: Commented out `String#scan` because it is not implemented yet --- mrbgems/mruby-enumerator/mrblib/enumerator.rb | 7 ++++--- mrblib/string.rb | 21 +++++++++------------ test/t/string.rb | 4 +++- 3 files changed, 16 insertions(+), 16 deletions(-) (limited to 'test/t/string.rb') diff --git a/mrbgems/mruby-enumerator/mrblib/enumerator.rb b/mrbgems/mruby-enumerator/mrblib/enumerator.rb index 457687268..89472ef01 100644 --- a/mrbgems/mruby-enumerator/mrblib/enumerator.rb +++ b/mrbgems/mruby-enumerator/mrblib/enumerator.rb @@ -244,9 +244,10 @@ class Enumerator # # === Examples # - # "Hello, world!".scan(/\w+/) #=> ["Hello", "world"] - # "Hello, world!".to_enum(:scan, /\w+/).to_a #=> ["Hello", "world"] - # "Hello, world!".to_enum(:scan).each(/\w+/).to_a #=> ["Hello", "world"] + # Array.new(3) #=> [nil, nil, nil] + # Array.new(3) { |i| i } #=> [0, 1, 2] + # Array.to_enum(:new, 3).to_a #=> [0, 1, 2] + # Array.to_enum(:new).each(3).to_a #=> [0, 1, 2] # # obj = Object.new # diff --git a/mrblib/string.rb b/mrblib/string.rb index e9eb2be1d..c92a9e7be 100644 --- a/mrblib/string.rb +++ b/mrblib/string.rb @@ -105,18 +105,15 @@ class String self.replace(str) end - ## - # Calls the given block for each match of +pattern+ - # If no block is given return an array with all - # matches of +pattern+. - # - # ISO 15.2.10.5.32 - def scan(reg, &block) - ### *** TODO *** ### - unless Object.const_defined?(:Regexp) - raise NotImplementedError, "scan not available (yet)" - end - end +# ## +# # Calls the given block for each match of +pattern+ +# # If no block is given return an array with all +# # matches of +pattern+. +# # +# # ISO 15.2.10.5.32 +# def scan(pattern, &block) +# # TODO: String#scan is not implemented yet +# end ## # Replace only the first match of +pattern+ with diff --git a/test/t/string.rb b/test/t/string.rb index 404cf03e1..e563db55a 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -509,7 +509,9 @@ assert('String#rindex(UTF-8)', '15.2.10.5.31') do assert_equal nil, str.index("さ") end if UTF8STRING -# 'String#scan', '15.2.10.5.32' will be tested in mrbgems. +# assert('String#scan', '15.2.10.5.32') do +# # Not implemented yet +# end assert('String#size', '15.2.10.5.33') do assert_equal 3, 'abc'.size -- cgit v1.2.3 From 0692f7916cc9865e276a58812186cac7f02dc042 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Fri, 3 May 2019 13:39:19 +0900 Subject: Simplify conversion process for `i` in `mrb_get_args()` --- src/class.c | 24 +----------------------- test/t/string.rb | 11 +++++++---- 2 files changed, 8 insertions(+), 27 deletions(-) (limited to 'test/t/string.rb') diff --git a/src/class.c b/src/class.c index 254f5b005..2cabc820e 100644 --- a/src/class.c +++ b/src/class.c @@ -838,29 +838,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) p = va_arg(ap, mrb_int*); if (i < argc) { - switch (mrb_type(ARGV[arg_i])) { - case MRB_TT_FIXNUM: - *p = mrb_fixnum(ARGV[arg_i]); - break; -#ifndef MRB_WITHOUT_FLOAT - case MRB_TT_FLOAT: - { - mrb_float f = mrb_float(ARGV[arg_i]); - - if (!FIXABLE_FLOAT(f)) { - mrb_raise(mrb, E_RANGE_ERROR, "float too big for int"); - } - *p = (mrb_int)f; - } - break; -#endif - case MRB_TT_STRING: - mrb_raise(mrb, E_TYPE_ERROR, "no implicit conversion of String into Integer"); - break; - default: - *p = mrb_fixnum(mrb_Integer(mrb, ARGV[arg_i])); - break; - } + *p = mrb_fixnum(mrb_to_int(mrb, ARGV[arg_i])); arg_i++; i++; } diff --git a/test/t/string.rb b/test/t/string.rb index e563db55a..e5b001366 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -37,11 +37,14 @@ end assert('String#*', '15.2.10.5.5') do assert_equal 'aaaaa', 'a' * 5 assert_equal '', 'a' * 0 - assert_raise(ArgumentError) do - 'a' * -1 - end + assert_equal 'aa', 'a' * 2.1 + assert_raise(ArgumentError) { 'a' * -1 } + assert_raise(RangeError) { '' * 1e30 } + assert_raise(RangeError) { '' * Float::INFINITY } + assert_raise(RangeError) { '' * Float::NAN } + assert_raise(TypeError) { 'a' * '1' } + assert_raise(TypeError) { 'a' * nil } end - assert('String#[]', '15.2.10.5.6') do # length of args is 1 a = 'abc'[0] -- cgit v1.2.3 From 2e160f53dbd69598ec6a3ee8a15f85b4cf5168cf Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Sat, 8 Jun 2019 22:32:19 +0900 Subject: Remove "Check the usage of a NUL character" test Because there is not assertion in this test and NUL character literal is used in other tests. --- test/t/string.rb | 4 ---- 1 file changed, 4 deletions(-) (limited to 'test/t/string.rb') diff --git a/test/t/string.rb b/test/t/string.rb index e5b001366..9817dd188 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -694,10 +694,6 @@ assert('String interpolation (mrb_str_concat for shared strings)') do assert_equal "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA:", "#{a}:" end -assert('Check the usage of a NUL character') do - "qqq\0ppp" -end - assert('String#bytes') do str1 = "hello" bytes1 = [104, 101, 108, 108, 111] -- cgit v1.2.3 From 5af8a9777be82838b65c5b84bb2758f5395df998 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 22 Jun 2019 22:58:08 +0900 Subject: Add test for one UTF-8 charactor --- test/t/string.rb | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'test/t/string.rb') diff --git a/test/t/string.rb b/test/t/string.rb index 9817dd188..7ef236dbe 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -479,6 +479,7 @@ assert('String#reverse(UTF-8)', '15.2.10.5.29') do assert_equal 'こんにちは世界!', a assert_equal '!界世はちにんこ', 'こんにちは世界!'.reverse + assert_equal 'あ', 'あ'.reverse end if UTF8STRING assert('String#reverse!', '15.2.10.5.30') do @@ -495,6 +496,10 @@ assert('String#reverse!(UTF-8)', '15.2.10.5.30') do assert_equal '!界世はちにんこ', a assert_equal '!界世はちにんこ', 'こんにちは世界!'.reverse! + + b = 'あ' + b.reverse! + assert_equal 'あ', b end if UTF8STRING assert('String#rindex', '15.2.10.5.31') do -- cgit v1.2.3 From bc3176da630e3e055d58aa065ff897aec66df280 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Fri, 28 Jun 2019 19:26:29 +0900 Subject: Use `__ENCODING__` in tests It cannot be used for `String#size` test if judging whether or not `MRB_UTF8_STRING` is defined by result of `String#size`. --- mrbgems/mruby-string-ext/test/string.rb | 2 +- mrbgems/mruby-symbol-ext/test/symbol.rb | 2 +- test/t/string.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'test/t/string.rb') diff --git a/mrbgems/mruby-string-ext/test/string.rb b/mrbgems/mruby-string-ext/test/string.rb index bf633bcef..9a324c46d 100644 --- a/mrbgems/mruby-string-ext/test/string.rb +++ b/mrbgems/mruby-string-ext/test/string.rb @@ -2,7 +2,7 @@ ## # String(Ext) Test -UTF8STRING = ("\343\201\202".size == 1) +UTF8STRING = __ENCODING__ == "UTF-8" assert('String#getbyte') do str1 = "hello" diff --git a/mrbgems/mruby-symbol-ext/test/symbol.rb b/mrbgems/mruby-symbol-ext/test/symbol.rb index 61ecad247..db686e5f4 100644 --- a/mrbgems/mruby-symbol-ext/test/symbol.rb +++ b/mrbgems/mruby-symbol-ext/test/symbol.rb @@ -14,7 +14,7 @@ end assert("Symbol##{n}") do assert_equal 5, :hello.__send__(n) assert_equal 4, :"aA\0b".__send__(n) - if "あ".size == 1 # enable MRB_UTF8_STRING? + if __ENCODING__ == "UTF-8" assert_equal 8, :"こんにちは世界!".__send__(n) assert_equal 4, :"aあ\0b".__send__(n) else diff --git a/test/t/string.rb b/test/t/string.rb index 7ef236dbe..81699f17e 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -2,7 +2,7 @@ ## # String ISO Test -UTF8STRING = ("\343\201\202".size == 1) +UTF8STRING = __ENCODING__ == "UTF-8" assert('String', '15.2.10') do assert_equal Class, String.class -- cgit v1.2.3 From 40030a5dbc2b76bbd9563cdfc6389ab672312b70 Mon Sep 17 00:00:00 2001 From: dearblue Date: Tue, 21 May 2019 21:58:53 +0900 Subject: Add test for `String#[]=` --- test/t/string.rb | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'test/t/string.rb') diff --git a/test/t/string.rb b/test/t/string.rb index 81699f17e..87d60ed72 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -209,6 +209,56 @@ assert('String#[]=') do assert_raise(TypeError) { 'a'[0, 1] = 1 } end +assert('String[]=(UTF-8)') do + a = "➀➁➂➃➄" + a[3] = "⚃" + assert_equal "➀➁➂⚃➄", a + + b = "➀➁➂➃➄" + b[3, 0] = "⛄" + assert_equal "➀➁➂⛄➃➄", b + + c = "➀➁➂➃➄" + c[3, 2] = "⚃⚄" + assert_equal "➀➁➂⚃⚄", c + + d = "➀➁➂➃➄" + d[5] = "⛄" + assert_equal "➀➁➂➃➄⛄", d + + e = "➀➁➂➃➄" + e[5, 0] = "⛄" + assert_equal "➀➁➂➃➄⛄", e + + f = "➀➁➂➃➄" + f[5, 2] = "⛄" + assert_equal "➀➁➂➃➄⛄", f + + g = "➀➁➂➃➄" + assert_raise(IndexError) { g[6] = "⛄" } + + h = "➀➁➂➃➄" + assert_raise(IndexError) { h[6, 0] = "⛄" } + + i = "➀➁➂➃➄" + assert_raise(IndexError) { i[6, 2] = "⛄" } + + j = "➀➁➂➃➄" + j["➃"] = "⚃" + assert_equal "➀➁➂⚃➄", j + + k = "➀➁➂➃➄" + assert_raise(IndexError) { k["⛄"] = "⛇" } + + l = "➀➁➂➃➄" + assert_nothing_raised { l["➂"] = "" } + assert_equal "➀➁➃➄", l + + m = "➀➁➂➃➄" + assert_raise(TypeError) { m["➂"] = nil } + assert_equal "➀➁➂➃➄", m +end if UTF8STRING + assert('String#capitalize', '15.2.10.5.7') do a = 'abc' a.capitalize -- cgit v1.2.3 From e4249b1b9e1c568546865287bf367e4501c263de Mon Sep 17 00:00:00 2001 From: dearblue Date: Thu, 11 Jul 2019 22:00:01 +0900 Subject: Add UTF-8 test for `String#index` --- test/t/string.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'test/t/string.rb') diff --git a/test/t/string.rb b/test/t/string.rb index 87d60ed72..cf145f97e 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -468,6 +468,17 @@ assert('String#index', '15.2.10.5.22') do assert_equal nil, "hello".index("", 6) end +assert('String#index(UTF-8)', '15.2.10.5.22') do + assert_equal 0, '⓿➊➋➌➍➎'.index('⓿') + assert_nil '⓿➊➋➌➍➎'.index('➓') + assert_equal 6, '⓿➊➋➌➍➎⓿➊➋➌➍➎'.index('⓿', 1) + assert_equal 6, "⓿➊➋➌➍➎".index("", 6) + assert_equal nil, "⓿➊➋➌➍➎".index("", 7) + assert_equal 0, '⓿➊➋➌➍➎'.index("\xe2") + assert_equal nil, '⓿➊➋➌➍➎'.index("\xe3") + assert_equal 6, "\xd1\xd1\xd1\xd1\xd1\xd1⓿➊➋➌➍➎".index('⓿') +end if UTF8STRING + assert('String#initialize', '15.2.10.5.23') do a = '' a.initialize('abc') -- cgit v1.2.3 From 9d2272ec2ca00e8951a61e2e1f287de04ee7f1c6 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Wed, 17 Jul 2019 20:09:37 +0900 Subject: Fix `String#[]` test --- test/t/string.rb | 47 +++++++++++++++-------------------------------- 1 file changed, 15 insertions(+), 32 deletions(-) (limited to 'test/t/string.rb') diff --git a/test/t/string.rb b/test/t/string.rb index cf145f97e..af944b359 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -45,44 +45,27 @@ assert('String#*', '15.2.10.5.5') do assert_raise(TypeError) { 'a' * '1' } assert_raise(TypeError) { 'a' * nil } end + assert('String#[]', '15.2.10.5.6') do # length of args is 1 - a = 'abc'[0] - b = 'abc'[-1] - c = 'abc'[10] - d = 'abc'[-10] - e = 'abc'[1.1] + assert_equal 'a', 'abc'[0] + assert_equal 'c', 'abc'[-1] + assert_nil 'abc'[10] + assert_nil 'abc'[-10] + assert_equal 'b', 'abc'[1.1] if Object.const_defined?(:Float) # length of args is 2 - a1 = 'abc'[0, -1] - b1 = 'abc'[10, 0] - c1 = 'abc'[-10, 0] - d1 = 'abc'[0, 0] - e1 = 'abc'[1, 2] - - # args is RegExp - # It will be tested in mrbgems. + assert_nil 'abc'[0, -1] + assert_nil 'abc'[10, 0] + assert_nil 'abc'[-10, 0] + assert_equal '', 'abc'[0, 0] + assert_equal 'bc', 'abc'[1, 2] # args is String - a3 = 'abc'['bc'] - b3 = 'abc'['XX'] - - assert_equal 'a', 'a' - # assert_equal 'c', b - # assert_nil c - # assert_nil d - # assert_equal 'b', e - # assert_nil a1 - # assert_nil b1 - # assert_nil c1 - # assert_equal '', d1 - # assert_equal 'bc', e1 - # assert_equal 'bc', a3 - # assert_nil b3 - - # assert_raise(TypeError) do - # a[nil] - # end + assert_equal 'bc', 'abc'['bc'] + assert_nil 'abc'['XX'] + + assert_raise(TypeError) { 'abc'[nil] } end assert('String#[](UTF-8)', '15.2.10.5.6') do -- cgit v1.2.3 From 9873d5e0b9f1d3be9b2c97a21789ccdbd500e039 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Thu, 18 Jul 2019 17:51:02 +0900 Subject: Fix `String#*` test with `MRB_WITHOUT_FLOAT` --- test/t/string.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'test/t/string.rb') diff --git a/test/t/string.rb b/test/t/string.rb index af944b359..46cbe6e2a 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -37,13 +37,15 @@ end assert('String#*', '15.2.10.5.5') do assert_equal 'aaaaa', 'a' * 5 assert_equal '', 'a' * 0 - assert_equal 'aa', 'a' * 2.1 assert_raise(ArgumentError) { 'a' * -1 } + assert_raise(TypeError) { 'a' * '1' } + assert_raise(TypeError) { 'a' * nil } + + skip unless Object.const_defined?(:Float) + assert_equal 'aa', 'a' * 2.1 assert_raise(RangeError) { '' * 1e30 } assert_raise(RangeError) { '' * Float::INFINITY } assert_raise(RangeError) { '' * Float::NAN } - assert_raise(TypeError) { 'a' * '1' } - assert_raise(TypeError) { 'a' * nil } end assert('String#[]', '15.2.10.5.6') do -- cgit v1.2.3 From cf5f290fa0b062c8cb99e2aa85f2486f6601f116 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 10 Aug 2019 22:17:35 +0900 Subject: Fix `String#rindex` test for UTF-8 string --- test/t/string.rb | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'test/t/string.rb') diff --git a/test/t/string.rb b/test/t/string.rb index 46cbe6e2a..1aa254cd0 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -557,10 +557,9 @@ end assert('String#rindex(UTF-8)', '15.2.10.5.31') do str = "こんにちは世界!\nこんにちは世界!" - assert_nil str.index('さ') - assert_equal 3, str.index('ち') - assert_equal 12, str.index('ち', 10) - assert_equal nil, str.index("さ") + assert_nil str.rindex('さ') + assert_equal 12, str.rindex('ち') + assert_equal 3, str.rindex('ち', 10) end if UTF8STRING # assert('String#scan', '15.2.10.5.32') do -- cgit v1.2.3 From 414ab682f37118288864f5298ea5eb2cd3791dd2 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 10 Aug 2019 22:18:23 +0900 Subject: Add `String#rindex` test for invalid UTF-8 string --- test/t/string.rb | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'test/t/string.rb') diff --git a/test/t/string.rb b/test/t/string.rb index 1aa254cd0..7e3c327b1 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -560,6 +560,13 @@ assert('String#rindex(UTF-8)', '15.2.10.5.31') do assert_nil str.rindex('さ') assert_equal 12, str.rindex('ち') assert_equal 3, str.rindex('ち', 10) + + broken = "\xf0☀\xf1☁\xf2☂\xf3☃\xf0☀\xf1☁\xf2☂\xf3☃" + assert_nil broken.rindex("\x81") # "\x81" is a part of "☁" ("\xe2\x98\x81") + assert_equal 11, broken.rindex("☁") + assert_equal 11, broken.rindex("☁", 12) + assert_equal 11, broken.rindex("☁", 11) + assert_equal 3, broken.rindex("☁", 10) end if UTF8STRING # assert('String#scan', '15.2.10.5.32') do -- cgit v1.2.3 From 04b098d000c129b1efde98904b9a1b411b32a46a Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 11 Sep 2019 18:49:08 +0900 Subject: Move tests related to `getbyte`, `setbyte`, byteslice` to core. --- mrbgems/mruby-string-ext/test/string.rb | 79 --------------------------------- test/t/string.rb | 79 +++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 79 deletions(-) (limited to 'test/t/string.rb') diff --git a/mrbgems/mruby-string-ext/test/string.rb b/mrbgems/mruby-string-ext/test/string.rb index edbeb02d7..6914fe31d 100644 --- a/mrbgems/mruby-string-ext/test/string.rb +++ b/mrbgems/mruby-string-ext/test/string.rb @@ -10,85 +10,6 @@ def assert_upto(exp, receiver, *args) assert_equal exp, act end -assert('String#getbyte') do - str1 = "hello" - bytes1 = [104, 101, 108, 108, 111] - assert_equal bytes1[0], str1.getbyte(0) - assert_equal bytes1[-1], str1.getbyte(-1) - assert_equal bytes1[6], str1.getbyte(6) - - str2 = "\xFF" - bytes2 = [0xFF] - assert_equal bytes2[0], str2.getbyte(0) -end - -assert('String#setbyte') do - str1 = "hello" - h = "H".getbyte(0) - str1.setbyte(0, h) - assert_equal(h, str1.getbyte(0)) - assert_equal("Hello", str1) -end - -assert('String#byteslice') do - str1 = "hello" - str2 = "\u3042ab" # "\xE3\x81\x82ab" - - assert_equal("h", str1.byteslice(0)) - assert_equal("e", str1.byteslice(1)) - assert_equal(nil, str1.byteslice(5)) - assert_equal("o", str1.byteslice(-1)) - assert_equal(nil, str1.byteslice(-6)) - assert_equal("\xE3", str2.byteslice(0)) - assert_equal("\x81", str2.byteslice(1)) - assert_equal(nil, str2.byteslice(5)) - assert_equal("b", str2.byteslice(-1)) - assert_equal(nil, str2.byteslice(-6)) - - assert_equal("", str1.byteslice(0, 0)) - assert_equal(str1, str1.byteslice(0, 6)) - assert_equal("el", str1.byteslice(1, 2)) - assert_equal("", str1.byteslice(5, 1)) - assert_equal("o", str1.byteslice(-1, 6)) - assert_equal(nil, str1.byteslice(-6, 1)) - assert_equal(nil, str1.byteslice(0, -1)) - assert_equal("", str2.byteslice(0, 0)) - assert_equal(str2, str2.byteslice(0, 6)) - assert_equal("\x81\x82", str2.byteslice(1, 2)) - assert_equal("", str2.byteslice(5, 1)) - assert_equal("b", str2.byteslice(-1, 6)) - assert_equal(nil, str2.byteslice(-6, 1)) - assert_equal(nil, str2.byteslice(0, -1)) - - assert_equal("ell", str1.byteslice(1..3)) - assert_equal("el", str1.byteslice(1...3)) - assert_equal("h", str1.byteslice(0..0)) - assert_equal("", str1.byteslice(5..0)) - assert_equal("o", str1.byteslice(4..5)) - assert_equal(nil, str1.byteslice(6..0)) - assert_equal("", str1.byteslice(-1..0)) - assert_equal("llo", str1.byteslice(-3..5)) - assert_equal("\x81\x82a", str2.byteslice(1..3)) - assert_equal("\x81\x82", str2.byteslice(1...3)) - assert_equal("\xE3", str2.byteslice(0..0)) - assert_equal("", str2.byteslice(5..0)) - assert_equal("b", str2.byteslice(4..5)) - assert_equal(nil, str2.byteslice(6..0)) - assert_equal("", str2.byteslice(-1..0)) - assert_equal("\x82ab", str2.byteslice(-3..5)) - - assert_raise(ArgumentError) { str1.byteslice } - assert_raise(ArgumentError) { str1.byteslice(1, 2, 3) } - assert_raise(TypeError) { str1.byteslice("1") } - assert_raise(TypeError) { str1.byteslice("1", 2) } - assert_raise(TypeError) { str1.byteslice(1, "2") } - assert_raise(TypeError) { str1.byteslice(1..2, 3) } - - skip unless Object.const_defined?(:Float) - assert_equal("o", str1.byteslice(4.0)) - assert_equal("\x82ab", str2.byteslice(2.0, 3.0)) -end - assert('String#dump') do assert_equal("\"\\x00\"", "\0".dump) assert_equal("\"foo\"", "foo".dump) diff --git a/test/t/string.rb b/test/t/string.rb index 7e3c327b1..c820bfa92 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -784,3 +784,82 @@ assert('String literal concatenation') do assert_equal 3, ('A' "B" 'C').size assert_equal 4, (%(A) "B#{?C}" "D").size end + +assert('String#getbyte') do + str1 = "hello" + bytes1 = [104, 101, 108, 108, 111] + assert_equal bytes1[0], str1.getbyte(0) + assert_equal bytes1[-1], str1.getbyte(-1) + assert_equal bytes1[6], str1.getbyte(6) + + str2 = "\xFF" + bytes2 = [0xFF] + assert_equal bytes2[0], str2.getbyte(0) +end + +assert('String#setbyte') do + str1 = "hello" + h = "H".getbyte(0) + str1.setbyte(0, h) + assert_equal(h, str1.getbyte(0)) + assert_equal("Hello", str1) +end + +assert('String#byteslice') do + str1 = "hello" + str2 = "\u3042ab" # "\xE3\x81\x82ab" + + assert_equal("h", str1.byteslice(0)) + assert_equal("e", str1.byteslice(1)) + assert_equal(nil, str1.byteslice(5)) + assert_equal("o", str1.byteslice(-1)) + assert_equal(nil, str1.byteslice(-6)) + assert_equal("\xE3", str2.byteslice(0)) + assert_equal("\x81", str2.byteslice(1)) + assert_equal(nil, str2.byteslice(5)) + assert_equal("b", str2.byteslice(-1)) + assert_equal(nil, str2.byteslice(-6)) + + assert_equal("", str1.byteslice(0, 0)) + assert_equal(str1, str1.byteslice(0, 6)) + assert_equal("el", str1.byteslice(1, 2)) + assert_equal("", str1.byteslice(5, 1)) + assert_equal("o", str1.byteslice(-1, 6)) + assert_equal(nil, str1.byteslice(-6, 1)) + assert_equal(nil, str1.byteslice(0, -1)) + assert_equal("", str2.byteslice(0, 0)) + assert_equal(str2, str2.byteslice(0, 6)) + assert_equal("\x81\x82", str2.byteslice(1, 2)) + assert_equal("", str2.byteslice(5, 1)) + assert_equal("b", str2.byteslice(-1, 6)) + assert_equal(nil, str2.byteslice(-6, 1)) + assert_equal(nil, str2.byteslice(0, -1)) + + assert_equal("ell", str1.byteslice(1..3)) + assert_equal("el", str1.byteslice(1...3)) + assert_equal("h", str1.byteslice(0..0)) + assert_equal("", str1.byteslice(5..0)) + assert_equal("o", str1.byteslice(4..5)) + assert_equal(nil, str1.byteslice(6..0)) + assert_equal("", str1.byteslice(-1..0)) + assert_equal("llo", str1.byteslice(-3..5)) + assert_equal("\x81\x82a", str2.byteslice(1..3)) + assert_equal("\x81\x82", str2.byteslice(1...3)) + assert_equal("\xE3", str2.byteslice(0..0)) + assert_equal("", str2.byteslice(5..0)) + assert_equal("b", str2.byteslice(4..5)) + assert_equal(nil, str2.byteslice(6..0)) + assert_equal("", str2.byteslice(-1..0)) + assert_equal("\x82ab", str2.byteslice(-3..5)) + + assert_raise(ArgumentError) { str1.byteslice } + assert_raise(ArgumentError) { str1.byteslice(1, 2, 3) } + assert_raise(TypeError) { str1.byteslice("1") } + assert_raise(TypeError) { str1.byteslice("1", 2) } + assert_raise(TypeError) { str1.byteslice(1, "2") } + assert_raise(TypeError) { str1.byteslice(1..2, 3) } + + skip unless Object.const_defined?(:Float) + assert_equal("o", str1.byteslice(4.0)) + assert_equal("\x82ab", str2.byteslice(2.0, 3.0)) +end -- cgit v1.2.3 From e61095426bbb0de2ab0a941f9ed3a3acdb7833e8 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Thu, 19 Sep 2019 20:19:38 +0900 Subject: Simplify arguments check in `String#index` Also fix document about type of the first argument. --- src/string.c | 54 +++++++++++++----------------------------------------- test/t/string.rb | 4 ++++ 2 files changed, 17 insertions(+), 41 deletions(-) (limited to 'test/t/string.rb') diff --git a/src/string.c b/src/string.c index 7abb3148c..48df958ec 100644 --- a/src/string.c +++ b/src/string.c @@ -1757,22 +1757,16 @@ mrb_str_include(mrb_state *mrb, mrb_value self) /* * call-seq: * str.index(substring [, offset]) => fixnum or nil - * str.index(fixnum [, offset]) => fixnum or nil - * str.index(regexp [, offset]) => fixnum or nil * * Returns the index of the first occurrence of the given - * substring, - * character (fixnum), or pattern (regexp) in str. - * Returns - * nil if not found. + * substring. Returns nil if not found. * If the second parameter is present, it * specifies the position in the string to begin the search. * - * "hello".index('e') #=> 1 + * "hello".index('l') #=> 2 * "hello".index('lo') #=> 3 * "hello".index('a') #=> nil - * "hello".index(101) #=> 1(101=0x65='e') - * "hello".index(/[aeiou]/, -3) #=> 4 + * "hello".index('l', -2) #=> 3 */ static mrb_value mrb_str_index_m(mrb_state *mrb, mrb_value str) @@ -1780,39 +1774,17 @@ mrb_str_index_m(mrb_state *mrb, mrb_value str) mrb_value sub; mrb_int pos; - switch (mrb_get_args(mrb, "|oi", &sub, &pos)) { - case 0: - sub = mrb_nil_value(); - /* fall through */ - case 1: - pos = 0; - break; - case 2: - if (pos < 0) { - mrb_int clen = RSTRING_CHAR_LEN(str); - pos += clen; - if (pos < 0) { - return mrb_nil_value(); - } - } - break; + if (mrb_get_args(mrb, "S|i", &sub, &pos) == 1) { + pos = 0; } - - switch (mrb_type(sub)) { - default: { - mrb_value tmp; - - tmp = mrb_check_string_type(mrb, sub); - if (mrb_nil_p(tmp)) { - mrb_raisef(mrb, E_TYPE_ERROR, "type mismatch: %v given", sub); - } - sub = tmp; + else if (pos < 0) { + mrb_int clen = RSTRING_CHAR_LEN(str); + pos += clen; + if (pos < 0) { + return mrb_nil_value(); } - /* fall through */ - case MRB_TT_STRING: - pos = str_index_str_by_char(mrb, str, sub, pos); - break; } + pos = str_index_str_by_char(mrb, str, sub, pos); if (pos == -1) return mrb_nil_value(); BYTES_ALIGN_CHECK(pos); @@ -3057,7 +3029,7 @@ mrb_init_string(mrb_state *mrb) mrb_define_method(mrb, s, "hash", mrb_str_hash_m, MRB_ARGS_NONE()); /* 15.2.10.5.20 */ mrb_define_method(mrb, s, "include?", mrb_str_include, MRB_ARGS_REQ(1)); /* 15.2.10.5.21 */ - mrb_define_method(mrb, s, "index", mrb_str_index_m, MRB_ARGS_ANY()); /* 15.2.10.5.22 */ + mrb_define_method(mrb, s, "index", mrb_str_index_m, MRB_ARGS_ARG(1,1)); /* 15.2.10.5.22 */ mrb_define_method(mrb, s, "initialize", mrb_str_init, MRB_ARGS_REQ(1)); /* 15.2.10.5.23 */ mrb_define_method(mrb, s, "initialize_copy", mrb_str_replace, MRB_ARGS_REQ(1)); /* 15.2.10.5.24 */ mrb_define_method(mrb, s, "intern", mrb_str_intern, MRB_ARGS_NONE()); /* 15.2.10.5.25 */ @@ -3084,7 +3056,7 @@ mrb_init_string(mrb_state *mrb) mrb_define_method(mrb, s, "getbyte", mrb_str_getbyte, MRB_ARGS_REQ(1)); mrb_define_method(mrb, s, "setbyte", mrb_str_setbyte, MRB_ARGS_REQ(2)); - mrb_define_method(mrb, s, "byteslice", mrb_str_byteslice, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)); + mrb_define_method(mrb, s, "byteslice", mrb_str_byteslice, MRB_ARGS_ARG(1,1)); } #ifndef MRB_WITHOUT_FLOAT diff --git a/test/t/string.rb b/test/t/string.rb index c820bfa92..01f3da327 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -451,12 +451,16 @@ assert('String#index', '15.2.10.5.22') do assert_equal 3, 'abcabc'.index('a', 1) assert_equal 5, "hello".index("", 5) assert_equal nil, "hello".index("", 6) + assert_equal 3, "hello".index("l", -2) + assert_raise(ArgumentError) { "hello".index } + assert_raise(TypeError) { "hello".index(101) } end assert('String#index(UTF-8)', '15.2.10.5.22') do assert_equal 0, '⓿➊➋➌➍➎'.index('⓿') assert_nil '⓿➊➋➌➍➎'.index('➓') assert_equal 6, '⓿➊➋➌➍➎⓿➊➋➌➍➎'.index('⓿', 1) + assert_equal 6, '⓿➊➋➌➍➎⓿➊➋➌➍➎'.index('⓿', -7) assert_equal 6, "⓿➊➋➌➍➎".index("", 6) assert_equal nil, "⓿➊➋➌➍➎".index("", 7) assert_equal 0, '⓿➊➋➌➍➎'.index("\xe2") -- cgit v1.2.3 From 198683e914ebaceba7b989c6592f871ac8fe5aa0 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Fri, 27 Sep 2019 17:13:57 +0900 Subject: Simplify arguments check in `String#rindex` Also fix document about type of the first argument. --- src/string.c | 67 ++++++++++++++++++-------------------------------------- test/t/string.rb | 8 +++++++ 2 files changed, 29 insertions(+), 46 deletions(-) (limited to 'test/t/string.rb') diff --git a/src/string.c b/src/string.c index b49fdfc2e..1428ea780 100644 --- a/src/string.c +++ b/src/string.c @@ -1977,21 +1977,17 @@ mrb_str_reverse(mrb_state *mrb, mrb_value str) /* 15.2.10.5.31 */ /* * call-seq: - * str.rindex(substring [, fixnum]) => fixnum or nil - * str.rindex(fixnum [, fixnum]) => fixnum or nil - * str.rindex(regexp [, fixnum]) => fixnum or nil + * str.rindex(substring [, offset]) => fixnum or nil * - * Returns the index of the last occurrence of the given substring, - * character (fixnum), or pattern (regexp) in str. Returns - * nil if not found. If the second parameter is present, it - * specifies the position in the string to end the search---characters beyond - * this point will not be considered. + * Returns the index of the last occurrence of the given substring. + * Returns nil if not found. If the second parameter is + * present, it specifies the position in the string to end the + * search---characters beyond this point will not be considered. * * "hello".rindex('e') #=> 1 * "hello".rindex('l') #=> 3 * "hello".rindex('a') #=> nil - * "hello".rindex(101) #=> 1 - * "hello".rindex(/[aeiou]/, -2) #=> 1 + * "hello".rindex('l', 2) #=> 2 */ static mrb_value mrb_str_rindex(mrb_state *mrb, mrb_value str) @@ -1999,46 +1995,25 @@ mrb_str_rindex(mrb_state *mrb, mrb_value str) mrb_value sub; mrb_int pos, len = RSTRING_CHAR_LEN(str); - switch (mrb_get_args(mrb, "|oi", &sub, &pos)) { - case 0: - sub = mrb_nil_value(); - /* fall through */ - case 1: - pos = len; - break; - case 2: + if (mrb_get_args(mrb, "S|i", &sub, &pos) == 1) { + pos = len; + } + else { + if (pos < 0) { + pos += len; if (pos < 0) { - pos += len; - if (pos < 0) { - return mrb_nil_value(); - } + return mrb_nil_value(); } - if (pos > len) pos = len; - break; + } + if (pos > len) pos = len; } pos = chars2bytes(str, 0, pos); - - switch (mrb_type(sub)) { - default: { - mrb_value tmp; - - tmp = mrb_check_string_type(mrb, sub); - if (mrb_nil_p(tmp)) { - mrb_raisef(mrb, E_TYPE_ERROR, "type mismatch: %v given", sub); - } - sub = tmp; - } - /* fall through */ - case MRB_TT_STRING: - pos = str_rindex(mrb, str, sub, pos); - if (pos >= 0) { - pos = bytes2chars(RSTRING_PTR(str), RSTRING_LEN(str), pos); - BYTES_ALIGN_CHECK(pos); - return mrb_fixnum_value(pos); - } - break; - - } /* end of switch (TYPE(sub)) */ + pos = str_rindex(mrb, str, sub, pos); + if (pos >= 0) { + pos = bytes2chars(RSTRING_PTR(str), RSTRING_LEN(str), pos); + BYTES_ALIGN_CHECK(pos); + return mrb_fixnum_value(pos); + } return mrb_nil_value(); } diff --git a/test/t/string.rb b/test/t/string.rb index 01f3da327..e1ff48312 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -554,9 +554,16 @@ end if UTF8STRING assert('String#rindex', '15.2.10.5.31') do assert_equal 0, 'abc'.rindex('a') + assert_equal 0, 'abc'.rindex('a', 3) + assert_nil 'abc'.rindex('a', -4) assert_nil 'abc'.rindex('d') + assert_equal 6, 'abcabc'.rindex('') + assert_equal 3, 'abcabc'.rindex('a') assert_equal 0, 'abcabc'.rindex('a', 1) assert_equal 3, 'abcabc'.rindex('a', 4) + assert_equal 0, 'abcabc'.rindex('a', -4) + assert_raise(ArgumentError) { "hello".rindex } + assert_raise(TypeError) { "hello".rindex(101) } end assert('String#rindex(UTF-8)', '15.2.10.5.31') do @@ -564,6 +571,7 @@ assert('String#rindex(UTF-8)', '15.2.10.5.31') do assert_nil str.rindex('さ') assert_equal 12, str.rindex('ち') assert_equal 3, str.rindex('ち', 10) + assert_equal 3, str.rindex('ち', -6) broken = "\xf0☀\xf1☁\xf2☂\xf3☃\xf0☀\xf1☁\xf2☂\xf3☃" assert_nil broken.rindex("\x81") # "\x81" is a part of "☁" ("\xe2\x98\x81") -- cgit v1.2.3 From 7ce5d3394706723a82d337641f960c58649e0134 Mon Sep 17 00:00:00 2001 From: KOBAYASHI Shuji Date: Thu, 10 Oct 2019 19:50:48 +0900 Subject: Integrate `mrb_str_inspect` and `mrb_str_dump` --- mrbgems/mruby-string-ext/test/string.rb | 1 + src/string.c | 261 ++++++++++---------------------- test/t/string.rb | 12 +- 3 files changed, 90 insertions(+), 184 deletions(-) (limited to 'test/t/string.rb') diff --git a/mrbgems/mruby-string-ext/test/string.rb b/mrbgems/mruby-string-ext/test/string.rb index 6914fe31d..3f11c00a0 100644 --- a/mrbgems/mruby-string-ext/test/string.rb +++ b/mrbgems/mruby-string-ext/test/string.rb @@ -13,6 +13,7 @@ end assert('String#dump') do assert_equal("\"\\x00\"", "\0".dump) assert_equal("\"foo\"", "foo".dump) + assert_equal('"\xe3\x82\x8b"', "る".dump) assert_nothing_raised { ("\1" * 100).dump } # regress #1210 end diff --git a/src/string.c b/src/string.c index 1428ea780..a45dee11e 100644 --- a/src/string.c +++ b/src/string.c @@ -1318,6 +1318,84 @@ str_replace_partial(mrb_state *mrb, mrb_value src, mrb_int pos, mrb_int end, mrb return src; } +#define CHAR_ESC_LEN 13 /* sizeof(\x{ hex of 32bit unsigned int } \0) */ +#define IS_EVSTR(p,e) ((p) < (e) && (*(p) == '$' || *(p) == '@' || *(p) == '{')) + +static mrb_value +str_escape(mrb_state *mrb, mrb_value str, mrb_bool inspect) +{ + const char *p, *pend; + char buf[CHAR_ESC_LEN + 1]; + mrb_value result = mrb_str_new_lit(mrb, "\""); +#ifdef MRB_UTF8_STRING + uint32_t ascii_flag = MRB_STR_ASCII; +#endif + + p = RSTRING_PTR(str); pend = RSTRING_END(str); + for (;p < pend; p++) { + unsigned char c, cc; +#ifdef MRB_UTF8_STRING + if (inspect) { + mrb_int clen = utf8len(p, pend); + if (clen > 1) { + mrb_int i; + + for (i=0; iflags |= ascii_flag; + mrb_str_ptr(result)->flags |= ascii_flag; +#endif + + return result; +} + static void mrb_str_aset(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen, mrb_value replace) { @@ -2574,8 +2652,6 @@ mrb_str_upcase(mrb_state *mrb, mrb_value self) return str; } -#define IS_EVSTR(p,e) ((p) < (e) && (*(p) == '$' || *(p) == '@' || *(p) == '{')) - /* * call-seq: * str.dump -> new_str @@ -2586,113 +2662,7 @@ mrb_str_upcase(mrb_state *mrb, mrb_value self) mrb_value mrb_str_dump(mrb_state *mrb, mrb_value str) { - mrb_int len; - const char *p, *pend; - char *q; - struct RString *result; - - len = 2; /* "" */ - p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str); - while (p < pend) { - unsigned char c = *p++; - switch (c) { - case '"': case '\\': - case '\n': case '\r': - case '\t': case '\f': - case '\013': case '\010': case '\007': case '\033': - len += 2; - break; - - case '#': - len += IS_EVSTR(p, pend) ? 2 : 1; - break; - - default: - if (ISPRINT(c)) { - len++; - } - else { - len += 4; /* \NNN */ - } - break; - } - } - - result = str_new(mrb, 0, len); - str_with_class(result, str); - p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str); - q = RSTR_PTR(result); - *q++ = '"'; - while (p < pend) { - unsigned char c = *p++; - - switch (c) { - case '"': - case '\\': - *q++ = '\\'; - *q++ = c; - break; - - case '\n': - *q++ = '\\'; - *q++ = 'n'; - break; - - case '\r': - *q++ = '\\'; - *q++ = 'r'; - break; - - case '\t': - *q++ = '\\'; - *q++ = 't'; - break; - - case '\f': - *q++ = '\\'; - *q++ = 'f'; - break; - - case '\013': - *q++ = '\\'; - *q++ = 'v'; - break; - - case '\010': - *q++ = '\\'; - *q++ = 'b'; - break; - - case '\007': - *q++ = '\\'; - *q++ = 'a'; - break; - - case '\033': - *q++ = '\\'; - *q++ = 'e'; - break; - - case '#': - if (IS_EVSTR(p, pend)) *q++ = '\\'; - *q++ = '#'; - break; - - default: - if (ISPRINT(c)) { - *q++ = c; - } - else { - *q++ = '\\'; - *q++ = 'x'; - q[1] = mrb_digitmap[c % 16]; c /= 16; - q[0] = mrb_digitmap[c % 16]; - q += 2; - } - } - } - *q = '"'; - return mrb_obj_value(result); + return str_escape(mrb, str, FALSE); } MRB_API mrb_value @@ -2762,8 +2732,6 @@ mrb_str_append(mrb_state *mrb, mrb_value str1, mrb_value str2) return mrb_str_cat_str(mrb, str1, str2); } -#define CHAR_ESC_LEN 13 /* sizeof(\x{ hex of 32bit unsigned int } \0) */ - /* * call-seq: * str.inspect -> string @@ -2778,76 +2746,7 @@ mrb_str_append(mrb_state *mrb, mrb_value str1, mrb_value str2) mrb_value mrb_str_inspect(mrb_state *mrb, mrb_value str) { - const char *p, *pend; - char buf[CHAR_ESC_LEN + 1]; - mrb_value result = mrb_str_new_lit(mrb, "\""); -#ifdef MRB_UTF8_STRING - uint32_t ascii_flag = MRB_STR_ASCII; -#endif - - p = RSTRING_PTR(str); pend = RSTRING_END(str); - for (;p < pend; p++) { - unsigned char c, cc; -#ifdef MRB_UTF8_STRING - mrb_int clen; - - clen = utf8len(p, pend); - if (clen > 1) { - mrb_int i; - - for (i=0; iflags |= ascii_flag; - mrb_str_ptr(result)->flags |= ascii_flag; -#endif - - return result; + return str_escape(mrb, str, TRUE); } /* diff --git a/test/t/string.rb b/test/t/string.rb index e1ff48312..65ad13103 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -748,12 +748,18 @@ assert('String#upcase!', '15.2.10.5.43') do end assert('String#inspect', '15.2.10.5.46') do + assert_equal "\"\\x00\"", "\0".inspect + assert_equal "\"foo\"", "foo".inspect + if UTF8STRING + assert_equal '"る"', "る".inspect + else + assert_equal '"\xe3\x82\x8b"', "る".inspect + end + # should not raise an exception - regress #1210 assert_nothing_raised do - ("\1" * 100).inspect + ("\1" * 100).inspect end - - assert_equal "\"\\x00\"", "\0".inspect end # Not ISO specified -- cgit v1.2.3