Coverage for manyworlds/data_table.py: 100%

29 statements  

« prev     ^ index     » next       coverage.py v7.3.0, created at 2023-08-25 16:44 +0200

1"""Defines the DataTable and DataTableRow classes""" 

2 

3import re 

4from typing import Optional, List 

5 

6 

7class DataTableRow: 

8 """A Gherkin data table row""" 

9 

10 values: List[str] 

11 comment: Optional[str] 

12 

13 def __init__(self, values: List[str], comment: Optional[str] = None): 

14 """Constructor method 

15 

16 Parameters 

17 ---------- 

18 values : List[str] 

19 The header row 

20 

21 comment : str 

22 Comment (optional) 

23 """ 

24 

25 self.values = values 

26 self.comment = comment 

27 

28 

29class DataTable: 

30 """A Gherkin data table""" 

31 

32 TABLE_ROW_PATTERN = re.compile( 

33 "(?P<table_row>\| ([^|]* +\|)+)( # (?P<comment>.+))?" 

34 ) 

35 """Pipe-delimited list of values, followed by an optional comment""" 

36 

37 header_row: DataTableRow 

38 rows: List[DataTableRow] 

39 

40 def __init__(self, header_row: DataTableRow) -> None: 

41 """Constructor method 

42 

43 Parameters 

44 ---------- 

45 header_row : DataTableRow 

46 The header row 

47 """ 

48 

49 self.header_row = header_row 

50 self.rows = [] 

51 

52 def to_list_of_list(self) -> List[List[str]]: 

53 """Returns a list of list of str representation of itself 

54 

55 First row is header row 

56 

57 Returns 

58 ------- 

59 List[List[str]] 

60 The list of list of str representation of itself 

61 """ 

62 

63 return [self.header_row.values] + [row.values for row in self.rows] 

64 

65 def to_list_of_dict(self) -> List[dict]: 

66 """Returns a list of dict representation of itself 

67 

68 Returns 

69 ------- 

70 List[dict] 

71 The list of dict representation of itself 

72 """ 

73 

74 return [dict(zip(self.header_row.values, row.values)) for row in self.rows] 

75 

76 def to_list(self) -> List[DataTableRow]: 

77 """Returns a list of DataTableRow representation of itself 

78 

79 Returns 

80 ------- 

81 List[DataTableRow] 

82 The list of DataTableRow representation of itself 

83 """ 

84 

85 return [self.header_row] + self.rows 

86 

87 @classmethod 

88 def parse_line(cls, line: str) -> Optional[DataTableRow]: 

89 """Parses a pipe delimited data table line into a DataTableRow 

90 

91 Parameters 

92 ---------- 

93 line : str 

94 A pipe delimited data table line 

95 

96 Returns 

97 ------- 

98 DataTableRow 

99 """ 

100 

101 match: Optional[re.Match] = DataTable.TABLE_ROW_PATTERN.match(line) 

102 

103 if match: 

104 values = [s.strip() for s in match.group("table_row").split("|")[1:-1]] 

105 comment = match.group("comment") 

106 return DataTableRow(values, comment) 

107 else: 

108 return None