Class: Ace::Test::EndToEndRunner::Atoms::TestCaseParser

Inherits:
Object
  • Object
show all
Defined in:
lib/ace/test/end_to_end_runner/atoms/test_case_parser.rb

Overview

Parses and normalizes test case IDs from markdown content

Provides pure utility methods for:

  • Extracting TC-NNN headers from markdown test scenarios

  • Normalizing various test case ID formats to TC-NNN

  • Filtering test cases by ID list

Normalization rules (consistent with workflow bash logic):

  • “TC-001” -> “TC-001” (already normalized)

  • “tc-001” -> “TC-001” (uppercased)

  • “001” -> “TC-001” (prefix added)

  • “1” -> “TC-001” (zero-padded and prefixed)

  • “TC-1” -> “TC-001” (zero-padded)

Constant Summary collapse

TC_HEADER_PATTERN =

Pattern matching TC-NNN headers in markdown Matches: ### TC-001: Description

/^###\s+(TC-\d+[a-z]?)[\s:]/i

Class Method Summary collapse

Class Method Details

.extract_from_content(content) ⇒ Array<String>

Extract available test case IDs from markdown content

Scans for ### TC-NNN: headers in the test scenario markdown.

Parameters:

  • content (String)

    Markdown content of a test scenario

Returns:

  • (Array<String>)

    List of test case IDs found (e.g., [“TC-001”, “TC-002”])



79
80
81
# File 'lib/ace/test/end_to_end_runner/atoms/test_case_parser.rb', line 79

def self.extract_from_content(content)
  content.scan(TC_HEADER_PATTERN).map { |match| match[0].upcase }
end

.normalize_identifier(id) ⇒ String

Normalize a single test case identifier to TC-NNN format

Parameters:

  • id (String)

    Raw test case ID in any accepted format

Returns:

  • (String)

    Normalized TC-NNN format

Raises:

  • (ArgumentError)

    If the ID cannot be normalized



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/ace/test/end_to_end_runner/atoms/test_case_parser.rb', line 30

def self.normalize_identifier(id)
  raw = id.to_s.strip
  raise ArgumentError, "Empty test case ID" if raw.empty?

  # Strip TC- prefix if present (case-insensitive)
  number_part = raw.sub(/\Atc-/i, "")

  # Extract numeric portion and optional alpha suffix
  match = number_part.match(/\A(\d+)([a-z]?)\z/i)
  raise ArgumentError, "Invalid test case ID: '#{id}'" unless match

  numeric = match[1]
  suffix = match[2].downcase

  # Zero-pad to 3 digits minimum
  padded = format("%03d", numeric.to_i)

  "TC-#{padded}#{suffix}"
end

.normalize_identifiers(ids) ⇒ Array<String>

Normalize multiple test case identifiers

Parameters:

  • ids (Array<String>)

    Raw test case IDs

Returns:

  • (Array<String>)

    Normalized TC-NNN format IDs



54
55
56
# File 'lib/ace/test/end_to_end_runner/atoms/test_case_parser.rb', line 54

def self.normalize_identifiers(ids)
  ids.map { |id| normalize_identifier(id) }
end

.parse(input) ⇒ Array<String>

Parse a comma-separated string of test case IDs

Parameters:

  • input (String)

    Comma-separated test case IDs (e.g., “tc-001,002,TC-3”)

Returns:

  • (Array<String>)

    Normalized TC-NNN format IDs

Raises:

  • (ArgumentError)

    If input is empty or contains invalid IDs



63
64
65
66
67
68
69
70
71
# File 'lib/ace/test/end_to_end_runner/atoms/test_case_parser.rb', line 63

def self.parse(input)
  raw = input.to_s.strip
  raise ArgumentError, "Empty test cases input" if raw.empty?

  ids = raw.split(",").map(&:strip).reject(&:empty?)
  raise ArgumentError, "No valid test case IDs found in: '#{input}'" if ids.empty?

  normalize_identifiers(ids)
end

.validate_against_available(requested_ids, available_ids) ⇒ Array<String>

Filter test case content by ID list

Given a list of desired test case IDs and the available IDs in content, validates that all requested IDs exist and returns the validated set.

Parameters:

  • requested_ids (Array<String>)

    Normalized test case IDs to filter

  • available_ids (Array<String>)

    Test case IDs available in the scenario

Returns:

  • (Array<String>)

    Validated test case IDs

Raises:

  • (ArgumentError)

    If any requested IDs are not found in the scenario



92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/ace/test/end_to_end_runner/atoms/test_case_parser.rb', line 92

def self.validate_against_available(requested_ids, available_ids)
  normalized_available = available_ids.map(&:upcase)
  missing = requested_ids.reject { |id| normalized_available.include?(id.upcase) }

  unless missing.empty?
    raise ArgumentError,
      "Test case(s) not found: #{missing.join(", ")}. " \
      "Available: #{available_ids.join(", ")}"
  end

  requested_ids
end