• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

chkware / cli / 5418472590

pending completion
5418472590

push

github

web-flow
Merge pull request #229 from 0hsn/feat/mod-validation

feat: mod validation

173 of 173 new or added lines in 6 files covered. (100.0%)

1471 of 1759 relevant lines covered (83.63%)

0.84 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

77.63
/chk/modules/validate/assertion_services.py
1
"""
2
Assertion services
3
"""
4
import typing
1✔
5
import uuid
1✔
6
from collections import UserDict
1✔
7
from datetime import datetime
1✔
8

9
import chk.modules.validate.assertion_function as asrt_f
1✔
10
from chk.infrastructure.symbol_table import linear_replace
1✔
11

12
MAP_TYPE_TO_FN = {
1✔
13
    "AssertEquals": asrt_f.assert_equals,
14
}
15

16

17
class AssertionEntry(typing.NamedTuple):
1✔
18
    """AssertionEntry holds one assertion operation"""
19

20
    assert_type: str
1✔
21
    type_of_actual: str
1✔
22
    actual: typing.Any
1✔
23
    actual_given: typing.Any
1✔
24
    type_of_expected: str
1✔
25
    expected: typing.Any
1✔
26
    msg_pass: str
1✔
27
    msg_fail: str
1✔
28
    assert_id: str = ""
1✔
29

30

31
class SingleTestRunResult(UserDict):
1✔
32
    """Result of an assertion run"""
33

34
    __slots__ = (
1✔
35
        "is_pass",
36
        "time_start",
37
        "time_end",
38
        "message",
39
    )
40

41
    is_pass: bool
1✔
42
    message: str
1✔
43
    assert_used: AssertionEntry
1✔
44

45
    @property
1✔
46
    def as_dict(self) -> dict:
1✔
47
        """Convert SingleTestRunResult to a dict"""
48

49
        _as_dict: dict = {
×
50
            key: value for key, value in self.items() if not key.startswith("time_")
51
        }
52

53
        _as_dict |= {
×
54
            key: value.timestamp()
55
            for key, value in self.items()
56
            if key.startswith("time_")
57
        }
58

59
        _as_dict["assert_used"] = self["assert_used"]._asdict()
×
60

61
        return _as_dict
×
62

63
    @property
1✔
64
    def as_fmt_str(self) -> str:
1✔
65
        """String representation of ApiResponse
66

67
        Returns:
68
            str: String representation
69
        """
70

71
        return (
×
72
            "\n"
73
            f"{'+' if self['is_pass'] else '-'} {self['assert_used'].assert_type} "
74
            + f"{'PASSED' if self['is_pass'] else 'FAILED'} with message: {self['message']}"
75
        )
76

77

78
class AllTestRunResult(UserDict):
1✔
79
    """Result of a test run"""
80

81
    __slots__ = (
1✔
82
        "id",
83
        "time_start",
84
        "time_end",
85
        "count_all",
86
        "results",
87
        "count_fail",
88
    )
89

90
    id: str
1✔
91
    time_start: datetime
1✔
92
    time_end: datetime
1✔
93
    count_all: int
1✔
94
    results: list[SingleTestRunResult]
1✔
95
    count_fail: int
1✔
96

97
    @property
1✔
98
    def is_all_pass(self) -> bool:
1✔
99
        """Have all assertion passed for this test run"""
100

101
        return self.count_fail == 0
×
102

103
    @property
1✔
104
    def as_dict(self) -> dict:
1✔
105
        """Convert AllTestRunResult to a dict"""
106
        _as_dict: dict = {
×
107
            key: value for key, value in self.items() if not key.startswith("time_")
108
        }
109

110
        _as_dict |= {
×
111
            key: value.timestamp()
112
            for key, value in self.items()
113
            if key.startswith("time_")
114
        }
115

116
        if len(self["results"]) > 0:
×
117
            _as_dict["results"] = [
×
118
                test_result.as_dict
119
                for test_result in self["results"]
120
                if isinstance(test_result, SingleTestRunResult)
121
            ]
122

123
        return _as_dict
×
124

125
    @property
1✔
126
    def as_fmt_str(self) -> str:
1✔
127
        """String representation of ApiResponse
128

129
        Returns:
130
            str: String representation
131
        """
132

133
        _display = (
×
134
            f"Test run id: {self['id']}, time taken {self['time_end'] - self['time_start']}\n"
135
            + f"Total tests: {self['count_all']}, "
136
            + f"Total tests failed: {self['count_fail']}\n"
137
        )
138
        _display += "\n> Test run result(s):"
×
139

140
        for one_result in self["results"]:
×
141
            _display += one_result.as_fmt_str
×
142

143
        return _display
×
144

145

146
class AssertionEntryListRunner:
1✔
147
    """AssertionAntiquary is service class that run assertion"""
148

149
    @staticmethod
1✔
150
    def test_run(
1✔
151
        assert_list: list[AssertionEntry], variables: dict
152
    ) -> AllTestRunResult:
153
        """Run the tests
154

155
        Args:
156
            assert_list: list[AssertionEntry]
157
            variables: dict
158

159
        Returns:
160
            AllTestRunResult: Test run result
161
        """
162

163
        test_run_result = AllTestRunResult(
1✔
164
            id=str(uuid.uuid4()),
165
            time_start=datetime.now(),
166
            count_all=len(assert_list),
167
            count_fail=0,
168
        )
169

170
        results: list[SingleTestRunResult] = []
1✔
171

172
        for assert_item in assert_list:
1✔
173
            asrt_fn = MAP_TYPE_TO_FN[assert_item.assert_type]
1✔
174

175
            resp = SingleTestRunResult()
1✔
176

177
            if (
1✔
178
                isinstance(assert_item.actual, str)
179
                and "{{" in assert_item.actual
180
                and "}}" in assert_item.actual
181
            ):
182
                assert_item = assert_item._replace(
1✔
183
                    actual=linear_replace(assert_item.actual_given, variables)
184
                )
185

186
            is_pass, asrt_resp = asrt_fn(**assert_item._asdict())
1✔
187

188
            if isinstance(asrt_resp, Exception):
1✔
189
                test_run_result["count_fail"] += 1
×
190

191
            resp["is_pass"] = is_pass
1✔
192
            resp["message"] = str(asrt_resp)
1✔
193
            resp["assert_used"] = assert_item
1✔
194

195
            results.append(resp)
1✔
196

197
        test_run_result["time_end"] = datetime.now()
1✔
198
        test_run_result["results"] = results
1✔
199

200
        return test_run_result
1✔
201

202

203
# @TODO:
204
# - add more use-case oriented named such as laravel validation
205
# - adjust existing asserts name; aligned name with new validator func
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc