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

chkware / cli / 12177747050

05 Dec 2024 10:20AM UTC coverage: 86.879% (-0.2%) from 87.128%
12177747050

push

github

web-flow
Merge pull request #343 from 0hsn/feat/Implement-Jinja3

Feat: Implement jinja2 for variable management

27 of 27 new or added lines in 4 files covered. (100.0%)

6 existing lines in 2 files now uncovered.

1662 of 1913 relevant lines covered (86.88%)

0.87 hits per line

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

78.26
/chk/modules/validate/assertion_services.py
1
"""
2
Assertion services
3
"""
4

5
from collections.abc import Callable
1✔
6
from datetime import datetime
1✔
7

8
import chk.modules.validate.assertion_function as asrt_f
1✔
9
from chk.infrastructure.helper import Cast
1✔
10
from chk.infrastructure.logging import debug
1✔
11
from chk.infrastructure.templating import JinjaTemplate, is_template_str
1✔
12
from chk.modules.validate.assertion_message import get_assert_msg_for
1✔
13
from chk.modules.validate.assertion_validation import AssertionEntityType
1✔
14
from chk.modules.validate.entities import AssertionEntry, RunDetail, RunReport
1✔
15

16
MAP_TYPE_TO_FN: dict[str, Callable] = {
1✔
17
    AssertionEntityType.Accepted: asrt_f.accepted,
18
    AssertionEntityType.Declined: asrt_f.declined,
19
    AssertionEntityType.Equal: asrt_f.equal,
20
    AssertionEntityType.NotEqual: asrt_f.not_equal,
21
    AssertionEntityType.Empty: asrt_f.empty,
22
    AssertionEntityType.NotEmpty: asrt_f.not_empty,
23
    AssertionEntityType.Boolean: asrt_f.boolean,
24
    AssertionEntityType.Integer: asrt_f.integer,
25
    AssertionEntityType.IntegerBetween: asrt_f.integer_between,
26
    AssertionEntityType.IntegerGreater: asrt_f.integer_greater,
27
    AssertionEntityType.IntegerGreaterOrEqual: asrt_f.integer_greater_or_equal,
28
    AssertionEntityType.IntegerLess: asrt_f.integer_less,
29
    AssertionEntityType.IntegerLessOrEqual: asrt_f.integer_less_or_equal,
30
    AssertionEntityType.Float: asrt_f.float_,
31
    AssertionEntityType.FloatBetween: asrt_f.float_between,
32
    AssertionEntityType.FloatGreater: asrt_f.float_greater,
33
    AssertionEntityType.FloatGreaterOrEqual: asrt_f.float_greater_or_equal,
34
    AssertionEntityType.FloatLess: asrt_f.float_less,
35
    AssertionEntityType.FloatLessOrEqual: asrt_f.float_less_or_equal,
36
    AssertionEntityType.Str: asrt_f.str_,
37
    AssertionEntityType.StrHave: asrt_f.str_have,
38
    AssertionEntityType.StrDoNotHave: asrt_f.str_do_not_have,
39
    AssertionEntityType.StrStartsWith: asrt_f.str_starts_with,
40
    AssertionEntityType.StrDoNotStartsWith: asrt_f.str_do_not_starts_with,
41
    AssertionEntityType.StrEndsWith: asrt_f.str_ends_with,
42
    AssertionEntityType.StrDoNotEndsWith: asrt_f.str_do_not_ends_with,
43
    AssertionEntityType.Date: asrt_f.date,
44
    AssertionEntityType.DateAfter: asrt_f.date_after,
45
    AssertionEntityType.DateAfterOrEqual: asrt_f.date_after_or_equal,
46
    AssertionEntityType.DateBefore: asrt_f.date_before,
47
    AssertionEntityType.DateBeforeOrEqual: asrt_f.date_before_or_equal,
48
    AssertionEntityType.List: asrt_f.list_,
49
    AssertionEntityType.ListContains: asrt_f.list_contains,
50
    AssertionEntityType.ListDoNotContains: asrt_f.list_do_not_contains,
51
    AssertionEntityType.ListHasIndex: asrt_f.list_has_index,
52
    AssertionEntityType.ListDoNotHasIndex: asrt_f.list_do_not_has_index,
53
    AssertionEntityType.Map: asrt_f.map_,
54
    AssertionEntityType.MapKeyCount: asrt_f.map_key_count,
55
    AssertionEntityType.MapHasKeys: asrt_f.map_has_keys,
56
    AssertionEntityType.MapDoNotHasKeys: asrt_f.map_do_not_has_keys,
57
    AssertionEntityType.MapExactKeys: asrt_f.map_exact_keys,
58
    AssertionEntityType.Count: asrt_f.count,
59
}
60

61

62
class AssertionEntryListRunner:
1✔
63
    """AssertionAntiquary is service class that run assertion"""
64

65
    @staticmethod
1✔
66
    def _replace_assertion_values(
1✔
67
        assert_item: AssertionEntry, variable_d: dict
68
    ) -> AssertionEntry:
69
        """Replace value for actual and expected data
70

71
        Args:
72
            assert_item: AssertionEntry
73
            variable_d: dict
74
        Returns:
75
            AssertionEntry
76
        """
