Class: Tryouts::ExpectationEvaluators::Output

Inherits:
Base
  • Object
show all
Defined in:
lib/tryouts/expectation_evaluators/output.rb

Overview

Evaluator for output expectations using syntax: #=1> content, #=2> content

PURPOSE:

  • Validates that stdout (pipe 1) or stderr (pipe 2) contains expected content
  • Provides ability to test console output, error messages, and logging
  • Supports both string contains and regex pattern matching

SYNTAX:

  • #=1> expression - Test stdout content
  • #=2> expression - Test stderr content

Examples:

puts "Hello World"           #=1> "Hello"            # String contains check
puts "Hello World"           #=1> /Hello.*World/     # Regex pattern match
$stderr.puts "Error!"        #=2> "Error"            # Stderr contains check
$stderr.puts "Warning: 404"  #=2> /Warning.*\d+/     # Stderr regex match

MATCHING BEHAVIOR:

  • String expectations: Uses String#include? for substring matching
  • Regex expectations: Uses =~ operator for pattern matching
  • Auto-detects expectation type based on content (literal string vs regex)
  • Case-sensitive matching for both strings and regex patterns

IMPLEMENTATION DETAILS:

  • Requires output capture during test execution
  • Expression has access to result and _ variables (actual_result)
  • Expected display shows the evaluated expression result
  • Actual display shows captured output content for the specific pipe
  • Supports evaluation of dynamic expressions in expectation content

DESIGN DECISIONS:

  • Uses POSIX pipe convention: 1=stdout, 2=stderr
  • Always captures output for debugging regardless of expectations
  • Supports both literal strings and regex patterns seamlessly
  • Part of unified #= prefix convention for all expectation types
  • Uses #=N> syntax where N is the pipe number (following shell convention)

PIPE MAPPING:

  • Pipe 1: Standard output (stdout) - $stdout, puts, print, p
  • Pipe 2: Standard error (stderr) - $stderr, warn, STDERR.puts
  • Future pipes (3+) could support custom streams if needed

Instance Attribute Summary

Attributes inherited from Base

#context, #expectation, #test_case

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#initialize

Constructor Details

This class inherits a constructor from Tryouts::ExpectationEvaluators::Base

Class Method Details

.handles?(expectation_type) ⇒ Boolean

Returns:



51
52
53
# File 'lib/tryouts/expectation_evaluators/output.rb', line 51

def self.handles?(expectation_type)
  expectation_type == :output
end

Instance Method Details

#evaluate(actual_result = nil, stdout_content = nil, stderr_content = nil) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/tryouts/expectation_evaluators/output.rb', line 55

def evaluate(actual_result = nil, stdout_content = nil, stderr_content = nil)
  # Determine which pipe we're testing based on expectation metadata
  pipe_number = @expectation.respond_to?(:pipe) ? @expectation.pipe : 1

  # Get the appropriate captured content
  captured_content = case pipe_number
                    when 1 then stdout_content || ''
                    when 2 then stderr_content || ''
                    else ''
                    end

  # Create result packet for expression evaluation
  expectation_result = ExpectationResult.from_execution_with_output(actual_result, stdout_content, stderr_content)

  # Evaluate the expectation expression (could be string literal or regex)
  expected_pattern = eval_expectation_content(@expectation.content, expectation_result)

  # Determine matching strategy based on expectation type
  matched = case expected_pattern
            when Regexp
              # Regex pattern matching
              !!(captured_content =~ expected_pattern)
            when String
              # String contains matching
              captured_content.include?(expected_pattern)
            else
              # Convert to string and do contains check
              captured_content.include?(expected_pattern.to_s)
            end

  # Build result with appropriate pipe description
  pipe_name = case pipe_number
             when 1 then 'stdout'
             when 2 then 'stderr'
             else "pipe#{pipe_number}"
             end

  build_result(
    passed: matched,
    actual: "#{pipe_name}: #{captured_content.inspect}",
    expected: expected_pattern.inspect,
    expectation: @expectation.content,
  )
rescue StandardError => ex
  handle_evaluation_error(ex, actual_result)
end