ようへいの日々精進XP

よかろうもん

Ruby の組み込みライブラリ (クラス) の「学習テスト」を書いて, 出来るだけ多くのメソッドと出会いたい (3)

これは...

いつまで続くかわからないシリーズである.

inokara.hateblo.jp

ということで

がちゃ

今日のメソッドガチャは以下の通り.

$ bundle exec ruby gacha.rb
クラス: String
メソッド: casecmp?
メソッド: to_i
メソッド: succ

この中から String#casecmp? と String#to_i 及び String#succ について学習テストしていく.

String#casecmp?

docs.ruby-lang.org

以下, ドキュメントより引用.

大文字小文字の違いを無視し文字列を比較します。 文字列が一致する場合には true を返し、一致しない場合には false を返します。

irb で試してみる.

irb(main):001:0> "abcdef".casecmp?("abcde") 
=> false
irb(main):002:0> "abcdef".casecmp?("abcdeF") 
=> true
irb(main):003:0> "abCDef".casecmp?("abCdeF") 
=> true
irb(main):004:0> "\u{e4 f6 fc}".casecmp?("\u{c4 d6 dc}")
=> true
irb(main):005:0>  "\u{e4 f6 fc}".encode("ISO-8859-1").casecmp?("\u{c4 d6 dc}")

テストは以下の通りに書いた.

# file name: 10-1.rb
require 'minitest/autorun'
require "minitest/reporters"
Minitest::Reporters.use! [Minitest::Reporters::SpecReporter.new]

class GakushuTest < Minitest::Test
  def test_string_casecmp_1
    assert "abcdef".casecmp?("abcdeF")
  end

  def test_string_casecmp_2
    assert "日本a語".casecmp?("日本A語")
  end

  def test_string_casecmp_3
    refute "abcdef".casecmp?("abdef")
  end

  def test_string_casecmp_4
    assert_nil "日本a語".encode("Shift_JIS").casecmp?("日本A語")
  end
end
  • 大文字, 小文字を無視して文字列を比較して true が返ることを期待する
  • 日本語と英字が混在していても比較出来ることを期待する
  • 文字列が異なる場合には false が返ることを期待する
  • エンコードが異なる場合, nil が返ることを期待する

テストを実行すると以下の通り.

$ bundle exec ruby 10-1.rb 
Started with run options --seed 51965

GakushuTest
  test_string_casecmp_3                                           PASS (0.00s)
  test_string_casecmp_2                                           PASS (0.00s)
  test_string_casecmp_1                                           PASS (0.00s)
  test_string_casecmp_4                                           PASS (0.00s)

Finished in 0.00133s
4 tests, 4 assertions, 0 failures, 0 errors, 0 skips

String#to_i

docs.ruby-lang.org

以下, ドキュメントより引用.

文字列を 10 進数表現された整数であると解釈して、整数に変換します。 (略) 整数とみなせない文字があればそこまでを変換対象とします。 変換対象が空文字列であれば 0 を返します。

irb で試してみる.

irb(main):001:0> "10".to_i
=> 10
irb(main):002:0> "+10".to_i
=> 10
irb(main):003:0> "-10".to_i
=> -10
irb(main):004:0> "A10B".to_i
=> 0
irb(main):005:0> "0x11".to_i
=> 0
irb(main):006:0> "x1x11".to_i
=> 0
irb(main):007:0> "".to_i
=> 0

"A10B".to_i"x1x11".to_i1 になるのかなって思ったけど, 0 になるのはアレって思っている. ドキュメントをちゃんと読み込めていないのかもしれないけど... 「整数とみなせない文字があればそこまでを変換対象」ということは, x1x11 は変換出来る文字列は無いと判断され, 結果として 0 となる.

String#to_i は基数を指定すると, 2 〜 36 進数表現に変換することが出来る. 以下, 2 進数表現を確認している.

irb(main):001:0> "01".to_i(2)
=> 1
irb(main):002:0> "10".to_i(2)
=> 2
irb(main):003:0> "100".to_i(2)
=> 4

