vm2gol v2 (44) テストの追加



残りのテストをまとめて追加しました。

アセンブラ・コード生成器・パーサについては ひとまずライフゲームのコードを与えて出力が一致するか検証するようにしました。 これで、パース〜アセンブルまでの過程のうちどこが壊れているかが瞬時に分かるようになります。 もっと細かい粒度のテストは必要になったらその都度追加しようかと。

VM については命令レベルのテストを書きました。 最初はなるべく VM のコードをいじらずにテストを書こうとしていたのですが、 いろいろめんどくさかった(直交性が低くテストコードが煩雑になる)ので、純粋に1命令だけを実行した結果を検証できるようにしました。

# vgvm.rb
# before

  def start
    # ...

    loop do
      @step += 1
      op = @mem.main[@pc]
      pc_delta = 1 + Vm.num_args_for(op)

      case op
        when "exit"

        # 以下、case 式が続く

この部分を execute() というメソッドに抽出して、 VM命令のテストではこのメソッドを使うようにしました。

# after

  def execute
    op = @mem.main[@pc]
    pc_delta = 1 + Vm.num_args_for(op)

    case op
    when "exit"

    # ...

    end

    false
  end

  def start
    # ...

    loop do
      @step += 1

      do_exit = execute()
      return if do_exit

      # ...
    end
  end

あとは、VM命令をファイル以外の経路で渡せるようにしたり(これもテストのため)、 細かいリファクタリングなどです。

- refactor: project_path() に抽出 (test)
- refactor: PROJECT_DIR を helper.rb で定義するようにした (test)
- chore: rubocop Metrics/ClassLength: vgvm.rb を除外
- refactor: フラグ値を定数化 (vm)
- Add Vm#load_program()
- rename: load_program => load_program_file (vm)

というわけで、各ステップのテストが(雑ですが)用意できて、 これからいろいろいじっていい感じにしていくための用意ができました 🙌