# <!-- rdoc-file=lib/minitest/benchmark.rb -->
# Subclass Benchmark to create your own benchmark runs. Methods starting with
# "bench_" get executed on a per-class.
#
# See Minitest::Assertions
#
class Minitest::Benchmark < ::Minitest::Test
  self.@io: untyped
  def self.io: () -> untyped
  def io: () -> untyped
  def self.run: (untyped reporter, ?::Hash[untyped, untyped] options) -> untyped
  def self.runnable_methods: () -> untyped

  # <!--
  #   rdoc-file=lib/minitest/benchmark.rb
  #   - bench_exp(min, max, base = 10)
  # -->
  # Returns a set of ranges stepped exponentially from `min` to `max` by powers of
  # `base`. Eg:
  #
  #     bench_exp(2, 16, 2) # => [2, 4, 8, 16]
  #
  def self.bench_exp: (untyped min, untyped max, ?::Integer base) -> untyped

  # <!--
  #   rdoc-file=lib/minitest/benchmark.rb
  #   - bench_linear(min, max, step = 10)
  # -->
  # Returns a set of ranges stepped linearly from `min` to `max` by `step`. Eg:
  #
  #     bench_linear(20, 40, 10) # => [20, 30, 40]
  #
  def self.bench_linear: (untyped min, untyped max, ?::Integer step) -> untyped

  # <!--
  #   rdoc-file=lib/minitest/benchmark.rb
  #   - bench_range()
  # -->
  # Specifies the ranges used for benchmarking for that class. Defaults to
  # exponential growth from 1 to 10k by powers of 10. Override if you need
  # different ranges for your benchmarks.
  #
  # See also: ::bench_exp and ::bench_linear.
  #
  def self.bench_range: () -> untyped

  # <!--
  #   rdoc-file=lib/minitest/benchmark.rb
  #   - assert_performance(validation, &work)
  # -->
  # Runs the given `work`, gathering the times of each run. Range and times are
  # then passed to a given `validation` proc. Outputs the benchmark name and times
  # in tab-separated format, making it easy to paste into a spreadsheet for
  # graphing or further analysis.
  #
  # Ranges are specified by ::bench_range.
  #
  # Eg:
  #
  #     def bench_algorithm
  #       validation = proc { |x, y| ... }
  #       assert_performance validation do |n|
  #         @obj.algorithm(n)
  #       end
  #     end
  #
  def assert_performance: (untyped validation) { (?) -> untyped } -> untyped

  # <!--
  #   rdoc-file=lib/minitest/benchmark.rb
  #   - assert_performance_constant(threshold = 0.99, &work)
  # -->
  # Runs the given `work` and asserts that the times gathered fit to match a
  # constant rate (eg, linear slope == 0) within a given `threshold`. Note:
  # because we're testing for a slope of 0, R^2 is not a good determining factor
  # for the fit, so the threshold is applied against the slope itself. As such,
  # you probably want to tighten it from the default.
  #
  # See
  # https://www.graphpad.com/guides/prism/8/curve-fitting/reg_intepretingnonlinr2.
  # htm for more details.
  #
  # Fit is calculated by #fit_linear.
  #
  # Ranges are specified by ::bench_range.
  #
  # Eg:
  #
  #     def bench_algorithm
  #       assert_performance_constant 0.9999 do |n|
  #         @obj.algorithm(n)
  #       end
  #     end
  #
  def assert_performance_constant: (?::Float threshold) { (?) -> untyped } -> untyped

  # <!--
  #   rdoc-file=lib/minitest/benchmark.rb
  #   - assert_performance_exponential(threshold = 0.99, &work)
  # -->
  # Runs the given `work` and asserts that the times gathered fit to match a
  # exponential curve within a given error `threshold`.
  #
  # Fit is calculated by #fit_exponential.
  #
  # Ranges are specified by ::bench_range.
  #
  # Eg:
  #
  #     def bench_algorithm
  #       assert_performance_exponential 0.9999 do |n|
  #         @obj.algorithm(n)
  #       end
  #     end
  #
  def assert_performance_exponential: (?::Float threshold) { (?) -> untyped } -> untyped

  # <!--
  #   rdoc-file=lib/minitest/benchmark.rb
  #   - assert_performance_logarithmic(threshold = 0.99, &work)
  # -->
  # Runs the given `work` and asserts that the times gathered fit to match a
  # logarithmic curve within a given error `threshold`.
  #
  # Fit is calculated by #fit_logarithmic.
  #
  # Ranges are specified by ::bench_range.
  #
  # Eg:
  #
  #     def bench_algorithm
  #       assert_performance_logarithmic 0.9999 do |n|
  #         @obj.algorithm(n)
  #       end
  #     end
  #
  def assert_performance_logarithmic: (?::Float threshold) { (?) -> untyped } -> untyped

  # <!--
  #   rdoc-file=lib/minitest/benchmark.rb
  #   - assert_performance_linear(threshold = 0.99, &work)
  # -->
  # Runs the given `work` and asserts that the times gathered fit to match a
  # straight line within a given error `threshold`.
  #
  # Fit is calculated by #fit_linear.
  #
  # Ranges are specified by ::bench_range.
  #
  # Eg:
  #
  #     def bench_algorithm
  #       assert_performance_linear 0.9999 do |n|
  #         @obj.algorithm(n)
  #       end
  #     end
  #
  def assert_performance_linear: (?::Float threshold) { (?) -> untyped } -> untyped

  # <!--
  #   rdoc-file=lib/minitest/benchmark.rb
  #   - assert_performance_power(threshold = 0.99, &work)
  # -->
  # Runs the given `work` and asserts that the times gathered curve fit to match a
  # power curve within a given error `threshold`.
  #
  # Fit is calculated by #fit_power.
  #
  # Ranges are specified by ::bench_range.
  #
  # Eg:
  #
  #     def bench_algorithm
  #       assert_performance_power 0.9999 do |x|
  #         @obj.algorithm
  #       end
  #     end
  #
  def assert_performance_power: (?::Float threshold) { (?) -> untyped } -> untyped

  # <!--
  #   rdoc-file=lib/minitest/benchmark.rb
  #   - fit_error(xys) { |x| ... }
  # -->
  # Takes an array of x/y pairs and calculates the general R^2 value.
  #
  # See: https://en.wikipedia.org/wiki/Coefficient_of_determination
  #
  def fit_error: (untyped xys) { (untyped) -> untyped } -> untyped

  # <!--
  #   rdoc-file=lib/minitest/benchmark.rb
  #   - fit_exponential(xs, ys)
  # -->
  # To fit a functional form: y = ae^(bx).
  #
  # Takes x and y values and returns [a, b, r^2].
  #
  # See: https://mathworld.wolfram.com/LeastSquaresFittingExponential.html
  #
  def fit_exponential: (untyped xs, untyped ys) -> ::Array[untyped]

  # <!--
  #   rdoc-file=lib/minitest/benchmark.rb
  #   - fit_logarithmic(xs, ys)
  # -->
  # To fit a functional form: y = a + b*ln(x).
  #
  # Takes x and y values and returns [a, b, r^2].
  #
  # See: https://mathworld.wolfram.com/LeastSquaresFittingLogarithmic.html
  #
  def fit_logarithmic: (untyped xs, untyped ys) -> ::Array[untyped]

  # <!--
  #   rdoc-file=lib/minitest/benchmark.rb
  #   - fit_linear(xs, ys)
  # -->
  # Fits the functional form: a + bx.
  #
  # Takes x and y values and returns [a, b, r^2].
  #
  # See: https://mathworld.wolfram.com/LeastSquaresFitting.html
  #
  def fit_linear: (untyped xs, untyped ys) -> ::Array[untyped]

  # <!--
  #   rdoc-file=lib/minitest/benchmark.rb
  #   - fit_power(xs, ys)
  # -->
  # To fit a functional form: y = ax^b.
  #
  # Takes x and y values and returns [a, b, r^2].
  #
  # See: https://mathworld.wolfram.com/LeastSquaresFittingPowerLaw.html
  #
  def fit_power: (untyped xs, untyped ys) -> ::Array[untyped]

  # <!--
  #   rdoc-file=lib/minitest/benchmark.rb
  #   - sigma(enum, &block)
  # -->
  # Enumerates over `enum` mapping `block` if given, returning the sum of the
  # result. Eg:
  #
  #     sigma([1, 2, 3])                # => 1 + 2 + 3 => 6
  #     sigma([1, 2, 3]) { |n| n ** 2 } # => 1 + 4 + 9 => 14
  #
  def sigma: (untyped enum) ?{ (?) -> untyped } -> untyped

  # <!--
  #   rdoc-file=lib/minitest/benchmark.rb
  #   - validation_for_fit(msg, threshold)
  # -->
  # Returns a proc that calls the specified fit method and asserts that the error
  # is within a tolerable threshold.
  #
  def validation_for_fit: (untyped msg, untyped threshold) -> untyped
end
