lib/tryouts.rb
# lib/tryouts.rb require 'stringio' require 'timeout' TRYOUTS_LIB_HOME = __dir__ unless defined?(TRYOUTS_LIB_HOME) require_relative 'tryouts/console' require_relative 'tryouts/test_batch' require_relative 'tryouts/version' require_relative 'tryouts/prism_parser' require_relative 'tryouts/cli' class Tryouts @debug = false @quiet = false @noisy = false @fails = false @container = Class.new @cases = [] # rubocop:disable ThreadSafety/MutableClassInstanceVariable @testcase_io = StringIO.new module ClassMethods attr_accessor :container, :quiet, :noisy, :fails attr_writer :debug attr_reader :cases, :testcase_io def debug? @debug == true end def update_load_path(lib_glob) Dir.glob(lib_glob).each { |dir| $LOAD_PATH.unshift(dir) } end def trace(msg, indent: 0) return unless debug? prefix = (' ' * indent) + Console.color(:dim, 'TRACE') warn "#{prefix} #{msg}" end def debug(msg, indent: 0) return unless debug? prefix = (' ' * indent) + Console.color(:cyan, 'DEBUG') warn "#{prefix} #{msg}" end # Error classification for resilient error handling def classify_error(exception) case exception when SystemExit, SignalException :non_recoverable_exit when Timeout::Error :transient when Errno::ENOENT, Errno::EACCES, Errno::EPERM :file_system when LoadError, NameError, NoMethodError :code_structure when SecurityError, NoMemoryError, SystemStackError :system_resource when SyntaxError, TryoutSyntaxError :syntax when StandardError :recoverable else :unknown end end # Determine if an error should stop batch execution def batch_stopping_error?(exception) classification = classify_error(exception) [:non_recoverable_exit, :system_resource, :syntax].include?(classification) end # Determine if an error should stop individual test execution def test_stopping_error?(exception) classification = classify_error(exception) [:non_recoverable_exit, :system_resource].include?(classification) end end extend ClassMethods end