xref: /aosp_15_r20/external/bazel-skylib/tests/dicts_tests.bzl (revision bcb5dc7965af6ee42bf2f21341a2ec00233a8c8a)
1# Copyright 2017 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"""Unit tests for dicts.bzl."""
16
17load("//lib:dicts.bzl", "dicts")
18load("//lib:unittest.bzl", "asserts", "unittest")
19
20def _add_test(ctx):
21    """Unit tests for dicts.add."""
22    env = unittest.begin(ctx)
23
24    # Test zero- and one-argument behavior.
25    asserts.equals(env, {}, dicts.add())
26    asserts.equals(env, {"a": 1}, dicts.add({"a": 1}))
27    asserts.equals(env, {"a": 1}, dicts.add(a = 1))
28    asserts.equals(env, {"a": 1, "b": 2}, dicts.add({"a": 1}, b = 2))
29
30    # Test simple two-argument behavior.
31    asserts.equals(env, {"a": 1, "b": 2}, dicts.add({"a": 1}, {"b": 2}))
32    asserts.equals(env, {"a": 1, "b": 2, "c": 3}, dicts.add({"a": 1}, {"b": 2}, c = 3))
33
34    # Test simple more-than-two-argument behavior.
35    asserts.equals(
36        env,
37        {"a": 1, "b": 2, "c": 3, "d": 4},
38        dicts.add({"a": 1}, {"b": 2}, {"c": 3}, {"d": 4}),
39    )
40    asserts.equals(
41        env,
42        {"a": 1, "b": 2, "c": 3, "d": 4, "e": 5},
43        dicts.add({"a": 1}, {"b": 2}, {"c": 3}, {"d": 4}, e = 5),
44    )
45
46    # Test same-key overriding.
47    asserts.equals(env, {"a": 100}, dicts.add({"a": 1}, {"a": 100}))
48    asserts.equals(env, {"a": 100}, dicts.add({"a": 1}, a = 100))
49    asserts.equals(env, {"a": 10}, dicts.add({"a": 1}, {"a": 100}, {"a": 10}))
50    asserts.equals(env, {"a": 10}, dicts.add({"a": 1}, {"a": 100}, a = 10))
51    asserts.equals(
52        env,
53        {"a": 100, "b": 10},
54        dicts.add({"a": 1}, {"a": 100}, {"b": 10}),
55    )
56    asserts.equals(env, {"a": 10}, dicts.add({"a": 1}, {}, {"a": 10}))
57    asserts.equals(env, {"a": 10}, dicts.add({"a": 1}, {}, a = 10))
58    asserts.equals(
59        env,
60        {"a": 10, "b": 5},
61        dicts.add({"a": 1}, {"a": 10, "b": 5}),
62    )
63    asserts.equals(
64        env,
65        {"a": 10, "b": 5},
66        dicts.add({"a": 1}, a = 10, b = 5),
67    )
68
69    # Test some other boundary cases.
70    asserts.equals(env, {"a": 1}, dicts.add({"a": 1}, {}))
71
72    # Since dictionaries are passed around by reference, make sure that the
73    # result of dicts.add is always a *copy* by modifying it afterwards and
74    # ensuring that the original argument doesn't also reflect the change. We do
75    # this to protect against someone who might attempt to optimize the function
76    # by returning the argument itself in the one-argument case.
77    original = {"a": 1}
78    result = dicts.add(original)
79    result["a"] = 2
80    asserts.equals(env, 1, original["a"])
81
82    return unittest.end(env)
83
84add_test = unittest.make(_add_test)
85
86def _omit_test(ctx):
87    """Unit tests for dicts.omit."""
88    env = unittest.begin(ctx)
89
90    # Test empty dict, empty list.
91    asserts.equals(env, {}, dicts.omit({}, []))
92
93    # Test empty dict, nonempty list.
94    asserts.equals(env, {}, dicts.omit({}, ["a"]))
95
96    # Test nonempty dict, empty list.
97    asserts.equals(env, {"a": 1}, dicts.omit({"a": 1}, []))
98
99    # Test key in dict.
100    asserts.equals(env, {}, dicts.omit({"a": 1}, ["a"]))
101
102    # Test key not in dict.
103    asserts.equals(env, {"a": 1}, dicts.omit({"a": 1}, ["b"]))
104
105    # Since dictionaries are passed around by reference, make sure that the
106    # result of dicts.omit is always a *copy* by modifying it afterwards and
107    # ensuring that the original argument doesn't also reflect the change. We do
108    # this to protect against someone who might attempt to optimize the function
109    # by returning the argument itself in the empty list case.
110    original = {"a": 1}
111    result = dicts.omit(original, [])
112    result["a"] = 2
113    asserts.equals(env, 1, original["a"])
114
115    return unittest.end(env)
116
117omit_test = unittest.make(_omit_test)
118
119def _pick_test(ctx):
120    """Unit tests for dicts.pick."""
121    env = unittest.begin(ctx)
122
123    # Test empty dict, empty list.
124    asserts.equals(env, {}, dicts.pick({}, []))
125
126    # Test empty dict, nonempty list.
127    asserts.equals(env, {}, dicts.pick({}, ["a"]))
128
129    # Test nonempty dict, empty list.
130    asserts.equals(env, {}, dicts.pick({"a": 1}, []))
131
132    # Test key in dict.
133    asserts.equals(env, {"a": 1}, dicts.pick({"a": 1}, ["a"]))
134
135    # Test key not in dict.
136    asserts.equals(env, {}, dicts.pick({"a": 1}, ["b"]))
137
138    # Since dictionaries are passed around by reference, make sure that the
139    # result of dicts.pick is always a *copy* by modifying it afterwards and
140    # ensuring that the original argument doesn't also reflect the change. We do
141    # this to protect against someone who might attempt to optimize the function
142    # by returning the argument itself.
143    original = {"a": 1}
144    result = dicts.pick(original, ["a"])
145    result["a"] = 2
146    asserts.equals(env, 1, original["a"])
147
148    return unittest.end(env)
149
150pick_test = unittest.make(_pick_test)
151
152def dicts_test_suite():
153    """Creates the test targets and test suite for dicts.bzl tests."""
154    unittest.suite(
155        "dicts_tests",
156        add_test,
157        omit_test,
158        pick_test,
159    )
160