Skip to content

Commit f5af973

Browse files
committed
basic tests
1 parent bcd4435 commit f5af973

File tree

3 files changed

+187
-0
lines changed

3 files changed

+187
-0
lines changed

tests/builders/BUILD.bazel

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
load(":attr_builders_tests.bzl", "attr_builders_test_suite")
1516
load(":builders_tests.bzl", "builders_test_suite")
17+
load(":rule_builders_tests.bzl", "rule_builders_test_suite")
1618

1719
builders_test_suite(name = "builders_test_suite")
20+
21+
rule_builders_test_suite(name = "rule_builders_test_suite")
22+
23+
attr_builders_test_suite(name = "attr_builders_test_suite")
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Copyright 2025 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+
load("@rules_testing//lib:analysis_test.bzl", "analysis_test")
16+
load("@rules_testing//lib:test_suite.bzl", "test_suite")
17+
load("@rules_testing//lib:truth.bzl", "subjects", "truth")
18+
load("@rules_testing//lib:util.bzl", rt_util = "util")
19+
load("//python/private:attr_builders.bzl", "attrb") # buildifier: disable=bzl-visibility
20+
21+
_tests = []
22+
23+
objs = {}
24+
25+
def _report_failures(name, env):
26+
failures = env.failures
27+
28+
def _report_failures_impl(env, target):
29+
env._failures.extend(failures)
30+
31+
analysis_test(
32+
name = name,
33+
target = "//python:none",
34+
impl = _report_failures_impl,
35+
)
36+
37+
def _loading_phase_expect(test_name):
38+
env = struct(
39+
ctx = struct(
40+
workspace_name = "bogus",
41+
label = Label(test_name),
42+
attr = struct(
43+
_impl_name = test_name,
44+
),
45+
),
46+
failures = [],
47+
)
48+
return env, truth.expect(env)
49+
50+
def _test_bool_defaults(name):
51+
env, expect = _loading_phase_expect(name)
52+
subject = attrb.Bool()
53+
expect.that_str(subject.doc.get()).equals("")
54+
expect.that_bool(subject.default.get()).equals(False)
55+
expect.that_bool(subject.mandatory.get()).equals(False)
56+
expect.that_dict(subject.extra_kwargs).contains_exactly({})
57+
58+
expect.that_str(str(subject.build())).contains("attr.bool")
59+
_report_failures(name, env)
60+
61+
_tests.append(_test_bool_defaults)
62+
63+
def _test_bool_mutable(name):
64+
subject = attrb.Bool()
65+
subject.default.set(True)
66+
subject.mandatory.set(True)
67+
subject.doc.set("doc")
68+
subject.extra_kwargs["extra"] = "value"
69+
70+
env, expect = _loading_phase_expect(name)
71+
expect.that_str(subject.doc.get()).equals("doc")
72+
expect.that_bool(subject.default.get()).equals(True)
73+
expect.that_bool(subject.mandatory.get()).equals(True)
74+
expect.that_dict(subject.extra_kwargs).contains_exactly({"extra": "value"})
75+
76+
_report_failures(name, env)
77+
78+
_tests.append(_test_bool_mutable)
79+
80+
def attr_builders_test_suite(name):
81+
test_suite(
82+
name = name,
83+
tests = _tests,
84+
)
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
# Copyright 2025 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+
load("@rules_testing//lib:analysis_test.bzl", "analysis_test")
16+
load("@rules_testing//lib:test_suite.bzl", "test_suite")
17+
load("@rules_testing//lib:truth.bzl", "subjects")
18+
load("@rules_testing//lib:util.bzl", rt_util = "util")
19+
load("//python/private:attr_builders.bzl", "attrb") # buildifier: disable=bzl-visibility
20+
load("//python/private:rule_builders.bzl", "ruleb") # buildifier: disable=bzl-visibility
21+
22+
BananaInfo = provider()
23+
24+
def _banana_impl(ctx):
25+
return [BananaInfo(
26+
color = ctx.attr.color,
27+
flavors = ctx.attr.flavors,
28+
organic = ctx.attr.organic,
29+
size = ctx.attr.size,
30+
origin = ctx.attr.origin,
31+
fertilizers = ctx.attr.fertilizers,
32+
xx = mybool,
33+
)]
34+
35+
banana = ruleb.Rule(
36+
implementation = _banana_impl,
37+
attrs = {
38+
"color": attrb.String(default = "yellow"),
39+
"flavors": attrb.StringList(),
40+
"organic": lambda: attrb.Bool(),
41+
"size": lambda: attrb.Int(default = 10),
42+
"origin": lambda: attrb.Label(),
43+
"fertilizers": attrb.LabelList(
44+
allow_files = True,
45+
),
46+
},
47+
).build()
48+
49+
_tests = []
50+
51+
mybool = attrb.Bool()
52+
53+
def _test_basic_rule(name):
54+
banana(
55+
name = name + "_subject",
56+
flavors = ["spicy", "sweet"],
57+
organic = True,
58+
size = 5,
59+
origin = "//python:none",
60+
fertilizers = [
61+
"nitrogen.txt",
62+
"phosphorus.txt",
63+
],
64+
)
65+
66+
analysis_test(
67+
name = name,
68+
target = name + "_subject",
69+
impl = _test_basic_rule_impl,
70+
)
71+
72+
def _test_basic_rule_impl(env, target):
73+
info = target[BananaInfo]
74+
env.expect.that_str(info.color).equals("yellow")
75+
env.expect.that_collection(info.flavors).contains_exactly(["spicy", "sweet"])
76+
env.expect.that_bool(info.organic).equals(True)
77+
env.expect.that_int(info.size).equals(5)
78+
79+
# //python:none is an alias to //python/private:sentinel; we see the
80+
# resolved value, not the intermediate alias
81+
env.expect.that_target(info.origin).label().equals(Label("//python/private:sentinel"))
82+
83+
env.expect.that_collection(info.fertilizers).transform(
84+
desc = "target.label",
85+
map_each = lambda t: t.label,
86+
).contains_exactly([
87+
Label(":nitrogen.txt"),
88+
Label(":phosphorus.txt"),
89+
])
90+
91+
_tests.append(_test_basic_rule)
92+
93+
def rule_builders_test_suite(name):
94+
test_suite(
95+
name = name,
96+
tests = _tests,
97+
)

0 commit comments

Comments
 (0)