テストは以下のように書いた.

# file name: 10-2.rb
require 'minitest/autorun'
require "minitest/reporters"
Minitest::Reporters.use! [Minitest::Reporters::SpecReporter.new]

class GakushuTest < Minitest::Test
  def test_string_to_i_1
    assert_equal "10".to_i, 10
  end

  def test_string_to_i_2
    assert_equal "-10".to_i, -10
  end

  def test_string_to_i_3
    assert_equal "".to_i, 0
  end

  def test_string_to_i_4
    assert_equal "2a10b".to_i, 2
  end

  def test_string_to_i_5
    assert_equal "100".to_i(2), 4
  end
end
  • シンプルな文字列 "10"10 に変換されることを期待
  • マイナスでも同様に変換されることを期待
  • 空文字は 0 に変換されることを期待
  • "2a10b" の場合には 2 までが変換されることを期待

テストを実行すると以下の通り.

$ bundle exec ruby 10-2.rb 
Started with run options --seed 7000

GakushuTest
  test_string_to_i_3                                              PASS (0.00s)
  test_string_to_i_1                                              PASS (0.00s)
  test_string_to_i_2                                              PASS (0.00s)
  test_string_to_i_5                                              PASS (0.00s)
  test_string_to_i_4                                              PASS (0.00s)

Finished in 0.00095s
5 tests, 5 assertions, 0 failures, 0 errors, 0 skips

String#succ

docs.ruby-lang.org

以下, ドキュメントより引用.

self の「次の」文字列を返します。

「次の」文字列は、対象の文字列の右端から アルファベットなら アルファベット順(aの次はb, zの次はa, 大文字も同様)に、 数字なら 10 進数(9 の次は 0)とみなして計算されます。

以下, irb にて確認.

irb(main):001:0> "a".succ
=> "b"
irb(main):002:0> "aa".succ
=> "ab"
irb(main):003:0> "aaa".succ
=> "aab"
irb(main):004:0> "aaabbcc".succ
=> "aaabbcd"
irb(main):005:0> "100".succ
=> "101"
irb(main):006:0> "-100".succ
=> "-101"
irb(main):007:0> "2.5.0".succ
=> "2.5.1"
irb(main):008:0> ".".succ
=> "/"
irb(main):009:0> ".".next
=> "/"
irb(main):010:0> "ab".next
=> "ac"

next メソッドも同様の挙動となる.

以下, テスト.

# file name: 10-3.rb
require 'minitest/autorun'
require "minitest/reporters"
Minitest::Reporters.use! [Minitest::Reporters::SpecReporter.new]

class GakushuTest < Minitest::Test
  def test_succ_1
    assert_equal "a".succ, "b"
  end

  def test_succ_2
    assert_equal "aa".succ, "ab"
  end

  def test_succ_3
    assert_equal "aabbcc".succ, "aabbcd"
  end

  def test_succ_4
    assert_equal "100".succ, "101"
  end

  def test_succ_5
    assert_equal "2.5.0".succ, "2.5.1"
  end
end
  • "a" の次は "b" になることを期待する
  • "aa" の場合は, 右端の a のみ変換されることを期待する
  • "aabbcc" の場合も同様に右端の c のみが変換されることを期待する
  • 数値文字列の場合も右端が対象となり 1 が加算される
  • アルファベットや数字とそれ以外の文字が混在している場合, アルファベットと数字が対象となることを期待する

テストを実行すると以下の通り.

$ bundle exec ruby 10-3.rb                                                                                            
Started with run options --seed 5360

GakushuTest
  test_succ_4                                                     PASS (0.00s)
  test_succ_5                                                     PASS (0.00s)
  test_succ_1                                                     PASS (0.00s)
  test_succ_2                                                     PASS (0.00s)
  test_succ_3                                                     PASS (0.00s)

Finished in 0.00086s
5 tests, 5 assertions, 0 failures, 0 errors, 0 skips

以上

メモでした.