xref: /aosp_15_r20/external/bazelbuild-rules_testing/lib/private/str_subject.bzl (revision d605057434dcabba796c020773aab68d9790ff9f)
1# Copyright 2023 The Bazel Authors. All rights reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""# StrSubject"""
16
17load(
18    ":check_util.bzl",
19    "check_not_equals",
20    "common_subject_is_in",
21)
22load(":collection_subject.bzl", "CollectionSubject")
23
24def _str_subject_new(actual, meta):
25    """Creates a subject for asserting strings.
26
27    Method: StrSubject.new
28
29    Args:
30        actual: ([`str`]) the string to check against.
31        meta: ([`ExpectMeta`]) of call chain information.
32
33    Returns:
34        [`StrSubject`] object.
35    """
36    self = struct(actual = actual, meta = meta)
37    public = struct(
38        # keep sorted start
39        contains = lambda *a, **k: _str_subject_contains(self, *a, **k),
40        equals = lambda *a, **k: _str_subject_equals(self, *a, **k),
41        is_in = lambda *a, **k: common_subject_is_in(self, *a, **k),
42        not_equals = lambda *a, **k: _str_subject_not_equals(self, *a, **k),
43        split = lambda *a, **k: _str_subject_split(self, *a, **k),
44        # keep sorted end
45    )
46    return public
47
48def _str_subject_contains(self, substr):
49    """Assert that the subject contains the substring `substr`.
50
51    Method: StrSubject.contains
52
53    Args:
54        self: implicitly added.
55        substr: ([`str`]) the substring to check for.
56    """
57    if substr in self.actual:
58        return
59    self.meta.add_failure(
60        "expected to contain: {}".format(substr),
61        "actual: {}".format(self.actual),
62    )
63
64def _str_subject_equals(self, other):
65    """Assert that the subject string equals the other string.
66
67    Method: StrSubject.equals
68
69    Args:
70        self: implicitly added.
71        other: ([`str`]) the expected value it should equal.
72    """
73    if self.actual == other:
74        return
75    self.meta.add_failure(
76        "expected: {}".format(other),
77        "actual: {}".format(self.actual),
78    )
79
80def _str_subject_not_equals(self, unexpected):
81    """Assert that the string is not equal to `unexpected`.
82
83    Method: BoolSubject.not_equals
84
85    Args:
86        self: implicitly added.
87        unexpected: ([`str`]) the value actual cannot equal.
88    """
89    return check_not_equals(
90        actual = self.actual,
91        unexpected = unexpected,
92        meta = self.meta,
93    )
94
95def _str_subject_split(self, sep):
96    """Return a `CollectionSubject` for the actual string split by `sep`.
97
98    Method: StrSubject.split
99    """
100    return CollectionSubject.new(
101        self.actual.split(sep),
102        meta = self.meta.derive("split({})".format(repr(sep))),
103        container_name = "split string",
104        sortable = False,
105        element_plural_name = "parts",
106    )
107
108# We use this name so it shows up nice in docs.
109# buildifier: disable=name-conventions
110StrSubject = struct(
111    new = _str_subject_new,
112    contains = _str_subject_contains,
113    equals = _str_subject_equals,
114    not_equals = _str_subject_not_equals,
115    split = _str_subject_split,
116)
117