<commit_before>require 'minitest/reporters'
require 'yaml'

module Minitest
  module Reporters

    # This reporter creates a report providing the average (mean), minimum and
    # maximum times for a test to run. Running this for all your tests will
    # allow you to:
    #
    # 1) Identify the slowest running tests over time as potential candidates
    #    for improvements or refactoring.
    # 2) Identify (and fix) regressions in test run speed caused by changes to
    #    your tests or algorithms in your code.
    # 3) Provide an abundance of statistics to enjoy.
    #
    # This is achieved by creating a (configurable) 'previous runs' statistics
    # file which is parsed at the end of each run to provide a new
    # (configurable) report. These statistics can be reset at any time by using
    # a simple rake task:
    #
    #     rake reset_statistics
    #
    class MeanTimeReporter < Minitest::Reporters::DefaultReporter

      # Reset the statistics file for this reporter. Called via a rake task:
      #
      #     rake reset_statistics
      #
      # @return [Boolean]
      def self.reset_statistics!
        new.reset_statistics!
      end

      # @param options [Hash]
      # @option previous_runs_filename [String] Contains the times for each test
      #   by description. Defaults to '/tmp/minitest_reporters_previous_run'.
      # @option report_filename [String] Contains the parsed results for the
      #   last test run. Defaults to '/tmp/minitest_reporters_report'.
      # @return [Minitest::Reporters::MeanTimeReporter]
      def initialize(options = {})
        super

        @all_suite_times = []
      end

      # Copies the suite times from the
      # {Minitest::Reporters::DefaultReporter#after_suite} method, making them
      # available to this class.
      #
      # @return [Hash<String => Float>]
      def after_suite(suite)
        super

        @all_suite_times = @suite_times
      end

      # Runs the {Minitest::Reporters::DefaultReporter#report} method and then
      # enhances it by storing the results to the 'previous_runs_filename' and
      # outputs the parsed results to both the 'report_filename' and the
      # terminal.
      #
      def report
        super

        create_or_update_previous_runs!

        create_new_report!

        write_to_screen!
      end

      # Resets the 'previous runs' file, essentially removing all previous
      # statistics gathered.
      #
      # @return [void]
      def reset_statistics!
        File.open(previous_runs_filename, 'w+') { |f| f.write('') }
      end

      protected

      attr_accessor :all_suite_times

      private

      # @return [Hash<String => Float>]
      def current_run
        Hash[all_suite_times]
      end

      # @return [Hash] Sets default values for the filenames used by this class,
      #   and the number of tests to output to output to the screen after each
      #   run.
      def defaults
        {
          show_count:             15,
          previous_runs_filename: '/tmp/minitest_reporters_previous_run',
          report_filename:        '/tmp/minitest_reporters_report',
        }
      end

      # Added to the top of the report file and to the screen output.
      #
      # @return [String]
      def report_title
        "\n\e[4mMinitest Reporters: Mean Time Report\e[24m (Samples: #{samples})\n"
      end

      # The report itself. Displays statistics about all runs, ideal for use
      # with the Unix 'head' command. Listed in slowest average descending
      # order.
      #
      # @return [String]
      def report_body
        previous_run.each_with_object([]) do |(description, timings), obj|
          size = Array(timings).size
          sum  = Array(timings).inject { |total, x| total + x }
          avg  = (sum / size).round(9).to_s.ljust(12)
          min  = Array(timings).min.to_s.ljust(12)
          max  = Array(timings).max.to_s.ljust(12)
          run  = Array(timings).last.to_s.ljust(12)

          rating = rate(run, min, max)

          obj << "#{avg_label} #{avg} " \
                 "#{min_label} #{min} " \
                 "#{max_label} #{max} " \
                 "#{run_label(rating)} #{run} " \
                 "#{des_label} #{description}\n"
        end.sort.reverse.join
      end

      # @return [Hash]
      def options
        defaults.merge!(@options)<commit_msg>Round times to 9 places for min, max and last;<commit_after>require 'minitest/reporters'
require 'yaml'

