<commit_before>require_relative '../spec_helper'

module RgGen
  describe Generator do
    before(:all) do
      @expected_rtl_code  = 2.times.map do |i|
        File.read("#{RGGEN_HOME}/sample/sample_#{i}.sv")
      end
      @expected_ral_code  = 2.times.map do |i|
        File.read("#{RGGEN_HOME}/sample/sample_#{i}_ral_pkg.sv")
      end
      @expected_c_header_code = 2.times.map do |i|
        File.read("#{RGGEN_HOME}/sample/sample_#{i}.h")
      end
    end

    before do
      cache   = factory_cache
      plugin  = factory_plugin
      allow(RgGen.builder).to receive(:build_factory).and_wrap_original do |m, component_name|
        f     = m.call(component_name)
        mock  = allow(f)
        if plugin.key?(component_name)
          mock.to receive(:create).and_wrap_original(&plugin[component_name])
        else
          mock.to receive(:create).and_call_original
        end
        cache[component_name] << f
        f
      end
    end

    after do
      clear_enabled_items
    end

    let(:generator) do
      Generator.new
    end

    let(:factory_cache) do
      Hash.new do |hash, component_name|
        hash[component_name]  = []
      end
    end

    let(:factory_plugin) do
      {}
    end

    let(:sample_setup) do
      "#{RGGEN_HOME}/sample/sample_setup.rb"
    end

    let(:sample_yaml) do
      "#{RGGEN_HOME}/sample/sample.yaml"
    end

    let(:sample_json) do
      "#{RGGEN_HOME}/sample/sample.json"
    end

    let(:sample_register_maps) do
      ["#{RGGEN_HOME}/sample/sample.xls", "#{RGGEN_HOME}/sample/sample.xlsx", "#{RGGEN_HOME}/sample/sample.csv"]
    end

    describe "RgGenホームディレクトリの表示" do
      let(:home) do
        "#{RgGen::RGGEN_HOME}\n"
      end

      it "RgGenのホームディレクトリを表示し、そのまま終了する" do
        expect {
          generator.run(['--show-home'])
        }.to raise_error(SystemExit).and output(home).to_stdout
      end
    end

    describe "バージョンの出力" do
      let(:version) do
        "rggen #{RgGen::VERSION}\n"
      end

      it "バージョンを出力し、そのまま終了する" do
        expect {
          generator.run(['-v'])
        }.to raise_error(SystemExit).and output(version).to_stdout
        expect {
          generator.run(['--version'])
        }.to raise_error(SystemExit).and output(version).to_stdout
      end
    end

    describe "ヘルプの表示" do
      let(:help) do
        <<HELP
