Class: Tryouts::CLI
- Inherits:
-
Object
- Object
- Tryouts::CLI
- Defined in:
- lib/tryouts/cli.rb,
lib/tryouts/cli/opts.rb,
lib/tryouts/cli/tty_detector.rb,
lib/tryouts/cli/modes/inspect.rb,
lib/tryouts/cli/modes/generate.rb,
lib/tryouts/cli/formatters/base.rb,
lib/tryouts/cli/formatters/agent.rb,
lib/tryouts/cli/formatters/quiet.rb,
lib/tryouts/cli/line_spec_parser.rb,
lib/tryouts/cli/formatters/compact.rb,
lib/tryouts/cli/formatters/factory.rb,
lib/tryouts/cli/formatters/verbose.rb,
lib/tryouts/cli/formatters/token_budget.rb,
lib/tryouts/cli/formatters/output_manager.rb,
lib/tryouts/cli/formatters/test_run_state.rb,
lib/tryouts/cli/formatters/tty_status_display.rb,
lib/tryouts/cli/formatters/live_status_manager.rb
Defined Under Namespace
Modules: FormatterInterface, TTYDetector Classes: AgentFormatter, CompactFailsFormatter, CompactFormatter, FormatterFactory, GenerateMode, InspectMode, LineSpecParser, LiveStatusManager, NoOpStatusDisplay, OutputManager, QuietFailsFormatter, QuietFormatter, TTYStatusDisplay, TestRunState, TokenBudget, VerboseFailsFormatter, VerboseFormatter
Constant Summary collapse
- HELP =
<<~HELP Framework Defaults: Tryouts: Shared context (state persists across tests) RSpec: Fresh context (each test isolated) Minitest: Fresh context (each test isolated) Examples: try test_try.rb # Tryouts test runner with shared context try --rspec test_try.rb # RSpec with fresh context try --direct --shared-context test_try.rb # Explicit shared context try --generate-rspec test_try.rb # Output RSpec code only try --inspect test_try.rb # Inspect file structure and validation try --agent test_try.rb # Agent-optimized structured output try --agent --agent-limit 10000 tests/ # Agent mode with 10K token limit Agent Output Modes: --agent # Structured, token-efficient output --agent-focus summary # Show counts and problem files only --agent-focus first-failure # Show first failure per file --agent-focus critical # Show errors/exceptions only --agent-limit 1000 # Limit output to 1000 tokens --agent-tips # Include framework tips for LLMs --agent-command # Include copy-paste re-run command --agent-no-failures # Suppress failure details (summary only) File Naming & Organization: Files must end with '_try.rb' or '.try.rb' (e.g., auth_service_try.rb, user_model.try.rb) Auto-discovery searches: ./try/, ./tryouts/, ./*_try.rb, ./*.try.rb patterns Organize by feature/module: try/models/, try/services/, try/api/ Testcase Structure (3 required parts) ## This is the description echo 'This is ruby code under test' true #=> true # this is the expected result File Structure (3 sections): # Setup section (optional) - code before first testcase runs once before all tests @shared_var = "available to all test cases" ## TEST: Feature description # Test case body with plain Ruby code result = some_operation() #=> expected_value # Teardown section (optional) - code after last testcase runs once after all tests Execution Context: Shared Context (default): Instance variables persist across test cases - Use for: Integration testing, stateful scenarios, realistic workflows - Caution: Test order matters, state accumulates Fresh Context (--rspec/--minitest): Each test gets isolated environment - Use for: Unit testing, independent test cases - Setup variables copied to each test, but changes don't persist Writing Quality Tryouts: - Use realistic, plain Ruby code (avoid mocks, test harnesses) - Test descriptions start with ##, be specific about what's being tested - One result per test case (last expression is the result) - Use appropriate expectation types for clarity (#==> for boolean, #=:> for types) - Keep tests focused and readable - they serve as documentation Great Expectations System: #=> Value equality #==> Must be true #=/=> Must be false #=|> True OR false #=!> Must raise error #=:> Type matching #=~> Regex matching #=%> Time constraints #=*> Non-nil result #=1> STDOUT content #=2> STDERR content #=<> Intentional failure Exception Testing: ## Method 1: Rescue and test exception begin risky_operation rescue MySpecificError => e e.class end #=> MySpecificError ## Method 2: Let it raise and test with #=!> and #=~> risky_operation #=!> MySpecificError #=~> /Could not complete action/ HELP
Class Method Summary collapse
Instance Method Summary collapse
-
#initialize ⇒ CLI
constructor
A new instance of CLI.
- #run(files, **options) ⇒ Object
Constructor Details
#initialize ⇒ CLI
Returns a new instance of CLI.
12 13 14 15 16 17 18 19 20 |
# File 'lib/tryouts/cli.rb', line 12 def initialize @options = { framework: :direct, verbose: false, inspect: false, strict: true, # Default to strict mode for better UX warnings: true, # Default to showing warnings } end |
Class Method Details
.parse_args(args) ⇒ Object
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/tryouts/cli/opts.rb', line 91 def parse_args(args) Tryouts.trace "Parsing arguments: #{args.inspect}" = {} parser = OptionParser.new do |opts| opts. = "Usage: try [OPTIONS] FILE...\n\nModern Tryouts test runner with framework translation" opts.separator "\nFramework Options:" opts.on('--direct', 'Direct execution with TestBatch (default)') { [:framework] = :direct } opts.on('--rspec', 'Use RSpec framework') { [:framework] = :rspec } opts.on('--minitest', 'Use Minitest framework') { [:framework] = :minitest } opts.separator "\nGeneration Options:" opts.on('--generate-rspec', 'Generate RSpec code only') do [:framework] = :rspec [:generate_only] = true end opts.on('--generate-minitest', 'Generate Minitest code only') do [:framework] = :minitest [:generate_only] = true end opts.on('--generate', 'Generate code only (use with --rspec/--minitest)') do [:generate_only] = true [:framework] ||= :rspec end opts.separator "\nExecution Options:" opts.on('--shared-context', 'Override default context mode') { [:shared_context] = true } opts.on('--no-shared-context', 'Override default context mode') { [:shared_context] = false } opts.on('-v', '--verbose', 'Show detailed test output with line numbers') { [:verbose] = true } opts.on('-f', '--fails', 'Show only failing tests') { [:fails_only] = true } opts.on('-q', '--quiet', 'Minimal output (dots and summary only)') { [:quiet] = true } opts.on('-c', '--compact', 'Compact single-line output') { [:compact] = true } opts.on('-l', '--live', 'Live status display') { [:live_status] = true } opts.on('-j', '--parallel [THREADS]', 'Run test files in parallel (optional thread count)') do |threads| [:parallel] = true [:parallel_threads] = threads.to_i if threads && threads.to_i > 0 end opts.separator "\nParser Options:" opts.on('--strict', 'Require explicit test descriptions (fail on unnamed tests)') { [:strict] = true } opts.on('--no-strict', 'Allow unnamed tests (legacy behavior)') { [:strict] = false } opts.on('-w', '--warnings', 'Show parser warnings (default: true)') { [:warnings] = true } opts.on('--no-warnings', 'Suppress parser warnings') { [:warnings] = false } opts.separator "\nAgent-Optimized Output:" opts.on('-a', '--agent', 'Agent-optimized structured output for LLM context management') do [:agent] = true end opts.on('--agent-limit TOKENS', Integer, 'Limit total output to token budget (default: 5000)') do |limit| [:agent] = true [:agent_limit] = limit end opts.on('--agent-focus TYPE', %w[failures first-failure summary critical], 'Focus mode: failures, first-failure, summary, critical (default: failures)') do |focus| [:agent] = true [:agent_focus] = focus.to_sym end opts.on('--agent-tips', 'Include tryouts framework tips and reminders in agent output') do [:agent] = true [:agent_tips] = true end opts.on('--agent-command', 'Include copy-paste command for re-running failures with -vfs') do [:agent] = true [:agent_command] = true end opts.on('--agent-no-failures', 'Suppress detailed failure list (show summary/command only)') do [:agent] = true [:agent_no_failures] = true end opts.separator "\nParser Options:" opts.on('--enhanced-parser', 'Use enhanced parser with inhouse comment extraction (default)') { [:parser] = :enhanced } opts.on('--legacy-parser', 'Use legacy prism parser') { [:parser] = :prism } opts.separator "\nInspection Options:" opts.on('-i', '--inspect', 'Inspect file structure without running tests') { [:inspect] = true } opts.separator "\nGeneral Options:" opts.on('-s', '--stack-traces', 'Show stack traces for exceptions') do [:stack_traces] = true Tryouts.stack_traces = true end opts.on('-V', '--version', 'Show version') { [:version] = true } opts.on('-D', '--debug', 'Enable debug mode') do [:debug] = true [:stack_traces] = true # Debug mode auto-enables stack traces Tryouts.debug = true Tryouts.stack_traces = true end opts.on('-h', '--help', 'Show this help') do puts opts exit 0 end opts.separator HELP.freeze end files = parser.parse(args) Tryouts.trace "Parsed files: #{files.inspect}, options: #{.inspect}" [files, ] rescue OptionParser::InvalidOption => ex warn "Error: #{ex.}" warn "Try 'try --help' for more information." exit 1 end |
Instance Method Details
#run(files, **options) ⇒ Object
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/tryouts/cli.rb', line 22 def run(files, **) @options.merge!() output_manager = FormatterFactory.create_output_manager(@options) handle_version_flag(@options, output_manager) # Parse line specs from file arguments files_with_specs = parse_file_specs(files) validate_files_exist(files_with_specs, output_manager) runner = TestRunner.new( files: files_with_specs.keys, options: @options.merge(file_line_specs: files_with_specs), output_manager: output_manager, ) runner.run end |