module Minitest
  module Reporters

    # This reporter creates a report providing the average (mean), minimum and
    # maximum times for a test to run. Running this for all your tests will
    # allow you to:
    #
    # 1) Identify the slowest running tests over time as potential candidates
    #    for improvements or refactoring.
    # 2) Identify (and fix) regressions in test run speed caused by changes to
    #    your tests or algorithms in your code.
    # 3) Provide an abundance of statistics to enjoy.
    #
    # This is achieved by creating a (configurable) 'previous runs' statistics
    # file which is parsed at the end of each run to provide a new
    # (configurable) report. These statistics can be reset at any time by using
    # a simple rake task:
    #
    #     rake reset_statistics
    #
    class MeanTimeReporter < Minitest::Reporters::DefaultReporter

      # Reset the statistics file for this reporter. Called via a rake task:
      #
      #     rake reset_statistics
      #
      # @return [Boolean]
      def self.reset_statistics!
        new.reset_statistics!
      end

      # @param options [Hash]
      # @option previous_runs_filename [String] Contains the times for each test
      #   by description. Defaults to '/tmp/minitest_reporters_previous_run'.
      # @option report_filename [String] Contains the parsed results for the
      #   last test run. Defaults to '/tmp/minitest_reporters_report'.
      # @return [Minitest::Reporters::MeanTimeReporter]
      def initialize(options = {})
        super

        @all_suite_times = []
      end

      # Copies the suite times from the
      # {Minitest::Reporters::DefaultReporter#after_suite} method, making them
      # available to this class.
      #
      # @return [Hash<String => Float>]
      def after_suite(suite)
        super

        @all_suite_times = @suite_times
      end

      # Runs the {Minitest::Reporters::DefaultReporter#report} method and then
      # enhances it by storing the results to the 'previous_runs_filename' and
      # outputs the parsed results to both the 'report_filename' and the
      # terminal.
      #
      def report
        super

        create_or_update_previous_runs!

        create_new_report!

        write_to_screen!
      end

      # Resets the 'previous runs' file, essentially removing all previous
      # statistics gathered.
      #
      # @return [void]
      def reset_statistics!
        File.open(previous_runs_filename, 'w+') { |f| f.write('') }
      end

      protected

      attr_accessor :all_suite_times

      private

      # @return [Hash<String => Float>]
      def current_run
        Hash[all_suite_times]
      end

      # @return [Hash] Sets default values for the filenames used by this class,
      #   and the number of tests to output to output to the screen after each
      #   run.
      def defaults
        {
          show_count:             15,
          previous_runs_filename: '/tmp/minitest_reporters_previous_run',
          report_filename:        '/tmp/minitest_reporters_report',
        }
      end

      # Added to the top of the report file and to the screen output.
      #
      # @return [String]
      def report_title
        "\n\e[4mMinitest Reporters: Mean Time Report\e[24m (Samples: #{samples})\n"
      end

      # The report itself. Displays statistics about all runs, ideal for use
      # with the Unix 'head' command. Listed in slowest average descending
      # order.
      #
      # @return [String]
      def report_body
        previous_run.each_with_object([]) do |(description, timings), obj|
          size = Array(timings).size
          sum  = Array(timings).inject { |total, x| total + x }
          avg  = (sum / size).round(9).to_s.ljust(12)
          min  = Array(timings).min.round(9).to_s.ljust(12)
          max  = Array(timings).max.round(9).to_s.ljust(12)
          run  = Array(timings).last.round(9).to_s.ljust(12)

          rating = rate(run, min, max)

          obj << "#{avg_label} #{avg} " \
                 "#{min_label} #{min} " \
                 "#{max_label} #{max} " \
                 "#{run_label(rating)} #{run} " \
                 "#{des_label} #{description}\n"
        end.sort.reverse.join
      end

      # @return [Hash]
      def options
        defaults.merge!(@options)
{'fraction_non_alphanumeric': 0.08705003395970115, 'fraction_numerical': 0.004301562146253113, 'mean_word_length': 2.2232761765778912, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 11, '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': '360327', 'n_tokens_mistral': 2625, 'n_tokens_neox': 2529, 'n_words': 812}