1# Copyright (C) 2023 The Android Open Source Project
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.
14load("@bazel_skylib//lib:unittest.bzl", "analysistest")
15load(":config_setting_boolean_algebra.bzl", "config_setting_boolean_algebra")
16
17_always_on_config_setting = "//build/bazel/utils:always_on_config_setting"
18_always_off_config_setting = "//build/bazel/utils:always_off_config_setting"
19
20def _fail_with_message_test(ctx):
21    env = analysistest.begin(ctx)
22    if ctx.attr.message:
23        analysistest.fail(env, ctx.attr.message)
24    return analysistest.end(env)
25
26fail_with_message_test = analysistest.make(
27    _fail_with_message_test,
28    attrs = {
29        "message": attr.string(),
30    },
31)
32
33def config_setting_test(*, name, config_setting, expected_value):
34    if type(expected_value) != "bool":
35        fail("Type of expected_value must be a bool")
36    if expected_value:
37        message = select({
38            config_setting: "",
39            "//conditions:default": "Expected %s to be on but was off" % config_setting,
40        })
41    else:
42        message = select({
43            config_setting: "Expected %s to be off but was on" % config_setting,
44            "//conditions:default": "",
45        })
46
47    fail_with_message_test(
48        name = name,
49        # target_under_test is required but unused
50        target_under_test = _always_on_config_setting,
51        message = message,
52    )
53
54def _test_always_on():
55    test_name = "test_always_on"
56    config_setting_test(
57        name = test_name,
58        config_setting = _always_on_config_setting,
59        expected_value = True,
60    )
61    return test_name
62
63def _test_always_off():
64    test_name = "test_always_off"
65    config_setting_test(
66        name = test_name,
67        config_setting = _always_off_config_setting,
68        expected_value = False,
69    )
70    return test_name
71
72def _test_config_setting_boolean_algebra():
73    on = _always_on_config_setting
74    off = _always_off_config_setting
75    tests = [
76        struct(
77            name = "not_on",
78            expected = False,
79            expr = {"NOT": on},
80        ),
81        struct(
82            name = "not_off",
83            expected = True,
84            expr = {"NOT": off},
85        ),
86        struct(
87            name = "and_on_on",
88            expected = True,
89            expr = {"AND": [on, on]},
90        ),
91        struct(
92            name = "and_on_off",
93            expected = False,
94            expr = {"AND": [on, off]},
95        ),
96        struct(
97            name = "and_off_off",
98            expected = False,
99            expr = {"AND": [off, off]},
100        ),
101        struct(
102            name = "and_empty",
103            expected = True,
104            expr = {"AND": []},
105        ),
106        struct(
107            name = "or_on_on",
108            expected = True,
109            expr = {"OR": [on, on]},
110        ),
111        struct(
112            name = "or_on_off",
113            expected = True,
114            expr = {"OR": [on, off]},
115        ),
116        struct(
117            name = "or_off_off",
118            expected = False,
119            expr = {"OR": [off, off]},
120        ),
121        struct(
122            name = "or_empty",
123            expected = False,
124            expr = {"OR": []},
125        ),
126        struct(
127            name = "complicated_1",
128            expected = True,
129            expr = {"AND": [
130                on,
131                {"NOT": off},
132                {"OR": [on, on, off]},
133            ]},
134        ),
135        struct(
136            name = "complicated_2",
137            expected = False,
138            expr = {"NOT": {"AND": [
139                on,
140                {"NOT": off},
141                {"OR": [on, on, off]},
142            ]}},
143        ),
144    ]
145
146    test_name = "test_config_setting_boolean_algebra"
147
148    for test in tests:
149        config_setting_boolean_algebra(
150            name = test_name + "_config_setting_" + test.name,
151            expr = test.expr,
152        )
153
154        config_setting_test(
155            name = test_name + "_" + test.name,
156            config_setting = ":" + test_name + "_config_setting_" + test.name,
157            expected_value = test.expected,
158        )
159
160    native.test_suite(
161        name = test_name,
162        tests = [
163            test_name + "_" + test.name
164            for test in tests
165        ],
166    )
167    return test_name
168
169def config_setting_boolean_algebra_test_suite(name):
170    native.test_suite(
171        name = name,
172        tests = [
173            _test_always_on(),
174            _test_always_off(),
175            _test_config_setting_boolean_algebra(),
176        ],
177    )
178