blob: 96a361cbef3030b34adfed0e654cac94576f2229 [file] [log] [blame]
# Copyright 2024 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tests for the cc_args rule."""
load("//cc:cc_toolchain_config_lib.bzl", "flag_group", "variable_with_value")
load("//cc/toolchains:cc_toolchain_info.bzl", "VariableInfo")
load("//cc/toolchains:format.bzl", "format_arg")
load(
"//cc/toolchains/impl:nested_args.bzl",
"FORMAT_ARGS_ERR",
"REQUIRES_EQUAL_ERR",
"REQUIRES_MUTUALLY_EXCLUSIVE_ERR",
"REQUIRES_NONE_ERR",
"format_string_indexes",
"format_variable",
"nested_args_provider",
"raw_string",
)
load("//tests/rule_based_toolchain:subjects.bzl", "result_fn_wrapper", "subjects")
visibility("private")
def _expect_that_nested(env, expr = None, **kwargs):
return env.expect.that_value(
expr = expr,
value = result_fn_wrapper(nested_args_provider)(
label = Label("//:args"),
**kwargs
),
factory = subjects.result(subjects.NestedArgsInfo),
)
def _expect_that_formatted(env, var, iterate_over = None, expr = None):
return env.expect.that_value(
result_fn_wrapper(format_variable)(var, iterate_over),
factory = subjects.result(subjects.str),
expr = expr or "format_variable(var=%r, iterate_over=%r" % (var, iterate_over),
)
def _expect_that_format_string_indexes(env, var, expr = None):
return env.expect.that_value(
result_fn_wrapper(format_string_indexes)(var),
factory = subjects.result(subjects.collection),
expr = expr or "format_string_indexes(%r)" % var,
)
def _format_string_indexes_test(env, _):
_expect_that_format_string_indexes(env, "foo").ok().contains_exactly([])
_expect_that_format_string_indexes(env, "%%").ok().contains_exactly([])
_expect_that_format_string_indexes(env, "%").err().equals(
'% should always either of the form %s, or escaped with %%. Instead, got "%"',
)
_expect_that_format_string_indexes(env, "%a").err().equals(
'% should always either of the form %s, or escaped with %%. Instead, got "%a"',
)
_expect_that_format_string_indexes(env, "%s").ok().contains_exactly([0])
_expect_that_format_string_indexes(env, "%%%s%s").ok().contains_exactly([2, 4])
_expect_that_format_string_indexes(env, "%%{").ok().contains_exactly([])
_expect_that_format_string_indexes(env, "%%s").ok().contains_exactly([])
_expect_that_format_string_indexes(env, "%{foo}").err().equals(
'Using the old mechanism for variables, %{variable}, but we instead use format_arg("--foo=%s", "//cc/toolchains/variables:<variable>"). Got "%{foo}"',
)
def _formats_raw_strings_test(env, _):
_expect_that_formatted(
env,
raw_string("foo"),
).ok().equals("foo")
_expect_that_formatted(
env,
raw_string("%s"),
).err().contains("Can't use %s with a raw string. Either escape it with %%s or use format_arg")
def _formats_variables_test(env, targets):
_expect_that_formatted(
env,
format_arg("ab %s cd", targets.foo[VariableInfo]),
).ok().equals("ab %{foo} cd")
_expect_that_formatted(
env,
format_arg("foo", targets.foo[VariableInfo]),
).err().equals('format_arg requires a "%s" in the format string, but got "foo"')
_expect_that_formatted(
env,
format_arg("%s%s", targets.foo[VariableInfo]),
).err().equals('Only one %s can be used in a format string, but got "%s%s"')
_expect_that_formatted(
env,
format_arg("%s"),
iterate_over = "foo",
).ok().equals("%{foo}")
_expect_that_formatted(
env,
format_arg("%s"),
).err().contains("format_arg requires either a variable to format, or iterate_over must be provided")
def _iterate_over_test(env, _):
inner = _expect_that_nested(
env,
args = [raw_string("--foo")],
).ok().actual
env.expect.that_str(inner.legacy_flag_group).equals(flag_group(flags = ["--foo"]))
nested = _expect_that_nested(
env,
nested = [inner],
iterate_over = "my_list",
).ok()
nested.iterate_over().some().equals("my_list")
nested.legacy_flag_group().equals(flag_group(
iterate_over = "my_list",
flag_groups = [inner.legacy_flag_group],
))
nested.requires_types().contains_exactly({})
def _requires_types_test(env, targets):
_expect_that_nested(
env,
requires_not_none = "abc",
requires_none = "def",
args = [raw_string("--foo")],
expr = "mutually_exclusive",
).err().equals(REQUIRES_MUTUALLY_EXCLUSIVE_ERR)
_expect_that_nested(
env,
requires_none = "var",
args = [raw_string("--foo")],
expr = "requires_none",
).ok().requires_types().contains_exactly(
{"var": [struct(
msg = REQUIRES_NONE_ERR,
valid_types = ["option"],
after_option_unwrap = False,
)]},
)
_expect_that_nested(
env,
args = [raw_string("foo %s baz")],
expr = "no_variable",
).err().contains("Can't use %s with a raw string")
_expect_that_nested(
env,
args = [format_arg("foo %s baz", targets.foo[VariableInfo])],
expr = "type_validation",
).ok().requires_types().contains_exactly(
{"foo": [struct(
msg = FORMAT_ARGS_ERR,
valid_types = ["string", "file", "directory"],
after_option_unwrap = True,
)]},
)
nested = _expect_that_nested(
env,
requires_equal = "foo",
requires_equal_value = "value",
args = [format_arg("--foo=%s", targets.foo[VariableInfo])],
expr = "type_and_requires_equal_validation",
).ok()
nested.requires_types().contains_exactly(
{"foo": [
struct(
msg = REQUIRES_EQUAL_ERR,
valid_types = ["string"],
after_option_unwrap = True,
),
struct(
msg = FORMAT_ARGS_ERR,
valid_types = ["string", "file", "directory"],
after_option_unwrap = True,
),
]},
)
nested.legacy_flag_group().equals(flag_group(
expand_if_equal = variable_with_value(name = "foo", value = "value"),
flags = ["--foo=%{foo}"],
))
TARGETS = [
":foo",
]
TESTS = {
"format_string_indexes_test": _format_string_indexes_test,
"formats_raw_strings_test": _formats_raw_strings_test,
"formats_variables_test": _formats_variables_test,
"iterate_over_test": _iterate_over_test,
"requires_types_test": _requires_types_test,
}