1+ from __future__ import annotations
2+
13import os
24import subprocess
35import tempfile
6+ from typing import Sequence
47from xml .etree import ElementTree
58
69import pytest
710
811from pytest_cpp .error import CppTestFailure
12+ from pytest_cpp .error import Markup
13+ from pytest_cpp .facade_abc import AbstractFacade
914
1015
11- class Catch2Facade (object ):
16+ class Catch2Facade (AbstractFacade ):
1217 """
1318 Facade for Catch2.
1419 """
1520
1621 @classmethod
17- def is_test_suite (cls , executable ) :
22+ def is_test_suite (cls , executable : str ) -> bool :
1823 try :
1924 output = subprocess .check_output (
2025 [executable , "--help" ],
@@ -26,7 +31,7 @@ def is_test_suite(cls, executable):
2631 else :
2732 return "--list-test-names-only" in output
2833
29- def list_tests (self , executable ) :
34+ def list_tests (self , executable : str ) -> list [ str ] :
3035 """
3136 Executes test with "--list-test-names-only" and gets list of tests
3237 parsing output like this:
@@ -49,10 +54,15 @@ def list_tests(self, executable):
4954
5055 return result
5156
52- def run_test (self , executable , test_id = "" , test_args = (), harness = None ):
53- harness = harness or []
57+ def run_test (
58+ self ,
59+ executable : str ,
60+ test_id : str = "" ,
61+ test_args : Sequence [str ] = (),
62+ harness : Sequence [str ] = (),
63+ ) -> tuple [Sequence [Catch2Failure ] | None , str ]:
5464 xml_filename = self ._get_temp_xml_filename ()
55- args = harness + [
65+ args = list ( harness ) + [
5666 executable ,
5767 test_id ,
5868 "--success" ,
@@ -103,16 +113,20 @@ def run_test(self, executable, test_id="", test_args=(), harness=None):
103113 else :
104114 return None , output
105115
106- msg = "Internal Error: could not find test " " {test_id} in results:\n {results}"
116+ msg = "Internal Error: could not find test {test_id} in results:\n {results}"
107117
108- results_list = "\n " .join ("\n " .join (x ) for (n , x , f ) in results )
109- failure = Catch2Failure (msg .format (test_id = test_id , results = results_list ))
118+ results_list = "\n " .join (n for (n , x , f ) in results )
119+ failure = Catch2Failure (
120+ msg .format (test_id = test_id , results = results_list ), 0 , ""
121+ )
110122 return [failure ], output
111123
112- def _get_temp_xml_filename (self ):
124+ def _get_temp_xml_filename (self ) -> str :
113125 return tempfile .mktemp ()
114126
115- def _parse_xml (self , xml_filename ):
127+ def _parse_xml (
128+ self , xml_filename : str
129+ ) -> Sequence [tuple [str , Sequence [tuple [str , int , str ]], bool ]]:
116130 root = ElementTree .parse (xml_filename )
117131 result = []
118132 for test_suite in root .findall ("Group" ):
@@ -121,14 +135,16 @@ def _parse_xml(self, xml_filename):
121135 test_name = test_case .attrib ["name" ]
122136 test_result = test_case .find ("OverallResult" )
123137 failures = []
124- if test_result .attrib ["success" ] == "false" :
138+ if test_result is not None and test_result .attrib ["success" ] == "false" :
125139 test_checks = test_case .findall ("Expression" )
126140 for check in test_checks :
127141 file_name = check .attrib ["filename" ]
128- line_num = check .attrib ["line" ]
129- if check .attrib ["success" ] == "false" :
130- expected = check .find ("Original" ).text
131- actual = check .find ("Expanded" ).text
142+ line_num = int (check .attrib ["line" ])
143+ if check is not None and check .attrib ["success" ] == "false" :
144+ item = check .find ("Original" )
145+ expected = item .text if item is not None else ""
146+ item = check .find ("Expanded" )
147+ actual = item .text if item is not None else ""
132148 fail_msg = "Expected: {expected}\n Actual: {actual}" .format (
133149 expected = expected , actual = actual
134150 )
@@ -146,14 +162,14 @@ def _parse_xml(self, xml_filename):
146162
147163
148164class Catch2Failure (CppTestFailure ):
149- def __init__ (self , filename , linenum , lines ):
165+ def __init__ (self , filename : str , linenum : int , lines : str ):
150166 self .lines = lines .splitlines ()
151167 self .filename = filename
152- self .linenum = int ( linenum )
168+ self .linenum = linenum
153169
154- def get_lines (self ):
170+ def get_lines (self ) -> list [ tuple [ str , Markup ]] :
155171 m = ("red" , "bold" )
156172 return [(x , m ) for x in self .lines ]
157173
158- def get_file_reference (self ):
174+ def get_file_reference (self ) -> tuple [ str , int ] :
159175 return self .filename , self .linenum
0 commit comments