77

78
        # replace actual value for template
79
        if isinstance(assert_item.actual, str) and is_template_str(assert_item.actual):
1✔
80
            assert_item.actual_given = assert_item.actual
1✔
81
            str_tpl = JinjaTemplate.make(assert_item.actual)
1✔
82
            assert_item.actual = str_tpl.render(variable_d)
1✔
83

84
        # convert actual value type
85
        if assert_item.cast_actual_to != "" and isinstance(assert_item.actual, str):
1✔
UNCOV
86
            assert_item.actual_b4_cast = assert_item.actual
×
87

UNCOV
88
            if assert_item.cast_actual_to == "int_or_float":
×
89
                assert_item.actual = Cast.to_int_or_float(assert_item.actual)
×
UNCOV
90
            elif assert_item.cast_actual_to == "int":
×
UNCOV
91
                assert_item.actual = Cast.to_int(assert_item.actual)
×
92
            elif assert_item.cast_actual_to == "float":
×
93
                assert_item.actual = Cast.to_float(assert_item.actual)
×
94
            elif assert_item.cast_actual_to == "bool":
×
95
                assert_item.actual = Cast.to_bool(assert_item.actual)
×
96
            elif assert_item.cast_actual_to == "none":
×
97
                assert_item.actual = Cast.to_none(assert_item.actual)
×
98
            elif assert_item.cast_actual_to in ["map", "list", "str"]:
×
99
                assert_item.actual = Cast.to_hashable(assert_item.actual)
×
100
            elif assert_item.cast_actual_to == "auto":
×
101
                assert_item.actual = Cast.to_auto(assert_item.actual)
×
102

103
        # replace expected value for template
104
        if isinstance(assert_item.expected, str) and is_template_str(
1✔
105
            assert_item.expected
106
        ):
107
            str_tpl = JinjaTemplate.make(assert_item.expected)
1✔
108
            assert_item.expected = str_tpl.render(variable_d)
1✔
109

110
        return assert_item
1✔
111

112
    @staticmethod
1✔
113
    def _prepare_test_run_result(
1✔
114
        assert_item: AssertionEntry,
115
        asrt_resp: ValueError | bool,
116
    ) -> RunDetail:
117
        def _prepare_message() -> str:
1✔
118
            asrt_fn_name = MAP_TYPE_TO_FN[assert_item.assert_type].__name__
1✔
119

120
            if isinstance(asrt_resp, ValueError):
1✔
121
                return get_assert_msg_for(f"{asrt_fn_name}.{str(asrt_resp)}").format(
1✔
122
                    **detail.get_message_values()
123
                )
124

125
            if asrt_resp:
1✔
126
                message = (
1✔
127
                    get_assert_msg_for(f"{asrt_fn_name}.pass")
128
                    if assert_item.msg_pass == ""
129
                    else assert_item.msg_pass
130
                )
131
            else:
132
                message = (
1✔
133
                    get_assert_msg_for(f"{asrt_fn_name}.fail")
134
                    if assert_item.msg_fail == ""
135
                    else assert_item.msg_fail
136
                )
137

138
            return message.format(**detail.get_message_values())
1✔
139

140
        detail = RunDetail(assert_entry=assert_item)
1✔
141

142
        if isinstance(asrt_resp, ValueError):
1✔
143
            detail.is_pass = False
1✔
144
            detail.message = _prepare_message()
1✔
145
        else:
146
            detail.is_pass = asrt_resp
1✔
147
            detail.message = _prepare_message()
1✔
148

149
        return detail
1✔
150

151
    @staticmethod
1✔
152
    def _call_assertion_method(
1✔
153
        assert_item: AssertionEntry,
154
    ) -> ValueError | bool:
155
        """Call assertion method
156

157
        Args:
158
            assert_item: AssertionEntry
159
        Returns:
160
            ValueError | bool
161
        """
162

163
        asrt_fn = MAP_TYPE_TO_FN[assert_item.assert_type]
1✔
164
        return asrt_fn(**dict(assert_item))
1✔
165

166
    @staticmethod
1✔
167
    def test_run(assert_list: list[AssertionEntry], variables: dict) -> RunReport:
1✔
168
        """Run the tests
169

170
        Args:
171
            assert_list: list[AssertionEntry]
172
            variables: dict
173

174
        Returns:
175
            RunReport: Test run report
176
        """
177

178
        run_report = RunReport(count_all=len(assert_list))
1✔
179

180
        for assert_item in assert_list:
1✔
181
            assert_item = AssertionEntryListRunner._replace_assertion_values(
1✔
182
                assert_item, variables
183
            )
184
            debug(assert_item)
1✔
185

186
            resp: RunDetail = AssertionEntryListRunner._prepare_test_run_result(
1✔
187
                assert_item,
188
                AssertionEntryListRunner._call_assertion_method(assert_item),
189
            )
190
            debug(resp)
1✔
191

192
            run_report.add_run_detail(resp)
1✔
193

194
        run_report.time_end = datetime.now()
1✔
195

196
        return run_report
1✔
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