Usage: rggen [options] REGISTER_MAP
        --setup FILE                 Specify a setup file to set up RgGen tool(default: #{RgGen::RGGEN_HOME}/setup/default.rb)
    -c, --configuration FILE         Specify a configuration file for generated source code
    -o, --output DIR                 Specify output directory(default: .)
        --except [TYPE1,TYPE2,...]   Disable the given output file type(s)
        --show-home                  Display the path of RgGen tool home directory
    -v, --version                    Display the version
    -h, --help                       Display this message
HELP
      end

      it "ヘルプを表示し、そのまま終了する" do
        expect {
          generator.run(['-h'])
        }.to raise_error(SystemExit).and output(help).to_stdout
        expect {
          generator.run(['--help'])
        }.to raise_error(SystemExit).and output(help).to_stdout
      end
    end

    describe "ジェネレータのセットアップ" do
      before do
        allow(File).to receive(:binwrite)
      end

      context "--setupでセットアップファイルの指定が無い場合" do
        before do
          expect(RgGen.builder).to receive(:enable).with(:global, [:data_width, :address_width]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:register_block, [:name, :byte_size]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:register, [:offset_address, :name, :array, :type, :uniquness_validator]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:register, :type, [:indirect, :external]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:bit_field, [:bit_assignment, :name, :type, :initial_value, :reference]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:bit_field, :type, [:rw, :ro, :w0c, :w1c, :w0s, :w1s, :rwl, :rwe, :reserved]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:register_block, [:top_module, :clock_reset, :host_if, :response_mux, :irq_controller]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:register_block, :host_if, [:apb, :axi4lite]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:register, [:address_decoder, :read_data, :bus_exporter]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:register_block, [:ral_package, :block_model, :constructor, :sub_model_creator, :default_map_creator]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:register, [:reg_model, :constructor, :field_model_creator, :indirect_index_configurator, :sub_block_model]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:bit_field, :field_model).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:register_block, [:c_header_file, :address_struct]).and_call_original
        end

        it "デフォルトのセットアップが実行される" do
          expect {
            generator.run([sample_register_maps[0]])
          }.not_to raise_error
        end
      end

      context "--setupでセットアップファイルの指定がある場合" do
        before do
          expect(RgGen.builder).to receive(:define_list_item).with(:bit_field, :type, :foo).and_call_original
          expect(RgGen.builder).to receive(:define_list_item).with(:register_block, :host_if, :bar).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:global, [:data_width, :address_width]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:register_block, [:name, :base_address]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:register, [:offset_address, :name, :array, :type, :uniquness_validator]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:register, :type, [:indirect, :external]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:bit_field, [:bit_assignment, :name, :type, :initial_value, :reference]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:bit_field, :type, [:rw, :ro, :w0c, :w1c, :w0s, :w1s, :rwl, :rwe, :foo, :reserved]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:register_block, [:top_module, :clock_reset, :host_if, :response_mux, :irq_controller]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:register_block, :host_if, [:apb, :bar]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:register, [:address_decoder, :read_data, :bus_exporter]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:register_block, [:ral_package, :block_model, :constructor, :sub_model_creator, :default_map_creator]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:register, [:reg_model, :constructor, :field_model_creator, :indirect_index_configurator, :sub_block_model]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:bit_field, :field_model).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:register_block, [:c_header_file, :address_struct]).and_call_original
        end

        after do
          clear_dummy_list_items(:type   , [:foo])
          clear_dummy_list_items(:host_if, [:bar])
        end

        it "--setupで指定したファイルからセットアップが実行される" do
          expect {<commit_msg>#20 の前準備で spec を整理<commit_after>require_relative '../spec_helper'

module RgGen
  describe Generator do
    before(:all) do
      @expected_rtl_code  = 2.times.map do |i|
        File.read("#{RGGEN_HOME}/sample/sample_#{i}.sv")
      end
      @expected_ral_code  = 2.times.map do |i|
        File.read("#{RGGEN_HOME}/sample/sample_#{i}_ral_pkg.sv")
      end
      @expected_c_header_code = 2.times.map do |i|
        File.read("#{RGGEN_HOME}/sample/sample_#{i}.h")
      end
    end

    before do
      cache   = factory_cache
      plugin  = factory_plugin
      allow(RgGen.builder).to receive(:build_factory).and_wrap_original do |m, component_name|
        f     = m.call(component_name)
        mock  = allow(f)
        if plugin.key?(component_name)
          mock.to receive(:create).and_wrap_original(&plugin[component_name])
        else
          mock.to receive(:create).and_call_original
        end
        cache[component_name] << f
        f
      end
    end

    after do
      clear_enabled_items
    end

    let(:generator) do
      Generator.new
    end

    let(:factory_cache) do
      Hash.new do |hash, component_name|
        hash[component_name]  = []
      end
    end

    let(:factory_plugin) do
      {}
    end

    let(:default_setup) do
      "#{RGGEN_HOME}/setup/default.rb"
    end

    let(:sample_setup) do
      "#{RGGEN_HOME}/sample/sample_setup.rb"
    end

    let(:sample_yaml) do
      "#{RGGEN_HOME}/sample/sample.yaml"
    end

    let(:sample_json) do
      "#{RGGEN_HOME}/sample/sample.json"
    end

    let(:sample_register_maps) do
      ["#{RGGEN_HOME}/sample/sample.xls", "#{RGGEN_HOME}/sample/sample.xlsx", "#{RGGEN_HOME}/sample/sample.csv"]
    end

    describe "RgGenホームディレクトリの表示" do
      let(:home) do
        "#{RgGen::RGGEN_HOME}\n"
      end

      it "RgGenのホームディレクトリを表示し、そのまま終了する" do
        expect {
          generator.run(['--show-home'])
        }.to raise_error(SystemExit).and output(home).to_stdout
      end
    end

    describe "バージョンの出力" do
      let(:version) do
        "rggen #{RgGen::VERSION}\n"
      end

      it "バージョンを出力し、そのまま終了する" do
        expect {
          generator.run(['-v'])
        }.to raise_error(SystemExit).and output(version).to_stdout
        expect {
          generator.run(['--version'])
        }.to raise_error(SystemExit).and output(version).to_stdout
      end
    end

    describe "ヘルプの表示" do
      let(:help) do
        <<HELP
Usage: rggen [options] REGISTER_MAP
        --setup FILE                 Specify a setup file to set up RgGen tool(default: #{default_setup})
    -c, --configuration FILE         Specify a configuration file for generated source code
    -o, --output DIR                 Specify output directory(default: .)
        --except [TYPE1,TYPE2,...]   Disable the given output file type(s)
        --show-home                  Display the path of RgGen tool home directory
    -v, --version                    Display the version
    -h, --help                       Display this message
HELP
      end

      it "ヘルプを表示し、そのまま終了する" do
        expect {
          generator.run(['-h'])
        }.to raise_error(SystemExit).and output(help).to_stdout
        expect {
          generator.run(['--help'])
        }.to raise_error(SystemExit).and output(help).to_stdout
      end
    end

    describe "ジェネレータのセットアップ" do
      before do
        allow(File).to receive(:binwrite)
      end

      context "--setupでセットアップファイルの指定が無い場合" do
        before do
          allow_any_instance_of(RgGen::Generator).to receive(:load).with(default_setup).and_call_original
        end

        before do
          expect(RgGen.builder).to receive(:enable).with(:global, [:data_width, :address_width]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:register_block, [:name, :byte_size]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:register, [:offset_address, :name, :array, :type, :uniquness_validator]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:register, :type, [:indirect, :external]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:bit_field, [:bit_assignment, :name, :type, :initial_value, :reference]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:bit_field, :type, [:rw, :ro, :w0c, :w1c, :w0s, :w1s, :rwl, :rwe, :reserved]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:register_block, [:top_module, :clock_reset, :host_if, :response_mux, :irq_controller]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:register_block, :host_if, [:apb, :axi4lite]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:register, [:address_decoder, :read_data, :bus_exporter]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:register_block, [:ral_package, :block_model, :constructor, :sub_model_creator, :default_map_creator]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:register, [:reg_model, :constructor, :field_model_creator, :indirect_index_configurator, :sub_block_model]).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:bit_field, :field_model).and_call_original
          expect(RgGen.builder).to receive(:enable).with(:register_block, [:c_header_file, :address_struct]).and_call_original
        end

        it "デフォルトのセットアップが実行される" do
          expect {
            generator.run([sample_register_maps[0]])
          }.not_to raise_error
        end
      end

      context "--setupでセットアップファイルの指定がある場合" do
        before do
          allow_any_instance_of(RgGen::Generator).to receive(:load).with(sample_setup).and_call_original
        end

        after do
          clear_dummy_list_items(:type   , [:foo])
          clear_dummy_list_items(:host_if, [:bar])
        end

        it "--setupで指定したファイルからセットアップが実行される" do
          expect {
{'fraction_non_alphanumeric': 0.1290110372048827, 'fraction_numerical': 0.0020466340179811416, 'mean_word_length': 2.930479747199081, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6317244', 'n_tokens_mistral': 4605, 'n_tokens_neox': 4555, 'n_words': 768}