Class: Tryouts::TestResultAggregator

Inherits:
Object
  • Object
show all
Defined in:
lib/tryouts/test_result_aggregator.rb

Overview

Centralized test result aggregation to ensure counting consistency across all formatters and eliminate counting discrepancies

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeTestResultAggregator

Returns a new instance of TestResultAggregator.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/tryouts/test_result_aggregator.rb', line 12

def initialize
  @failure_collector       = FailureCollector.new
  # Use thread-safe atomic counters
  @test_counts             = {
    total_tests: Concurrent::AtomicFixnum.new(0),
    passed: Concurrent::AtomicFixnum.new(0),
    failed: Concurrent::AtomicFixnum.new(0),
    errors: Concurrent::AtomicFixnum.new(0),
  }
  @infrastructure_failures = Concurrent::Array.new
  @file_counts             = {
    total: Concurrent::AtomicFixnum.new(0),
    successful: Concurrent::AtomicFixnum.new(0),
  }
end

Instance Attribute Details

#failure_collectorObject (readonly)

Returns the value of attribute failure_collector.



28
29
30
# File 'lib/tryouts/test_result_aggregator.rb', line 28

def failure_collector
  @failure_collector
end

Instance Method Details

#add_infrastructure_failure(type, file_path, error_message, exception = nil) ⇒ Object

Add an infrastructure-level failure (setup, teardown, file-level)



46
47
48
49
50
51
52
53
# File 'lib/tryouts/test_result_aggregator.rb', line 46

def add_infrastructure_failure(type, file_path, error_message, exception = nil)
  @infrastructure_failures << {
    type: type,           # :setup, :teardown, :file_processing
    file_path: file_path,
    error_message: error_message,
    exception: exception,
  }
end

#add_test_result(file_path, result_packet) ⇒ Object

Add a test-level result (from individual test execution)



31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/tryouts/test_result_aggregator.rb', line 31

def add_test_result(file_path, result_packet)
  @test_counts[:total_tests].increment

  if result_packet.passed?
    @test_counts[:passed].increment
  elsif result_packet.failed?
    @test_counts[:failed].increment
    @failure_collector.add_failure(file_path, result_packet)
  elsif result_packet.error?
    @test_counts[:errors].increment
    @failure_collector.add_failure(file_path, result_packet)
  end
end

#any_display_failures?Boolean

Check if there are displayable failures (for numbered lists)

Returns:

  • (Boolean)


114
115
116
# File 'lib/tryouts/test_result_aggregator.rb', line 114

def any_display_failures?
  @failure_collector.any_failures?
end

#any_failures?Boolean

Check if there are any failures at all

Returns:

  • (Boolean)


109
110
111
# File 'lib/tryouts/test_result_aggregator.rb', line 109

def any_failures?
  @failure_collector.any_failures? || !@infrastructure_failures.empty?
end

#clearObject

Reset for testing purposes



119
120
121
122
123
124
125
126
127
128
# File 'lib/tryouts/test_result_aggregator.rb', line 119

def clear
  @failure_collector.clear
  @test_counts[:total_tests].update { |_| 0 }
  @test_counts[:passed].update { |_| 0 }
  @test_counts[:failed].update { |_| 0 }
  @test_counts[:errors].update { |_| 0 }
  @infrastructure_failures.clear
  @file_counts[:total].update { |_| 0 }
  @file_counts[:successful].update { |_| 0 }
end

#get_display_countsObject

Get counts that should be displayed in numbered failure lists These match what actually appears in the failure summary



71
72
73
74
75
76
77
78
79
# File 'lib/tryouts/test_result_aggregator.rb', line 71

def get_display_counts
  {
    total_tests: @test_counts[:total_tests].value,
    passed: @test_counts[:passed].value,
    failed: @failure_collector.failure_count,
    errors: @failure_collector.error_count,
    total_issues: @failure_collector.total_issues,
  }
end

#get_file_countsObject

Get file-level statistics



96
97
98
99
100
101
# File 'lib/tryouts/test_result_aggregator.rb', line 96

def get_file_counts
  {
    total: @file_counts[:total].value,
    successful: @file_counts[:successful].value,
  }
end

#get_infrastructure_failuresObject

Get infrastructure failures for detailed reporting



104
105
106
# File 'lib/tryouts/test_result_aggregator.rb', line 104

def get_infrastructure_failures
  @infrastructure_failures.dup
end

#get_total_countsObject

Get total counts including infrastructure failures These represent all issues that occurred during test execution



83
84
85
86
87
88
89
90
91
92
93
# File 'lib/tryouts/test_result_aggregator.rb', line 83

def get_total_counts
  display = get_display_counts
  {
    total_tests: display[:total_tests],
    passed: display[:passed],
    failed: display[:failed],
    errors: display[:errors],
    infrastructure_failures: @infrastructure_failures.size,
    total_issues: display[:total_issues] + @infrastructure_failures.size,
  }
end

#increment_successful_filesObject



60
61
62
# File 'lib/tryouts/test_result_aggregator.rb', line 60

def increment_successful_files
  @file_counts[:successful].increment
end

#increment_total_filesObject

Atomic increment methods for file-level operations



56
57
58
# File 'lib/tryouts/test_result_aggregator.rb', line 56

def increment_total_files
  @file_counts[:total].increment
end

#infrastructure_failure_countObject

Get count of infrastructure failures



65
66
67
# File 'lib/tryouts/test_result_aggregator.rb', line 65

def infrastructure_failure_count
  @infrastructure_failures.size
end

#summaryObject

Provide a summary string for debugging



131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/tryouts/test_result_aggregator.rb', line 131

def summary
  display = get_display_counts
  total   = get_total_counts

  parts = []
  parts << "#{display[:passed]} passed" if display[:passed] > 0
  parts << "#{display[:failed]} failed" if display[:failed] > 0
  parts << "#{display[:errors]} errors" if display[:errors] > 0
  parts << "#{total[:infrastructure_failures]} infrastructure failures" if total[:infrastructure_failures] > 0

  parts.empty? ? 'All tests passed' : parts.join(', ')
end