Reformat .bzl files with buildifier and add format check.
Buildifier 0.12.0 includes initial support for reformatting .bzl files. - Reformat all the bzl files. - Expand the travis check to check the .bzl files also.
This commit is contained in:
parent
a5431b7bab
commit
e5203c0f5d
|
@ -26,9 +26,14 @@ fi
|
|||
# Asked to do a buildifier run.
|
||||
if [[ -n "${BUILDIFER:-}" ]]; then
|
||||
# bazelbuild/buildtools/issues/220 - diff doesn't include the file that needs updating
|
||||
if ! find . -name BUILD -print | xargs buildifier -d > /dev/null 2>&1 ; then
|
||||
echo "ERROR: BUILD file formatting issue(s)"
|
||||
find . -name BUILD -print -exec buildifier -v -d {} \;
|
||||
if ! find . \( -name BUILD -o -name "*.bzl" \) -print | xargs buildifier -d > /dev/null 2>&1 ; then
|
||||
echo "ERROR: BUILD/.bzl file formatting issue(s):"
|
||||
echo ""
|
||||
find . \( -name BUILD -o -name "*.bzl" \) -print -exec buildifier -v -d {} \;
|
||||
echo ""
|
||||
echo "Please download the latest buildifier"
|
||||
echo " https://github.com/bazelbuild/buildtools/releases"
|
||||
echo "and run it over the changed BUILD/.bzl files."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
|
25
lib.bzl
25
lib.bzl
|
@ -14,22 +14,21 @@
|
|||
|
||||
"""Index from which multiple modules can be loaded."""
|
||||
|
||||
load("//lib:collections.bzl", _collections="collections")
|
||||
load("//lib:dicts.bzl", _dicts="dicts")
|
||||
load("//lib:new_sets.bzl", _new_sets="sets")
|
||||
load("//lib:partial.bzl", _partial="partial")
|
||||
load("//lib:paths.bzl", _paths="paths")
|
||||
load("//lib:selects.bzl", _selects="selects")
|
||||
load("//lib:sets.bzl", _sets="sets")
|
||||
load("//lib:shell.bzl", _shell="shell")
|
||||
load("//lib:structs.bzl", _structs="structs")
|
||||
load("//lib:types.bzl", _types="types")
|
||||
load("//lib:versions.bzl", _versions="versions")
|
||||
load("//lib:collections.bzl", _collections = "collections")
|
||||
load("//lib:dicts.bzl", _dicts = "dicts")
|
||||
load("//lib:new_sets.bzl", _new_sets = "sets")
|
||||
load("//lib:partial.bzl", _partial = "partial")
|
||||
load("//lib:paths.bzl", _paths = "paths")
|
||||
load("//lib:selects.bzl", _selects = "selects")
|
||||
load("//lib:sets.bzl", _sets = "sets")
|
||||
load("//lib:shell.bzl", _shell = "shell")
|
||||
load("//lib:structs.bzl", _structs = "structs")
|
||||
load("//lib:types.bzl", _types = "types")
|
||||
load("//lib:versions.bzl", _versions = "versions")
|
||||
|
||||
# The unittest module is treated differently to give more convenient names to
|
||||
# the assert functions, while keeping them in the same .bzl file.
|
||||
load("//lib:unittest.bzl", _asserts="asserts", _unittest="unittest")
|
||||
|
||||
load("//lib:unittest.bzl", _asserts = "asserts", _unittest = "unittest")
|
||||
|
||||
collections = _collections
|
||||
dicts = _dicts
|
||||
|
|
|
@ -14,60 +14,56 @@
|
|||
|
||||
"""Skylib module containing functions that operate on collections."""
|
||||
|
||||
|
||||
def _after_each(separator, iterable):
|
||||
"""Inserts `separator` after each item in `iterable`.
|
||||
"""Inserts `separator` after each item in `iterable`.
|
||||
|
||||
Args:
|
||||
separator: The value to insert after each item in `iterable`.
|
||||
iterable: The list into which to intersperse the separator.
|
||||
Args:
|
||||
separator: The value to insert after each item in `iterable`.
|
||||
iterable: The list into which to intersperse the separator.
|
||||
|
||||
Returns:
|
||||
A new list with `separator` after each item in `iterable`.
|
||||
"""
|
||||
result = []
|
||||
for x in iterable:
|
||||
result.append(x)
|
||||
result.append(separator)
|
||||
|
||||
return result
|
||||
Returns:
|
||||
A new list with `separator` after each item in `iterable`.
|
||||
"""
|
||||
result = []
|
||||
for x in iterable:
|
||||
result.append(x)
|
||||
result.append(separator)
|
||||
|
||||
return result
|
||||
|
||||
def _before_each(separator, iterable):
|
||||
"""Inserts `separator` before each item in `iterable`.
|
||||
"""Inserts `separator` before each item in `iterable`.
|
||||
|
||||
Args:
|
||||
separator: The value to insert before each item in `iterable`.
|
||||
iterable: The list into which to intersperse the separator.
|
||||
Args:
|
||||
separator: The value to insert before each item in `iterable`.
|
||||
iterable: The list into which to intersperse the separator.
|
||||
|
||||
Returns:
|
||||
A new list with `separator` before each item in `iterable`.
|
||||
"""
|
||||
result = []
|
||||
for x in iterable:
|
||||
result.append(separator)
|
||||
result.append(x)
|
||||
|
||||
return result
|
||||
Returns:
|
||||
A new list with `separator` before each item in `iterable`.
|
||||
"""
|
||||
result = []
|
||||
for x in iterable:
|
||||
result.append(separator)
|
||||
result.append(x)
|
||||
|
||||
return result
|
||||
|
||||
def _uniq(iterable):
|
||||
"""Returns a list of unique elements in `iterable`.
|
||||
"""Returns a list of unique elements in `iterable`.
|
||||
|
||||
Requires all the elements to be hashable.
|
||||
Requires all the elements to be hashable.
|
||||
|
||||
Args:
|
||||
iterable: An iterable to filter.
|
||||
|
||||
Returns:
|
||||
A new list with all unique elements from `iterable`.
|
||||
"""
|
||||
unique_elements = {element: None for element in iterable}
|
||||
return unique_elements.keys()
|
||||
Args:
|
||||
iterable: An iterable to filter.
|
||||
|
||||
Returns:
|
||||
A new list with all unique elements from `iterable`.
|
||||
"""
|
||||
unique_elements = {element: None for element in iterable}
|
||||
return unique_elements.keys()
|
||||
|
||||
collections = struct(
|
||||
after_each=_after_each,
|
||||
before_each=_before_each,
|
||||
uniq=_uniq,
|
||||
after_each = _after_each,
|
||||
before_each = _before_each,
|
||||
uniq = _uniq,
|
||||
)
|
||||
|
|
|
@ -14,30 +14,28 @@
|
|||
|
||||
"""Skylib module containing functions that operate on dictionaries."""
|
||||
|
||||
|
||||
def _add(*dictionaries):
|
||||
"""Returns a new `dict` that has all the entries of the given dictionaries.
|
||||
"""Returns a new `dict` that has all the entries of the given dictionaries.
|
||||
|
||||
If the same key is present in more than one of the input dictionaries, the
|
||||
last of them in the argument list overrides any earlier ones.
|
||||
If the same key is present in more than one of the input dictionaries, the
|
||||
last of them in the argument list overrides any earlier ones.
|
||||
|
||||
This function is designed to take zero or one arguments as well as multiple
|
||||
dictionaries, so that it follows arithmetic identities and callers can avoid
|
||||
special cases for their inputs: the sum of zero dictionaries is the empty
|
||||
dictionary, and the sum of a single dictionary is a copy of itself.
|
||||
This function is designed to take zero or one arguments as well as multiple
|
||||
dictionaries, so that it follows arithmetic identities and callers can avoid
|
||||
special cases for their inputs: the sum of zero dictionaries is the empty
|
||||
dictionary, and the sum of a single dictionary is a copy of itself.
|
||||
|
||||
Args:
|
||||
*dictionaries: Zero or more dictionaries to be added.
|
||||
|
||||
Returns:
|
||||
A new `dict` that has all the entries of the given dictionaries.
|
||||
"""
|
||||
result = {}
|
||||
for d in dictionaries:
|
||||
result.update(d)
|
||||
return result
|
||||
Args:
|
||||
*dictionaries: Zero or more dictionaries to be added.
|
||||
|
||||
Returns:
|
||||
A new `dict` that has all the entries of the given dictionaries.
|
||||
"""
|
||||
result = {}
|
||||
for d in dictionaries:
|
||||
result.update(d)
|
||||
return result
|
||||
|
||||
dicts = struct(
|
||||
add=_add,
|
||||
add = _add,
|
||||
)
|
||||
|
|
309
lib/new_sets.bzl
309
lib/new_sets.bzl
|
@ -22,230 +22,215 @@
|
|||
|
||||
load(":dicts.bzl", "dicts")
|
||||
|
||||
def _make(elements = None):
|
||||
"""Creates a new set.
|
||||
|
||||
def _make(elements=None):
|
||||
"""Creates a new set.
|
||||
All elements must be hashable.
|
||||
|
||||
All elements must be hashable.
|
||||
|
||||
Args:
|
||||
elements: Optional sequence to construct the set out of.
|
||||
|
||||
Returns:
|
||||
A set containing the passed in values.
|
||||
"""
|
||||
elements = elements if elements else []
|
||||
return struct(_values = {e: None for e in elements})
|
||||
Args:
|
||||
elements: Optional sequence to construct the set out of.
|
||||
|
||||
Returns:
|
||||
A set containing the passed in values.
|
||||
"""
|
||||
elements = elements if elements else []
|
||||
return struct(_values = {e: None for e in elements})
|
||||
|
||||
def _copy(s):
|
||||
"""Creates a new set from another set.
|
||||
"""Creates a new set from another set.
|
||||
|
||||
Args:
|
||||
s: A set, as returned by `sets.make()`.
|
||||
|
||||
Returns:
|
||||
A new set containing the same elements as `s`.
|
||||
"""
|
||||
return struct(_values = dict(s._values))
|
||||
Args:
|
||||
s: A set, as returned by `sets.make()`.
|
||||
|
||||
Returns:
|
||||
A new set containing the same elements as `s`.
|
||||
"""
|
||||
return struct(_values = dict(s._values))
|
||||
|
||||
def _to_list(s):
|
||||
"""Creates a list from the values in the set.
|
||||
"""Creates a list from the values in the set.
|
||||
|
||||
Args:
|
||||
s: A set, as returned by `sets.make()`.
|
||||
|
||||
Returns:
|
||||
A list of values inserted into the set.
|
||||
"""
|
||||
return s._values.keys()
|
||||
Args:
|
||||
s: A set, as returned by `sets.make()`.
|
||||
|
||||
Returns:
|
||||
A list of values inserted into the set.
|
||||
"""
|
||||
return s._values.keys()
|
||||
|
||||
def _insert(s, e):
|
||||
"""Inserts an element into the set.
|
||||
"""Inserts an element into the set.
|
||||
|
||||
Element must be hashable. This mutates the orginal set.
|
||||
Element must be hashable. This mutates the orginal set.
|
||||
|
||||
Args:
|
||||
s: A set, as returned by `sets.make()`.
|
||||
e: The element to be inserted.
|
||||
|
||||
Returns:
|
||||
The set `s` with `e` included.
|
||||
"""
|
||||
s._values[e] = None
|
||||
return s
|
||||
Args:
|
||||
s: A set, as returned by `sets.make()`.
|
||||
e: The element to be inserted.
|
||||
|
||||
Returns:
|
||||
The set `s` with `e` included.
|
||||
"""
|
||||
s._values[e] = None
|
||||
return s
|
||||
|
||||
def _remove(s, e):
|
||||
"""Removes an element from the set.
|
||||
"""Removes an element from the set.
|
||||
|
||||
Element must be hashable. This mutates the orginal set.
|
||||
Element must be hashable. This mutates the orginal set.
|
||||
|
||||
Args:
|
||||
s: A set, as returned by `sets.make()`.
|
||||
e: The element to be removed.
|
||||
|
||||
Returns:
|
||||
The set `s` with `e` removed.
|
||||
"""
|
||||
s._values.pop(e)
|
||||
return s
|
||||
Args:
|
||||
s: A set, as returned by `sets.make()`.
|
||||
e: The element to be removed.
|
||||
|
||||
Returns:
|
||||
The set `s` with `e` removed.
|
||||
"""
|
||||
s._values.pop(e)
|
||||
return s
|
||||
|
||||
def _contains(a, e):
|
||||
"""Checks for the existence of an element in a set.
|
||||
"""Checks for the existence of an element in a set.
|
||||
|
||||
Args:
|
||||
a: A set, as returned by `sets.make()`.
|
||||
e: The element to look for.
|
||||
|
||||
Returns:
|
||||
True if the element exists in the set, False if the element does not.
|
||||
"""
|
||||
return e in a._values
|
||||
Args:
|
||||
a: A set, as returned by `sets.make()`.
|
||||
e: The element to look for.
|
||||
|
||||
Returns:
|
||||
True if the element exists in the set, False if the element does not.
|
||||
"""
|
||||
return e in a._values
|
||||
|
||||
def _get_shorter_and_longer(a, b):
|
||||
"""Returns two sets in the order of shortest and longest.
|
||||
"""Returns two sets in the order of shortest and longest.
|
||||
|
||||
Args:
|
||||
a: A set, as returned by `sets.make()`.
|
||||
b: A set, as returned by `sets.make()`.
|
||||
|
||||
Returns:
|
||||
`a`, `b` if `a` is shorter than `b` - or `b`, `a` if `b` is shorter than `a`.
|
||||
"""
|
||||
if _length(a) < _length(b):
|
||||
return a, b
|
||||
return b, a
|
||||
Args:
|
||||
a: A set, as returned by `sets.make()`.
|
||||
b: A set, as returned by `sets.make()`.
|
||||
|
||||
Returns:
|
||||
`a`, `b` if `a` is shorter than `b` - or `b`, `a` if `b` is shorter than `a`.
|
||||
"""
|
||||
if _length(a) < _length(b):
|
||||
return a, b
|
||||
return b, a
|
||||
|
||||
def _is_equal(a, b):
|
||||
"""Returns whether two sets are equal.
|
||||
"""Returns whether two sets are equal.
|
||||
|
||||
Args:
|
||||
a: A set, as returned by `sets.make()`.
|
||||
b: A set, as returned by `sets.make()`.
|
||||
|
||||
Returns:
|
||||
True if `a` is equal to `b`, False otherwise.
|
||||
"""
|
||||
return a._values == b._values
|
||||
Args:
|
||||
a: A set, as returned by `sets.make()`.
|
||||
b: A set, as returned by `sets.make()`.
|
||||
|
||||
Returns:
|
||||
True if `a` is equal to `b`, False otherwise.
|
||||
"""
|
||||
return a._values == b._values
|
||||
|
||||
def _is_subset(a, b):
|
||||
"""Returns whether `a` is a subset of `b`.
|
||||
"""Returns whether `a` is a subset of `b`.
|
||||
|
||||
Args:
|
||||
a: A set, as returned by `sets.make()`.
|
||||
b: A set, as returned by `sets.make()`.
|
||||
|
||||
Returns:
|
||||
True if `a` is a subset of `b`, False otherwise.
|
||||
"""
|
||||
for e in a._values.keys():
|
||||
if e not in b._values:
|
||||
return False
|
||||
return True
|
||||
Args:
|
||||
a: A set, as returned by `sets.make()`.
|
||||
b: A set, as returned by `sets.make()`.
|
||||
|
||||
Returns:
|
||||
True if `a` is a subset of `b`, False otherwise.
|
||||
"""
|
||||
for e in a._values.keys():
|
||||
if e not in b._values:
|
||||
return False
|
||||
return True
|
||||
|
||||
def _disjoint(a, b):
|
||||
"""Returns whether two sets are disjoint.
|
||||
"""Returns whether two sets are disjoint.
|
||||
|
||||
Two sets are disjoint if they have no elements in common.
|
||||
Two sets are disjoint if they have no elements in common.
|
||||
|
||||
Args:
|
||||
a: A set, as returned by `sets.make()`.
|
||||
b: A set, as returned by `sets.make()`.
|
||||
|
||||
Returns:
|
||||
True if `a` and `b` are disjoint, False otherwise.
|
||||
"""
|
||||
shorter, longer = _get_shorter_and_longer(a, b)
|
||||
for e in shorter._values.keys():
|
||||
if e in longer._values:
|
||||
return False
|
||||
return True
|
||||
Args:
|
||||
a: A set, as returned by `sets.make()`.
|
||||
b: A set, as returned by `sets.make()`.
|
||||
|
||||
Returns:
|
||||
True if `a` and `b` are disjoint, False otherwise.
|
||||
"""
|
||||
shorter, longer = _get_shorter_and_longer(a, b)
|
||||
for e in shorter._values.keys():
|
||||
if e in longer._values:
|
||||
return False
|
||||
return True
|
||||
|
||||
def _intersection(a, b):
|
||||
"""Returns the intersection of two sets.
|
||||
"""Returns the intersection of two sets.
|
||||
|
||||
Args:
|
||||
a: A set, as returned by `sets.make()`.
|
||||
b: A set, as returned by `sets.make()`.
|
||||
|
||||
Returns:
|
||||
A set containing the elements that are in both `a` and `b`.
|
||||
"""
|
||||
shorter, longer = _get_shorter_and_longer(a, b)
|
||||
return struct(_values = {e: None for e in shorter._values.keys() if e in longer._values})
|
||||
Args:
|
||||
a: A set, as returned by `sets.make()`.
|
||||
b: A set, as returned by `sets.make()`.
|
||||
|
||||
Returns:
|
||||
A set containing the elements that are in both `a` and `b`.
|
||||
"""
|
||||
shorter, longer = _get_shorter_and_longer(a, b)
|
||||
return struct(_values = {e: None for e in shorter._values.keys() if e in longer._values})
|
||||
|
||||
def _union(*args):
|
||||
"""Returns the union of several sets.
|
||||
"""Returns the union of several sets.
|
||||
|
||||
Args:
|
||||
*args: An arbitrary number of sets or lists.
|
||||
|
||||
Returns:
|
||||
The set union of all sets or lists in `*args`.
|
||||
"""
|
||||
return struct(_values = dicts.add(*[s._values for s in args]))
|
||||
Args:
|
||||
*args: An arbitrary number of sets or lists.
|
||||
|
||||
Returns:
|
||||
The set union of all sets or lists in `*args`.
|
||||
"""
|
||||
return struct(_values = dicts.add(*[s._values for s in args]))
|
||||
|
||||
def _difference(a, b):
|
||||
"""Returns the elements in `a` that are not in `b`.
|
||||
"""Returns the elements in `a` that are not in `b`.
|
||||
|
||||
Args:
|
||||
a: A set, as returned by `sets.make()`.
|
||||
b: A set, as returned by `sets.make()`.
|
||||
|
||||
Returns:
|
||||
A set containing the elements that are in `a` but not in `b`.
|
||||
"""
|
||||
return struct(_values = {e: None for e in a._values.keys() if e not in b._values})
|
||||
Args:
|
||||
a: A set, as returned by `sets.make()`.
|
||||
b: A set, as returned by `sets.make()`.
|
||||
|
||||
Returns:
|
||||
A set containing the elements that are in `a` but not in `b`.
|
||||
"""
|
||||
return struct(_values = {e: None for e in a._values.keys() if e not in b._values})
|
||||
|
||||
def _length(s):
|
||||
"""Returns the number of elements in a set.
|
||||
"""Returns the number of elements in a set.
|
||||
|
||||
Args:
|
||||
s: A set, as returned by `sets.make()`.
|
||||
Args:
|
||||
s: A set, as returned by `sets.make()`.
|
||||
|
||||
Returns:
|
||||
An integer representing the number of elements in the set.
|
||||
"""
|
||||
return len(s._values)
|
||||
Returns:
|
||||
An integer representing the number of elements in the set.
|
||||
"""
|
||||
return len(s._values)
|
||||
|
||||
def _repr(s):
|
||||
"""Returns a string value representing the set.
|
||||
"""Returns a string value representing the set.
|
||||
|
||||
Args:
|
||||
s: A set, as returned by `sets.make()`.
|
||||
|
||||
Returns:
|
||||
A string representing the set.
|
||||
"""
|
||||
return repr(s._values.keys())
|
||||
Args:
|
||||
s: A set, as returned by `sets.make()`.
|
||||
|
||||
Returns:
|
||||
A string representing the set.
|
||||
"""
|
||||
return repr(s._values.keys())
|
||||
|
||||
sets = struct(
|
||||
make = _make,
|
||||
copy = _copy,
|
||||
to_list = _to_list,
|
||||
insert = _insert,
|
||||
contains = _contains,
|
||||
is_equal = _is_equal,
|
||||
is_subset = _is_subset,
|
||||
disjoint = _disjoint,
|
||||
intersection = _intersection,
|
||||
union = _union,
|
||||
difference = _difference,
|
||||
length = _length,
|
||||
remove = _remove,
|
||||
repr = _repr,
|
||||
str = _repr,
|
||||
make = _make,
|
||||
copy = _copy,
|
||||
to_list = _to_list,
|
||||
insert = _insert,
|
||||
contains = _contains,
|
||||
is_equal = _is_equal,
|
||||
is_subset = _is_subset,
|
||||
disjoint = _disjoint,
|
||||
intersection = _intersection,
|
||||
union = _union,
|
||||
difference = _difference,
|
||||
length = _length,
|
||||
remove = _remove,
|
||||
repr = _repr,
|
||||
str = _repr,
|
||||
)
|
||||
|
|
156
lib/partial.bzl
156
lib/partial.bzl
|
@ -20,111 +20,111 @@ Similar to https://docs.python.org/3/library/functools.html#functools.partial.
|
|||
"""
|
||||
|
||||
def _call(partial, *args, **kwargs):
|
||||
"""Calls a partial created using `make`.
|
||||
"""Calls a partial created using `make`.
|
||||
|
||||
Args:
|
||||
partial: The partial to be called.
|
||||
*args: Additional positional arguments to be appended to the ones given to
|
||||
make.
|
||||
**kwargs: Additional keyword arguments to augment and override the ones
|
||||
given to make.
|
||||
Args:
|
||||
partial: The partial to be called.
|
||||
*args: Additional positional arguments to be appended to the ones given to
|
||||
make.
|
||||
**kwargs: Additional keyword arguments to augment and override the ones
|
||||
given to make.
|
||||
|
||||
Returns:
|
||||
Whatever the function in the partial returns.
|
||||
"""
|
||||
function_args = partial.args + args
|
||||
function_kwargs = dict(partial.kwargs)
|
||||
function_kwargs.update(kwargs)
|
||||
return partial.function(*function_args, **function_kwargs)
|
||||
Returns:
|
||||
Whatever the function in the partial returns.
|
||||
"""
|
||||
function_args = partial.args + args
|
||||
function_kwargs = dict(partial.kwargs)
|
||||
function_kwargs.update(kwargs)
|
||||
return partial.function(*function_args, **function_kwargs)
|
||||
|
||||
def _make(func, *args, **kwargs):
|
||||
"""Creates a partial that can be called using `call`.
|
||||
"""Creates a partial that can be called using `call`.
|
||||
|
||||
A partial can have args assigned to it at the make site, and can have args
|
||||
passed to it at the call sites.
|
||||
A partial can have args assigned to it at the make site, and can have args
|
||||
passed to it at the call sites.
|
||||
|
||||
A partial 'function' can be defined with positional args and kwargs:
|
||||
A partial 'function' can be defined with positional args and kwargs:
|
||||
|
||||
# function with no args
|
||||
def function1():
|
||||
...
|
||||
# function with no args
|
||||
def function1():
|
||||
...
|
||||
|
||||
# function with 2 args
|
||||
def function2(arg1, arg2):
|
||||
...
|
||||
# function with 2 args
|
||||
def function2(arg1, arg2):
|
||||
...
|
||||
|
||||
# function with 2 args and keyword args
|
||||
def function3(arg1, arg2, x, y):
|
||||
...
|
||||
# function with 2 args and keyword args
|
||||
def function3(arg1, arg2, x, y):
|
||||
...
|
||||
|
||||
The positional args passed to the function are the args passed into make
|
||||
followed by any additional positional args given to call. The below example
|
||||
illustrates a function with two positional arguments where one is supplied by
|
||||
make and the other by call:
|
||||
The positional args passed to the function are the args passed into make
|
||||
followed by any additional positional args given to call. The below example
|
||||
illustrates a function with two positional arguments where one is supplied by
|
||||
make and the other by call:
|
||||
|
||||
# function demonstrating 1 arg at make site, and 1 arg at call site
|
||||
def _foo(make_arg1, func_arg1):
|
||||
print(make_arg1 + " " + func_arg1 + "!")
|
||||
# function demonstrating 1 arg at make site, and 1 arg at call site
|
||||
def _foo(make_arg1, func_arg1):
|
||||
print(make_arg1 + " " + func_arg1 + "!")
|
||||
|
||||
For example:
|
||||
For example:
|
||||
|
||||
hi_func = partial.make(_foo, "Hello")
|
||||
bye_func = partial.make(_foo, "Goodbye")
|
||||
partial.call(hi_func, "Jennifer")
|
||||
partial.call(hi_func, "Dave")
|
||||
partial.call(bye_func, "Jennifer")
|
||||
partial.call(bye_func, "Dave")
|
||||
hi_func = partial.make(_foo, "Hello")
|
||||
bye_func = partial.make(_foo, "Goodbye")
|
||||
partial.call(hi_func, "Jennifer")
|
||||
partial.call(hi_func, "Dave")
|
||||
partial.call(bye_func, "Jennifer")
|
||||
partial.call(bye_func, "Dave")
|
||||
|
||||
prints:
|
||||
prints:
|
||||
|
||||
"Hello, Jennifer!"
|
||||
"Hello, Dave!"
|
||||
"Goodbye, Jennifer!"
|
||||
"Goodbye, Dave!"
|
||||
"Hello, Jennifer!"
|
||||
"Hello, Dave!"
|
||||
"Goodbye, Jennifer!"
|
||||
"Goodbye, Dave!"
|
||||
|
||||
The keyword args given to the function are the kwargs passed into make
|
||||
unioned with the keyword args given to call. In case of a conflict, the
|
||||
keyword args given to call take precedence. This allows you to set a default
|
||||
value for keyword arguments and override it at the call site.
|
||||
The keyword args given to the function are the kwargs passed into make
|
||||
unioned with the keyword args given to call. In case of a conflict, the
|
||||
keyword args given to call take precedence. This allows you to set a default
|
||||
value for keyword arguments and override it at the call site.
|
||||
|
||||
Example with a make site arg, a call site arg, a make site kwarg and a
|
||||
call site kwarg:
|
||||
Example with a make site arg, a call site arg, a make site kwarg and a
|
||||
call site kwarg:
|
||||
|
||||
def _foo(make_arg1, call_arg1, make_location, call_location):
|
||||
print(make_arg1 + " is from " + make_location + " and " +
|
||||
call_arg1 + " is from " + call_location + "!")
|
||||
def _foo(make_arg1, call_arg1, make_location, call_location):
|
||||
print(make_arg1 + " is from " + make_location + " and " +
|
||||
call_arg1 + " is from " + call_location + "!")
|
||||
|
||||
func = partial.make(_foo, "Ben", make_location="Hollywood")
|
||||
partial.call(func, "Jennifer", call_location="Denver")
|
||||
func = partial.make(_foo, "Ben", make_location="Hollywood")
|
||||
partial.call(func, "Jennifer", call_location="Denver")
|
||||
|
||||
Prints "Ben is from Hollywood and Jennifer is from Denver!".
|
||||
Prints "Ben is from Hollywood and Jennifer is from Denver!".
|
||||
|
||||
partial.call(func, "Jennifer", make_location="LA", call_location="Denver")
|
||||
partial.call(func, "Jennifer", make_location="LA", call_location="Denver")
|
||||
|
||||
Prints "Ben is from LA and Jennifer is from Denver!".
|
||||
Prints "Ben is from LA and Jennifer is from Denver!".
|
||||
|
||||
Note that keyword args may not overlap with positional args, regardless of
|
||||
whether they are given during the make or call step. For instance, you can't
|
||||
do:
|
||||
Note that keyword args may not overlap with positional args, regardless of
|
||||
whether they are given during the make or call step. For instance, you can't
|
||||
do:
|
||||
|
||||
def foo(x):
|
||||
pass
|
||||
def foo(x):
|
||||
pass
|
||||
|
||||
func = partial.make(foo, 1)
|
||||
partial.call(func, x=2)
|
||||
func = partial.make(foo, 1)
|
||||
partial.call(func, x=2)
|
||||
|
||||
Args:
|
||||
func: The function to be called.
|
||||
*args: Positional arguments to be passed to function.
|
||||
**kwargs: Keyword arguments to be passed to function. Note that these can
|
||||
be overridden at the call sites.
|
||||
Args:
|
||||
func: The function to be called.
|
||||
*args: Positional arguments to be passed to function.
|
||||
**kwargs: Keyword arguments to be passed to function. Note that these can
|
||||
be overridden at the call sites.
|
||||
|
||||
Returns:
|
||||
A new `partial` that can be called using `call`
|
||||
"""
|
||||
return struct(function=func, args=args, kwargs=kwargs)
|
||||
Returns:
|
||||
A new `partial` that can be called using `call`
|
||||
"""
|
||||
return struct(function = func, args = args, kwargs = kwargs)
|
||||
|
||||
partial = struct(
|
||||
make=_make,
|
||||
call=_call,
|
||||
make = _make,
|
||||
call = _call,
|
||||
)
|
||||
|
|
339
lib/paths.bzl
339
lib/paths.bzl
|
@ -19,233 +19,224 @@ path separators (forward slash, "/"); they do not handle Windows-style paths
|
|||
with backslash separators or drive letters.
|
||||
"""
|
||||
|
||||
|
||||
def _basename(p):
|
||||
"""Returns the basename (i.e., the file portion) of a path.
|
||||
"""Returns the basename (i.e., the file portion) of a path.
|
||||
|
||||
Note that if `p` ends with a slash, this function returns an empty string.
|
||||
This matches the behavior of Python's `os.path.basename`, but differs from
|
||||
the Unix `basename` command (which would return the path segment preceding
|
||||
the final slash).
|
||||
Note that if `p` ends with a slash, this function returns an empty string.
|
||||
This matches the behavior of Python's `os.path.basename`, but differs from
|
||||
the Unix `basename` command (which would return the path segment preceding
|
||||
the final slash).
|
||||
|
||||
Args:
|
||||
p: The path whose basename should be returned.
|
||||
|
||||
Returns:
|
||||
The basename of the path, which includes the extension.
|
||||
"""
|
||||
return p.rpartition("/")[-1]
|
||||
Args:
|
||||
p: The path whose basename should be returned.
|
||||
|
||||
Returns:
|
||||
The basename of the path, which includes the extension.
|
||||
"""
|
||||
return p.rpartition("/")[-1]
|
||||
|
||||
def _dirname(p):
|
||||
"""Returns the dirname of a path.
|
||||
"""Returns the dirname of a path.
|
||||
|
||||
The dirname is the portion of `p` up to but not including the file portion
|
||||
(i.e., the basename). Any slashes immediately preceding the basename are not
|
||||
included, unless omitting them would make the dirname empty.
|
||||
The dirname is the portion of `p` up to but not including the file portion
|
||||
(i.e., the basename). Any slashes immediately preceding the basename are not
|
||||
included, unless omitting them would make the dirname empty.
|
||||
|
||||
Args:
|
||||
p: The path whose dirname should be returned.
|
||||
|
||||
Returns:
|
||||
The dirname of the path.
|
||||
"""
|
||||
prefix, sep, _ = p.rpartition("/")
|
||||
if not prefix:
|
||||
return sep
|
||||
else:
|
||||
# If there are multiple consecutive slashes, strip them all out as Python's
|
||||
# os.path.dirname does.
|
||||
return prefix.rstrip("/")
|
||||
Args:
|
||||
p: The path whose dirname should be returned.
|
||||
|
||||
Returns:
|
||||
The dirname of the path.
|
||||
"""
|
||||
prefix, sep, _ = p.rpartition("/")
|
||||
if not prefix:
|
||||
return sep
|
||||
else:
|
||||
# If there are multiple consecutive slashes, strip them all out as Python's
|
||||
# os.path.dirname does.
|
||||
return prefix.rstrip("/")
|
||||
|
||||
def _is_absolute(path):
|
||||
"""Returns `True` if `path` is an absolute path.
|
||||
"""Returns `True` if `path` is an absolute path.
|
||||
|
||||
Args:
|
||||
path: A path (which is a string).
|
||||
|
||||
Returns:
|
||||
`True` if `path` is an absolute path.
|
||||
"""
|
||||
return path.startswith("/") or (len(path)>2 and path[1] == ":")
|
||||
Args:
|
||||
path: A path (which is a string).
|
||||
|
||||
Returns:
|
||||
`True` if `path` is an absolute path.
|
||||
"""
|
||||
return path.startswith("/") or (len(path) > 2 and path[1] == ":")
|
||||
|
||||
def _join(path, *others):
|
||||
"""Joins one or more path components intelligently.
|
||||
"""Joins one or more path components intelligently.
|
||||
|
||||
This function mimics the behavior of Python's `os.path.join` function on POSIX
|
||||
platform. It returns the concatenation of `path` and any members of `others`,
|
||||
inserting directory separators before each component except the first. The
|
||||
separator is not inserted if the path up until that point is either empty or
|
||||
already ends in a separator.
|
||||
This function mimics the behavior of Python's `os.path.join` function on POSIX
|
||||
platform. It returns the concatenation of `path` and any members of `others`,
|
||||
inserting directory separators before each component except the first. The
|
||||
separator is not inserted if the path up until that point is either empty or
|
||||
already ends in a separator.
|
||||
|
||||
If any component is an absolute path, all previous components are discarded.
|
||||
If any component is an absolute path, all previous components are discarded.
|
||||
|
||||
Args:
|
||||
path: A path segment.
|
||||
*others: Additional path segments.
|
||||
Args:
|
||||
path: A path segment.
|
||||
*others: Additional path segments.
|
||||
|
||||
Returns:
|
||||
A string containing the joined paths.
|
||||
"""
|
||||
result = path
|
||||
Returns:
|
||||
A string containing the joined paths.
|
||||
"""
|
||||
result = path
|
||||
|
||||
for p in others:
|
||||
if _is_absolute(p):
|
||||
result = p
|
||||
elif not result or result.endswith("/"):
|
||||
result += p
|
||||
else:
|
||||
result += "/" + p
|
||||
|
||||
return result
|
||||
for p in others:
|
||||
if _is_absolute(p):
|
||||
result = p
|
||||
elif not result or result.endswith("/"):
|
||||
result += p
|
||||
else:
|
||||
result += "/" + p
|
||||
|
||||
return result
|
||||
|
||||
def _normalize(path):
|
||||
"""Normalizes a path, eliminating double slashes and other redundant segments.
|
||||
"""Normalizes a path, eliminating double slashes and other redundant segments.
|
||||
|
||||
This function mimics the behavior of Python's `os.path.normpath` function on
|
||||
POSIX platforms; specifically:
|
||||
This function mimics the behavior of Python's `os.path.normpath` function on
|
||||
POSIX platforms; specifically:
|
||||
|
||||
- If the entire path is empty, "." is returned.
|
||||
- All "." segments are removed, unless the path consists solely of a single
|
||||
"." segment.
|
||||
- Trailing slashes are removed, unless the path consists solely of slashes.
|
||||
- ".." segments are removed as long as there are corresponding segments
|
||||
earlier in the path to remove; otherwise, they are retained as leading ".."
|
||||
segments.
|
||||
- Single and double leading slashes are preserved, but three or more leading
|
||||
slashes are collapsed into a single leading slash.
|
||||
- Multiple adjacent internal slashes are collapsed into a single slash.
|
||||
- If the entire path is empty, "." is returned.
|
||||
- All "." segments are removed, unless the path consists solely of a single
|
||||
"." segment.
|
||||
- Trailing slashes are removed, unless the path consists solely of slashes.
|
||||
- ".." segments are removed as long as there are corresponding segments
|
||||
earlier in the path to remove; otherwise, they are retained as leading ".."
|
||||
segments.
|
||||
- Single and double leading slashes are preserved, but three or more leading
|
||||
slashes are collapsed into a single leading slash.
|
||||
- Multiple adjacent internal slashes are collapsed into a single slash.
|
||||
|
||||
Args:
|
||||
path: A path.
|
||||
Args:
|
||||
path: A path.
|
||||
|
||||
Returns:
|
||||
The normalized path.
|
||||
"""
|
||||
if not path:
|
||||
return "."
|
||||
Returns:
|
||||
The normalized path.
|
||||
"""
|
||||
if not path:
|
||||
return "."
|
||||
|
||||
if path.startswith("//") and not path.startswith("///"):
|
||||
initial_slashes = 2
|
||||
elif path.startswith("/"):
|
||||
initial_slashes = 1
|
||||
else:
|
||||
initial_slashes = 0
|
||||
is_relative = (initial_slashes == 0)
|
||||
|
||||
components = path.split("/")
|
||||
new_components = []
|
||||
|
||||
for component in components:
|
||||
if component in ("", "."):
|
||||
continue
|
||||
if component == "..":
|
||||
if new_components and new_components[-1] != "..":
|
||||
# Only pop the last segment if it isn't another "..".
|
||||
new_components.pop()
|
||||
elif is_relative:
|
||||
# Preserve leading ".." segments for relative paths.
|
||||
new_components.append(component)
|
||||
if path.startswith("//") and not path.startswith("///"):
|
||||
initial_slashes = 2
|
||||
elif path.startswith("/"):
|
||||
initial_slashes = 1
|
||||
else:
|
||||
new_components.append(component)
|
||||
initial_slashes = 0
|
||||
is_relative = (initial_slashes == 0)
|
||||
|
||||
path = "/".join(new_components)
|
||||
if not is_relative:
|
||||
path = ("/" * initial_slashes) + path
|
||||
components = path.split("/")
|
||||
new_components = []
|
||||
|
||||
return path or "."
|
||||
for component in components:
|
||||
if component in ("", "."):
|
||||
continue
|
||||
if component == "..":
|
||||
if new_components and new_components[-1] != "..":
|
||||
# Only pop the last segment if it isn't another "..".
|
||||
new_components.pop()
|
||||
elif is_relative:
|
||||
# Preserve leading ".." segments for relative paths.
|
||||
new_components.append(component)
|
||||
else:
|
||||
new_components.append(component)
|
||||
|
||||
path = "/".join(new_components)
|
||||
if not is_relative:
|
||||
path = ("/" * initial_slashes) + path
|
||||
|
||||
return path or "."
|
||||
|
||||
def _relativize(path, start):
|
||||
"""Returns the portion of `path` that is relative to `start`.
|
||||
"""Returns the portion of `path` that is relative to `start`.
|
||||
|
||||
Because we do not have access to the underlying file system, this
|
||||
implementation differs slightly from Python's `os.path.relpath` in that it
|
||||
will fail if `path` is not beneath `start` (rather than use parent segments to
|
||||
walk up to the common file system root).
|
||||
Because we do not have access to the underlying file system, this
|
||||
implementation differs slightly from Python's `os.path.relpath` in that it
|
||||
will fail if `path` is not beneath `start` (rather than use parent segments to
|
||||
walk up to the common file system root).
|
||||
|
||||
Relativizing paths that start with parent directory references only works if
|
||||
the path both start with the same initial parent references.
|
||||
Relativizing paths that start with parent directory references only works if
|
||||
the path both start with the same initial parent references.
|
||||
|
||||
Args:
|
||||
path: The path to relativize.
|
||||
start: The ancestor path against which to relativize.
|
||||
Args:
|
||||
path: The path to relativize.
|
||||
start: The ancestor path against which to relativize.
|
||||
|
||||
Returns:
|
||||
The portion of `path` that is relative to `start`.
|
||||
"""
|
||||
segments = _normalize(path).split("/")
|
||||
start_segments = _normalize(start).split("/")
|
||||
if start_segments == ["."]:
|
||||
start_segments = []
|
||||
start_length = len(start_segments)
|
||||
Returns:
|
||||
The portion of `path` that is relative to `start`.
|
||||
"""
|
||||
segments = _normalize(path).split("/")
|
||||
start_segments = _normalize(start).split("/")
|
||||
if start_segments == ["."]:
|
||||
start_segments = []
|
||||
start_length = len(start_segments)
|
||||
|
||||
if (path.startswith("/") != start.startswith("/") or
|
||||
len(segments) < start_length):
|
||||
fail("Path '%s' is not beneath '%s'" % (path, start))
|
||||
if (path.startswith("/") != start.startswith("/") or
|
||||
len(segments) < start_length):
|
||||
fail("Path '%s' is not beneath '%s'" % (path, start))
|
||||
|
||||
for ancestor_segment, segment in zip(start_segments, segments):
|
||||
if ancestor_segment != segment:
|
||||
fail("Path '%s' is not beneath '%s'" % (path, start))
|
||||
|
||||
length = len(segments) - start_length
|
||||
result_segments = segments[-length:]
|
||||
return "/".join(result_segments)
|
||||
for ancestor_segment, segment in zip(start_segments, segments):
|
||||
if ancestor_segment != segment:
|
||||
fail("Path '%s' is not beneath '%s'" % (path, start))
|
||||
|
||||
length = len(segments) - start_length
|
||||
result_segments = segments[-length:]
|
||||
return "/".join(result_segments)
|
||||
|
||||
def _replace_extension(p, new_extension):
|
||||
"""Replaces the extension of the file at the end of a path.
|
||||
"""Replaces the extension of the file at the end of a path.
|
||||
|
||||
If the path has no extension, the new extension is added to it.
|
||||
If the path has no extension, the new extension is added to it.
|
||||
|
||||
Args:
|
||||
p: The path whose extension should be replaced.
|
||||
new_extension: The new extension for the file. The new extension should
|
||||
begin with a dot if you want the new filename to have one.
|
||||
|
||||
Returns:
|
||||
The path with the extension replaced (or added, if it did not have one).
|
||||
"""
|
||||
return _split_extension(p)[0] + new_extension
|
||||
Args:
|
||||
p: The path whose extension should be replaced.
|
||||
new_extension: The new extension for the file. The new extension should
|
||||
begin with a dot if you want the new filename to have one.
|
||||
|
||||
Returns:
|
||||
The path with the extension replaced (or added, if it did not have one).
|
||||
"""
|
||||
return _split_extension(p)[0] + new_extension
|
||||
|
||||
def _split_extension(p):
|
||||
"""Splits the path `p` into a tuple containing the root and extension.
|
||||
"""Splits the path `p` into a tuple containing the root and extension.
|
||||
|
||||
Leading periods on the basename are ignored, so
|
||||
`path.split_extension(".bashrc")` returns `(".bashrc", "")`.
|
||||
Leading periods on the basename are ignored, so
|
||||
`path.split_extension(".bashrc")` returns `(".bashrc", "")`.
|
||||
|
||||
Args:
|
||||
p: The path whose root and extension should be split.
|
||||
Args:
|
||||
p: The path whose root and extension should be split.
|
||||
|
||||
Returns:
|
||||
A tuple `(root, ext)` such that the root is the path without the file
|
||||
extension, and `ext` is the file extension (which, if non-empty, contains
|
||||
the leading dot). The returned tuple always satisfies the relationship
|
||||
`root + ext == p`.
|
||||
"""
|
||||
b = _basename(p)
|
||||
last_dot_in_basename = b.rfind(".")
|
||||
Returns:
|
||||
A tuple `(root, ext)` such that the root is the path without the file
|
||||
extension, and `ext` is the file extension (which, if non-empty, contains
|
||||
the leading dot). The returned tuple always satisfies the relationship
|
||||
`root + ext == p`.
|
||||
"""
|
||||
b = _basename(p)
|
||||
last_dot_in_basename = b.rfind(".")
|
||||
|
||||
# If there is no dot or the only dot in the basename is at the front, then
|
||||
# there is no extension.
|
||||
if last_dot_in_basename <= 0:
|
||||
return (p, "")
|
||||
|
||||
dot_distance_from_end = len(b) - last_dot_in_basename
|
||||
return (p[:-dot_distance_from_end], p[-dot_distance_from_end:])
|
||||
# If there is no dot or the only dot in the basename is at the front, then
|
||||
# there is no extension.
|
||||
if last_dot_in_basename <= 0:
|
||||
return (p, "")
|
||||
|
||||
dot_distance_from_end = len(b) - last_dot_in_basename
|
||||
return (p[:-dot_distance_from_end], p[-dot_distance_from_end:])
|
||||
|
||||
paths = struct(
|
||||
basename=_basename,
|
||||
dirname=_dirname,
|
||||
is_absolute=_is_absolute,
|
||||
join=_join,
|
||||
normalize=_normalize,
|
||||
relativize=_relativize,
|
||||
replace_extension=_replace_extension,
|
||||
split_extension=_split_extension,
|
||||
basename = _basename,
|
||||
dirname = _dirname,
|
||||
is_absolute = _is_absolute,
|
||||
join = _join,
|
||||
normalize = _normalize,
|
||||
relativize = _relativize,
|
||||
replace_extension = _replace_extension,
|
||||
split_extension = _split_extension,
|
||||
)
|
||||
|
|
102
lib/selects.bzl
102
lib/selects.bzl
|
@ -14,71 +14,69 @@
|
|||
|
||||
"""Skylib module containing convenience interfaces for select()."""
|
||||
|
||||
def _with_or(input_dict, no_match_error=''):
|
||||
"""Drop-in replacement for `select()` that supports ORed keys.
|
||||
def _with_or(input_dict, no_match_error = ""):
|
||||
"""Drop-in replacement for `select()` that supports ORed keys.
|
||||
|
||||
Args:
|
||||
input_dict: The same dictionary `select()` takes, except keys may take
|
||||
either the usual form `"//foo:config1"` or
|
||||
`("//foo:config1", "//foo:config2", ...)` to signify
|
||||
`//foo:config1` OR `//foo:config2` OR `...`.
|
||||
no_match_error: Optional custom error to report if no condition matches.
|
||||
Args:
|
||||
input_dict: The same dictionary `select()` takes, except keys may take
|
||||
either the usual form `"//foo:config1"` or
|
||||
`("//foo:config1", "//foo:config2", ...)` to signify
|
||||
`//foo:config1` OR `//foo:config2` OR `...`.
|
||||
no_match_error: Optional custom error to report if no condition matches.
|
||||
|
||||
Example:
|
||||
Example:
|
||||
|
||||
```build
|
||||
deps = selects.with_or({
|
||||
"//configs:one": [":dep1"],
|
||||
("//configs:two", "//configs:three"): [":dep2or3"],
|
||||
"//configs:four": [":dep4"],
|
||||
"//conditions:default": [":default"]
|
||||
})
|
||||
```
|
||||
```build
|
||||
deps = selects.with_or({
|
||||
"//configs:one": [":dep1"],
|
||||
("//configs:two", "//configs:three"): [":dep2or3"],
|
||||
"//configs:four": [":dep4"],
|
||||
"//conditions:default": [":default"]
|
||||
})
|
||||
```
|
||||
|
||||
Key labels may appear at most once anywhere in the input.
|
||||
Key labels may appear at most once anywhere in the input.
|
||||
|
||||
Returns:
|
||||
A native `select()` that expands
|
||||
Returns:
|
||||
A native `select()` that expands
|
||||
|
||||
`("//configs:two", "//configs:three"): [":dep2or3"]`
|
||||
`("//configs:two", "//configs:three"): [":dep2or3"]`
|
||||
|
||||
to
|
||||
|
||||
```build
|
||||
"//configs:two": [":dep2or3"],
|
||||
"//configs:three": [":dep2or3"],
|
||||
```
|
||||
"""
|
||||
return select(_with_or_dict(input_dict), no_match_error=no_match_error)
|
||||
to
|
||||
|
||||
```build
|
||||
"//configs:two": [":dep2or3"],
|
||||
"//configs:three": [":dep2or3"],
|
||||
```
|
||||
"""
|
||||
return select(_with_or_dict(input_dict), no_match_error = no_match_error)
|
||||
|
||||
def _with_or_dict(input_dict):
|
||||
"""Variation of `with_or` that returns the dict of the `select()`.
|
||||
"""Variation of `with_or` that returns the dict of the `select()`.
|
||||
|
||||
Unlike `select()`, the contents of the dict can be inspected by Skylark
|
||||
macros.
|
||||
Unlike `select()`, the contents of the dict can be inspected by Skylark
|
||||
macros.
|
||||
|
||||
Args:
|
||||
input_dict: Same as `with_or`.
|
||||
|
||||
Returns:
|
||||
A dictionary usable by a native `select()`.
|
||||
"""
|
||||
output_dict = {}
|
||||
for (key, value) in input_dict.items():
|
||||
if type(key) == type(()):
|
||||
for config_setting in key:
|
||||
if config_setting in output_dict.keys():
|
||||
fail("key %s appears multiple times" % config_setting)
|
||||
output_dict[config_setting] = value
|
||||
else:
|
||||
if key in output_dict.keys():
|
||||
fail("key %s appears multiple times" % key)
|
||||
output_dict[key] = value
|
||||
return output_dict
|
||||
Args:
|
||||
input_dict: Same as `with_or`.
|
||||
|
||||
Returns:
|
||||
A dictionary usable by a native `select()`.
|
||||
"""
|
||||
output_dict = {}
|
||||
for (key, value) in input_dict.items():
|
||||
if type(key) == type(()):
|
||||
for config_setting in key:
|
||||
if config_setting in output_dict.keys():
|
||||
fail("key %s appears multiple times" % config_setting)
|
||||
output_dict[config_setting] = value
|
||||
else:
|
||||
if key in output_dict.keys():
|
||||
fail("key %s appears multiple times" % key)
|
||||
output_dict[key] = value
|
||||
return output_dict
|
||||
|
||||
selects = struct(
|
||||
with_or=_with_or,
|
||||
with_or_dict=_with_or_dict
|
||||
with_or = _with_or,
|
||||
with_or_dict = _with_or_dict,
|
||||
)
|
||||
|
|
150
lib/sets.bzl
150
lib/sets.bzl
|
@ -26,113 +26,105 @@ duplicate elements are ignored). Functions that return new sets always return
|
|||
them as the `set` type, regardless of the types of the inputs.
|
||||
"""
|
||||
|
||||
|
||||
def _precondition_only_sets_or_lists(*args):
|
||||
"""Verifies that all arguments are either sets or lists.
|
||||
"""Verifies that all arguments are either sets or lists.
|
||||
|
||||
The build will fail if any of the arguments is neither a set nor a list.
|
||||
|
||||
Args:
|
||||
*args: A list of values that must be sets or lists.
|
||||
"""
|
||||
for a in args:
|
||||
t = type(a)
|
||||
if t not in("depset", "list"):
|
||||
fail("Expected arguments to be depset or list, but found type %s: %r" %
|
||||
(t, a))
|
||||
The build will fail if any of the arguments is neither a set nor a list.
|
||||
|
||||
Args:
|
||||
*args: A list of values that must be sets or lists.
|
||||
"""
|
||||
for a in args:
|
||||
t = type(a)
|
||||
if t not in ("depset", "list"):
|
||||
fail("Expected arguments to be depset or list, but found type %s: %r" %
|
||||
(t, a))
|
||||
|
||||
def _is_equal(a, b):
|
||||
"""Returns whether two sets are equal.
|
||||
"""Returns whether two sets are equal.
|
||||
|
||||
Args:
|
||||
a: A depset or a list.
|
||||
b: A depset or a list.
|
||||
|
||||
Returns:
|
||||
True if `a` is equal to `b`, False otherwise.
|
||||
"""
|
||||
_precondition_only_sets_or_lists(a, b)
|
||||
return sorted(depset(a)) == sorted(depset(b))
|
||||
Args:
|
||||
a: A depset or a list.
|
||||
b: A depset or a list.
|
||||
|
||||
Returns:
|
||||
True if `a` is equal to `b`, False otherwise.
|
||||
"""
|
||||
_precondition_only_sets_or_lists(a, b)
|
||||
return sorted(depset(a)) == sorted(depset(b))
|
||||
|
||||
def _is_subset(a, b):
|
||||
"""Returns whether `a` is a subset of `b`.
|
||||
"""Returns whether `a` is a subset of `b`.
|
||||
|
||||
Args:
|
||||
a: A depset or a list.
|
||||
b: A depset or a list.
|
||||
|
||||
Returns:
|
||||
True if `a` is a subset of `b`, False otherwise.
|
||||
"""
|
||||
_precondition_only_sets_or_lists(a, b)
|
||||
for e in a:
|
||||
if e not in b:
|
||||
return False
|
||||
return True
|
||||
Args:
|
||||
a: A depset or a list.
|
||||
b: A depset or a list.
|
||||
|
||||
Returns:
|
||||
True if `a` is a subset of `b`, False otherwise.
|
||||
"""
|
||||
_precondition_only_sets_or_lists(a, b)
|
||||
for e in a:
|
||||
if e not in b:
|
||||
return False
|
||||
return True
|
||||
|
||||
def _disjoint(a, b):
|
||||
"""Returns whether two sets are disjoint.
|
||||
"""Returns whether two sets are disjoint.
|
||||
|
||||
Two sets are disjoint if they have no elements in common.
|
||||
Two sets are disjoint if they have no elements in common.
|
||||
|
||||
Args:
|
||||
a: A set or list.
|
||||
b: A set or list.
|
||||
|
||||
Returns:
|
||||
True if `a` and `b` are disjoint, False otherwise.
|
||||
"""
|
||||
_precondition_only_sets_or_lists(a, b)
|
||||
for e in a:
|
||||
if e in b:
|
||||
return False
|
||||
return True
|
||||
Args:
|
||||
a: A set or list.
|
||||
b: A set or list.
|
||||
|
||||
Returns:
|
||||
True if `a` and `b` are disjoint, False otherwise.
|
||||
"""
|
||||
_precondition_only_sets_or_lists(a, b)
|
||||
for e in a:
|
||||
if e in b:
|
||||
return False
|
||||
return True
|
||||
|
||||
def _intersection(a, b):
|
||||
"""Returns the intersection of two sets.
|
||||
"""Returns the intersection of two sets.
|
||||
|
||||
Args:
|
||||
a: A set or list.
|
||||
b: A set or list.
|
||||
|
||||
Returns:
|
||||
A set containing the elements that are in both `a` and `b`.
|
||||
"""
|
||||
_precondition_only_sets_or_lists(a, b)
|
||||
return depset([e for e in a if e in b])
|
||||
Args:
|
||||
a: A set or list.
|
||||
b: A set or list.
|
||||
|
||||
Returns:
|
||||
A set containing the elements that are in both `a` and `b`.
|
||||
"""
|
||||
_precondition_only_sets_or_lists(a, b)
|
||||
return depset([e for e in a if e in b])
|
||||
|
||||
def _union(*args):
|
||||
"""Returns the union of several sets.
|
||||
"""Returns the union of several sets.
|
||||
|
||||
Args:
|
||||
*args: An arbitrary number of sets or lists.
|
||||
|
||||
Returns:
|
||||
The set union of all sets or lists in `*args`.
|
||||
"""
|
||||
_precondition_only_sets_or_lists(*args)
|
||||
args_deps = [depset(x) if type(x) == type([]) else x for x in args]
|
||||
return depset(transitive=args_deps)
|
||||
Args:
|
||||
*args: An arbitrary number of sets or lists.
|
||||
|
||||
Returns:
|
||||
The set union of all sets or lists in `*args`.
|
||||
"""
|
||||
_precondition_only_sets_or_lists(*args)
|
||||
args_deps = [depset(x) if type(x) == type([]) else x for x in args]
|
||||
return depset(transitive = args_deps)
|
||||
|
||||
def _difference(a, b):
|
||||
"""Returns the elements in `a` that are not in `b`.
|
||||
"""Returns the elements in `a` that are not in `b`.
|
||||
|
||||
Args:
|
||||
a: A set or list.
|
||||
b: A set or list.
|
||||
|
||||
Returns:
|
||||
A set containing the elements that are in `a` but not in `b`.
|
||||
"""
|
||||
_precondition_only_sets_or_lists(a, b)
|
||||
return depset([e for e in a if e not in b])
|
||||
Args:
|
||||
a: A set or list.
|
||||
b: A set or list.
|
||||
|
||||
Returns:
|
||||
A set containing the elements that are in `a` but not in `b`.
|
||||
"""
|
||||
_precondition_only_sets_or_lists(a, b)
|
||||
return depset([e for e in a if e not in b])
|
||||
|
||||
sets = struct(
|
||||
difference = _difference,
|
||||
|
|
|
@ -14,44 +14,41 @@
|
|||
|
||||
"""Skylib module containing shell utility functions."""
|
||||
|
||||
|
||||
def _array_literal(iterable):
|
||||
"""Creates a string from a sequence that can be used as a shell array.
|
||||
"""Creates a string from a sequence that can be used as a shell array.
|
||||
|
||||
For example, `shell.array_literal(["a", "b", "c"])` would return the string
|
||||
`("a" "b" "c")`, which can be used in a shell script wherever an array
|
||||
literal is needed.
|
||||
For example, `shell.array_literal(["a", "b", "c"])` would return the string
|
||||
`("a" "b" "c")`, which can be used in a shell script wherever an array
|
||||
literal is needed.
|
||||
|
||||
Note that all elements in the array are quoted (using `shell.quote`) for
|
||||
safety, even if they do not need to be.
|
||||
Note that all elements in the array are quoted (using `shell.quote`) for
|
||||
safety, even if they do not need to be.
|
||||
|
||||
Args:
|
||||
iterable: A sequence of elements. Elements that are not strings will be
|
||||
converted to strings first, by calling `str()`.
|
||||
|
||||
Returns:
|
||||
A string that represents the sequence as a shell array; that is,
|
||||
parentheses containing the quoted elements.
|
||||
"""
|
||||
return "(" + " ".join([_quote(str(i)) for i in iterable]) + ")"
|
||||
Args:
|
||||
iterable: A sequence of elements. Elements that are not strings will be
|
||||
converted to strings first, by calling `str()`.
|
||||
|
||||
Returns:
|
||||
A string that represents the sequence as a shell array; that is,
|
||||
parentheses containing the quoted elements.
|
||||
"""
|
||||
return "(" + " ".join([_quote(str(i)) for i in iterable]) + ")"
|
||||
|
||||
def _quote(s):
|
||||
"""Quotes the given string for use in a shell command.
|
||||
"""Quotes the given string for use in a shell command.
|
||||
|
||||
This function quotes the given string (in case it contains spaces or other
|
||||
shell metacharacters.)
|
||||
This function quotes the given string (in case it contains spaces or other
|
||||
shell metacharacters.)
|
||||
|
||||
Args:
|
||||
s: The string to quote.
|
||||
|
||||
Returns:
|
||||
A quoted version of the string that can be passed to a shell command.
|
||||
"""
|
||||
return "'" + s.replace("'", "'\\''") + "'"
|
||||
Args:
|
||||
s: The string to quote.
|
||||
|
||||
Returns:
|
||||
A quoted version of the string that can be passed to a shell command.
|
||||
"""
|
||||
return "'" + s.replace("'", "'\\''") + "'"
|
||||
|
||||
shell = struct(
|
||||
array_literal=_array_literal,
|
||||
quote=_quote,
|
||||
array_literal = _array_literal,
|
||||
quote = _quote,
|
||||
)
|
||||
|
|
|
@ -14,24 +14,22 @@
|
|||
|
||||
"""Skylib module containing functions that operate on structs."""
|
||||
|
||||
|
||||
def _to_dict(s):
|
||||
"""Converts a `struct` to a `dict`.
|
||||
"""Converts a `struct` to a `dict`.
|
||||
|
||||
Args:
|
||||
s: A `struct`.
|
||||
|
||||
Returns:
|
||||
A `dict` whose keys and values are the same as the fields in `s`. The
|
||||
transformation is only applied to the struct's fields and not to any
|
||||
nested values.
|
||||
"""
|
||||
attributes = dir(s)
|
||||
attributes.remove("to_json")
|
||||
attributes.remove("to_proto")
|
||||
return {key: getattr(s, key) for key in attributes}
|
||||
Args:
|
||||
s: A `struct`.
|
||||
|
||||
Returns:
|
||||
A `dict` whose keys and values are the same as the fields in `s`. The
|
||||
transformation is only applied to the struct's fields and not to any
|
||||
nested values.
|
||||
"""
|
||||
attributes = dir(s)
|
||||
attributes.remove("to_json")
|
||||
attributes.remove("to_proto")
|
||||
return {key: getattr(s, key) for key in attributes}
|
||||
|
||||
structs = struct(
|
||||
to_dict=_to_dict,
|
||||
to_dict = _to_dict,
|
||||
)
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
# limitations under the License.
|
||||
"""Skylib module containing functions checking types."""
|
||||
|
||||
|
||||
# create instance singletons to avoid unnecessary allocations
|
||||
_a_bool = True
|
||||
_a_dict = {}
|
||||
|
@ -22,10 +21,8 @@ _a_string = ""
|
|||
_a_tuple = ()
|
||||
_an_int = 1
|
||||
|
||||
|
||||
def _a_function():
|
||||
pass
|
||||
|
||||
pass
|
||||
|
||||
def _is_list(v):
|
||||
"""Returns True if v is an instance of a list.
|
||||
|
@ -38,7 +35,6 @@ def _is_list(v):
|
|||
"""
|
||||
return type(v) == type(_a_list)
|
||||
|
||||
|
||||
def _is_string(v):
|
||||
"""Returns True if v is an instance of a string.
|
||||
|
||||
|
@ -50,7 +46,6 @@ def _is_string(v):
|
|||
"""
|
||||
return type(v) == type(_a_string)
|
||||
|
||||
|
||||
def _is_bool(v):
|
||||
"""Returns True if v is an instance of a bool.
|
||||
|
||||
|
@ -62,7 +57,6 @@ def _is_bool(v):
|
|||
"""
|
||||
return type(v) == type(_a_bool)
|
||||
|
||||
|
||||
def _is_none(v):
|
||||
"""Returns True if v has the type of None.
|
||||
|
||||
|
@ -74,7 +68,6 @@ def _is_none(v):
|
|||
"""
|
||||
return type(v) == type(None)
|
||||
|
||||
|
||||
def _is_int(v):
|
||||
"""Returns True if v is an instance of a signed integer.
|
||||
|
||||
|
@ -86,7 +79,6 @@ def _is_int(v):
|
|||
"""
|
||||
return type(v) == type(_an_int)
|
||||
|
||||
|
||||
def _is_tuple(v):
|
||||
"""Returns True if v is an instance of a tuple.
|
||||
|
||||
|
@ -98,7 +90,6 @@ def _is_tuple(v):
|
|||
"""
|
||||
return type(v) == type(_a_tuple)
|
||||
|
||||
|
||||
def _is_dict(v):
|
||||
"""Returns True if v is an instance of a dict.
|
||||
|
||||
|
@ -110,7 +101,6 @@ def _is_dict(v):
|
|||
"""
|
||||
return type(v) == type(_a_dict)
|
||||
|
||||
|
||||
def _is_function(v):
|
||||
"""Returns True if v is an instance of a function.
|
||||
|
||||
|
@ -122,14 +112,13 @@ def _is_function(v):
|
|||
"""
|
||||
return type(v) == type(_a_function)
|
||||
|
||||
|
||||
types = struct(
|
||||
is_list=_is_list,
|
||||
is_string=_is_string,
|
||||
is_bool=_is_bool,
|
||||
is_none=_is_none,
|
||||
is_int=_is_int,
|
||||
is_tuple=_is_tuple,
|
||||
is_dict=_is_dict,
|
||||
is_function=_is_function,
|
||||
is_list = _is_list,
|
||||
is_string = _is_string,
|
||||
is_bool = _is_bool,
|
||||
is_none = _is_none,
|
||||
is_int = _is_int,
|
||||
is_tuple = _is_tuple,
|
||||
is_dict = _is_dict,
|
||||
is_function = _is_function,
|
||||
)
|
||||
|
|
433
lib/unittest.bzl
433
lib/unittest.bzl
|
@ -20,272 +20,265 @@ assertions used to within tests.
|
|||
"""
|
||||
|
||||
load(":sets.bzl", "sets")
|
||||
load(":new_sets.bzl", new_sets="sets")
|
||||
load(":new_sets.bzl", new_sets = "sets")
|
||||
|
||||
def _make(impl, attrs = None):
|
||||
"""Creates a unit test rule from its implementation function.
|
||||
|
||||
def _make(impl, attrs=None):
|
||||
"""Creates a unit test rule from its implementation function.
|
||||
Each unit test is defined in an implementation function that must then be
|
||||
associated with a rule so that a target can be built. This function handles
|
||||
the boilerplate to create and return a test rule and captures the
|
||||
implementation function's name so that it can be printed in test feedback.
|
||||
|
||||
Each unit test is defined in an implementation function that must then be
|
||||
associated with a rule so that a target can be built. This function handles
|
||||
the boilerplate to create and return a test rule and captures the
|
||||
implementation function's name so that it can be printed in test feedback.
|
||||
The optional `attrs` argument can be used to define dependencies for this
|
||||
test, in order to form unit tests of rules.
|
||||
|
||||
The optional `attrs` argument can be used to define dependencies for this
|
||||
test, in order to form unit tests of rules.
|
||||
An example of a unit test:
|
||||
|
||||
An example of a unit test:
|
||||
```
|
||||
def _your_test(ctx):
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
```
|
||||
def _your_test(ctx):
|
||||
env = unittest.begin(ctx)
|
||||
# Assert statements go here
|
||||
|
||||
# Assert statements go here
|
||||
unittest.end(env)
|
||||
|
||||
unittest.end(env)
|
||||
your_test = unittest.make(_your_test)
|
||||
```
|
||||
|
||||
your_test = unittest.make(_your_test)
|
||||
```
|
||||
Recall that names of test rules must end in `_test`.
|
||||
|
||||
Recall that names of test rules must end in `_test`.
|
||||
Args:
|
||||
impl: The implementation function of the unit test.
|
||||
attrs: An optional dictionary to supplement the attrs passed to the
|
||||
unit test's `rule()` constructor.
|
||||
|
||||
Args:
|
||||
impl: The implementation function of the unit test.
|
||||
attrs: An optional dictionary to supplement the attrs passed to the
|
||||
unit test's `rule()` constructor.
|
||||
Returns:
|
||||
A rule definition that should be stored in a global whose name ends in
|
||||
`_test`.
|
||||
"""
|
||||
|
||||
Returns:
|
||||
A rule definition that should be stored in a global whose name ends in
|
||||
`_test`.
|
||||
"""
|
||||
# Derive the name of the implementation function for better test feedback.
|
||||
# Skylark currently stringifies a function as "<function NAME>", so we use
|
||||
# that knowledge to parse the "NAME" portion out. If this behavior ever
|
||||
# changes, we'll need to update this.
|
||||
# TODO(bazel-team): Expose a ._name field on functions to avoid this.
|
||||
impl_name = str(impl)
|
||||
impl_name = impl_name.partition("<function ")[-1]
|
||||
impl_name = impl_name.rpartition(">")[0]
|
||||
|
||||
# Derive the name of the implementation function for better test feedback.
|
||||
# Skylark currently stringifies a function as "<function NAME>", so we use
|
||||
# that knowledge to parse the "NAME" portion out. If this behavior ever
|
||||
# changes, we'll need to update this.
|
||||
# TODO(bazel-team): Expose a ._name field on functions to avoid this.
|
||||
impl_name = str(impl)
|
||||
impl_name = impl_name.partition("<function ")[-1]
|
||||
impl_name = impl_name.rpartition(">")[0]
|
||||
|
||||
attrs = dict(attrs) if attrs else {}
|
||||
attrs["_impl_name"] = attr.string(default=impl_name)
|
||||
|
||||
return rule(
|
||||
impl,
|
||||
attrs=attrs,
|
||||
_skylark_testable=True,
|
||||
test=True,
|
||||
)
|
||||
attrs = dict(attrs) if attrs else {}
|
||||
attrs["_impl_name"] = attr.string(default = impl_name)
|
||||
|
||||
return rule(
|
||||
impl,
|
||||
attrs = attrs,
|
||||
_skylark_testable = True,
|
||||
test = True,
|
||||
)
|
||||
|
||||
def _suite(name, *test_rules):
|
||||
"""Defines a `test_suite` target that contains multiple tests.
|
||||
"""Defines a `test_suite` target that contains multiple tests.
|
||||
|
||||
After defining your test rules in a `.bzl` file, you need to create targets
|
||||
from those rules so that `blaze test` can execute them. Doing this manually
|
||||
in a BUILD file would consist of listing each test in your `load` statement
|
||||
and then creating each target one by one. To reduce duplication, we recommend
|
||||
writing a macro in your `.bzl` file to instantiate all targets, and calling
|
||||
that macro from your BUILD file so you only have to load one symbol.
|
||||
After defining your test rules in a `.bzl` file, you need to create targets
|
||||
from those rules so that `blaze test` can execute them. Doing this manually
|
||||
in a BUILD file would consist of listing each test in your `load` statement
|
||||
and then creating each target one by one. To reduce duplication, we recommend
|
||||
writing a macro in your `.bzl` file to instantiate all targets, and calling
|
||||
that macro from your BUILD file so you only have to load one symbol.
|
||||
|
||||
For the case where your unit tests do not take any (non-default) attributes --
|
||||
i.e., if your unit tests do not test rules -- you can use this function to
|
||||
create the targets and wrap them in a single test_suite target. In your
|
||||
`.bzl` file, write:
|
||||
For the case where your unit tests do not take any (non-default) attributes --
|
||||
i.e., if your unit tests do not test rules -- you can use this function to
|
||||
create the targets and wrap them in a single test_suite target. In your
|
||||
`.bzl` file, write:
|
||||
|
||||
```
|
||||
def your_test_suite():
|
||||
unittest.suite(
|
||||
"your_test_suite",
|
||||
your_test,
|
||||
your_other_test,
|
||||
yet_another_test,
|
||||
```
|
||||
def your_test_suite():
|
||||
unittest.suite(
|
||||
"your_test_suite",
|
||||
your_test,
|
||||
your_other_test,
|
||||
yet_another_test,
|
||||
)
|
||||
```
|
||||
|
||||
Then, in your `BUILD` file, simply load the macro and invoke it to have all
|
||||
of the targets created:
|
||||
|
||||
```
|
||||
load("//path/to/your/package:tests.bzl", "your_test_suite")
|
||||
your_test_suite()
|
||||
```
|
||||
|
||||
If you pass _N_ unit test rules to `unittest.suite`, _N_ + 1 targets will be
|
||||
created: a `test_suite` target named `${name}` (where `${name}` is the name
|
||||
argument passed in here) and targets named `${name}_test_${i}`, where `${i}`
|
||||
is the index of the test in the `test_rules` list, which is used to uniquely
|
||||
name each target.
|
||||
|
||||
Args:
|
||||
name: The name of the `test_suite` target, and the prefix of all the test
|
||||
target names.
|
||||
*test_rules: A list of test rules defines by `unittest.test`.
|
||||
"""
|
||||
test_names = []
|
||||
for index, test_rule in enumerate(test_rules):
|
||||
test_name = "%s_test_%d" % (name, index)
|
||||
test_rule(name = test_name)
|
||||
test_names.append(test_name)
|
||||
|
||||
native.test_suite(
|
||||
name = name,
|
||||
tests = [":%s" % t for t in test_names],
|
||||
)
|
||||
```
|
||||
|
||||
Then, in your `BUILD` file, simply load the macro and invoke it to have all
|
||||
of the targets created:
|
||||
|
||||
```
|
||||
load("//path/to/your/package:tests.bzl", "your_test_suite")
|
||||
your_test_suite()
|
||||
```
|
||||
|
||||
If you pass _N_ unit test rules to `unittest.suite`, _N_ + 1 targets will be
|
||||
created: a `test_suite` target named `${name}` (where `${name}` is the name
|
||||
argument passed in here) and targets named `${name}_test_${i}`, where `${i}`
|
||||
is the index of the test in the `test_rules` list, which is used to uniquely
|
||||
name each target.
|
||||
|
||||
Args:
|
||||
name: The name of the `test_suite` target, and the prefix of all the test
|
||||
target names.
|
||||
*test_rules: A list of test rules defines by `unittest.test`.
|
||||
"""
|
||||
test_names = []
|
||||
for index, test_rule in enumerate(test_rules):
|
||||
test_name = "%s_test_%d" % (name, index)
|
||||
test_rule(name=test_name)
|
||||
test_names.append(test_name)
|
||||
|
||||
native.test_suite(
|
||||
name=name,
|
||||
tests=[":%s" % t for t in test_names]
|
||||
)
|
||||
|
||||
|
||||
def _begin(ctx):
|
||||
"""Begins a unit test.
|
||||
"""Begins a unit test.
|
||||
|
||||
This should be the first function called in a unit test implementation
|
||||
function. It initializes a "test environment" that is used to collect
|
||||
assertion failures so that they can be reported and logged at the end of the
|
||||
test.
|
||||
This should be the first function called in a unit test implementation
|
||||
function. It initializes a "test environment" that is used to collect
|
||||
assertion failures so that they can be reported and logged at the end of the
|
||||
test.
|
||||
|
||||
Args:
|
||||
ctx: The Skylark context. Pass the implementation function's `ctx` argument
|
||||
in verbatim.
|
||||
|
||||
Returns:
|
||||
A test environment struct that must be passed to assertions and finally to
|
||||
`unittest.end`. Do not rely on internal details about the fields in this
|
||||
struct as it may change.
|
||||
"""
|
||||
return struct(ctx=ctx, failures=[])
|
||||
Args:
|
||||
ctx: The Skylark context. Pass the implementation function's `ctx` argument
|
||||
in verbatim.
|
||||
|
||||
Returns:
|
||||
A test environment struct that must be passed to assertions and finally to
|
||||
`unittest.end`. Do not rely on internal details about the fields in this
|
||||
struct as it may change.
|
||||
"""
|
||||
return struct(ctx = ctx, failures = [])
|
||||
|
||||
def _end(env):
|
||||
"""Ends a unit test and logs the results.
|
||||
"""Ends a unit test and logs the results.
|
||||
|
||||
This must be called before the end of a unit test implementation function so
|
||||
that the results are reported.
|
||||
|
||||
Args:
|
||||
env: The test environment returned by `unittest.begin`.
|
||||
"""
|
||||
cmd = "\n".join([
|
||||
"cat << EOF",
|
||||
"\n".join(env.failures),
|
||||
"EOF",
|
||||
"exit %d" % len(env.failures),
|
||||
])
|
||||
env.ctx.file_action(
|
||||
output=env.ctx.outputs.executable,
|
||||
content=cmd,
|
||||
executable=True,
|
||||
)
|
||||
This must be called before the end of a unit test implementation function so
|
||||
that the results are reported.
|
||||
|
||||
Args:
|
||||
env: The test environment returned by `unittest.begin`.
|
||||
"""
|
||||
cmd = "\n".join([
|
||||
"cat << EOF",
|
||||
"\n".join(env.failures),
|
||||
"EOF",
|
||||
"exit %d" % len(env.failures),
|
||||
])
|
||||
env.ctx.file_action(
|
||||
output = env.ctx.outputs.executable,
|
||||
content = cmd,
|
||||
executable = True,
|
||||
)
|
||||
|
||||
def _fail(env, msg):
|
||||
"""Unconditionally causes the current test to fail.
|
||||
"""Unconditionally causes the current test to fail.
|
||||
|
||||
Args:
|
||||
env: The test environment returned by `unittest.begin`.
|
||||
msg: The message to log describing the failure.
|
||||
"""
|
||||
full_msg = "In test %s: %s" % (env.ctx.attr._impl_name, msg)
|
||||
print(full_msg)
|
||||
env.failures.append(full_msg)
|
||||
Args:
|
||||
env: The test environment returned by `unittest.begin`.
|
||||
msg: The message to log describing the failure.
|
||||
"""
|
||||
full_msg = "In test %s: %s" % (env.ctx.attr._impl_name, msg)
|
||||
print(full_msg)
|
||||
env.failures.append(full_msg)
|
||||
|
||||
def _assert_true(
|
||||
env,
|
||||
condition,
|
||||
msg = "Expected condition to be true, but was false."):
|
||||
"""Asserts that the given `condition` is true.
|
||||
|
||||
def _assert_true(env,
|
||||
condition,
|
||||
msg="Expected condition to be true, but was false."):
|
||||
"""Asserts that the given `condition` is true.
|
||||
Args:
|
||||
env: The test environment returned by `unittest.begin`.
|
||||
condition: A value that will be evaluated in a Boolean context.
|
||||
msg: An optional message that will be printed that describes the failure.
|
||||
If omitted, a default will be used.
|
||||
"""
|
||||
if not condition:
|
||||
_fail(env, msg)
|
||||
|
||||
Args:
|
||||
env: The test environment returned by `unittest.begin`.
|
||||
condition: A value that will be evaluated in a Boolean context.
|
||||
msg: An optional message that will be printed that describes the failure.
|
||||
If omitted, a default will be used.
|
||||
"""
|
||||
if not condition:
|
||||
_fail(env, msg)
|
||||
def _assert_false(
|
||||
env,
|
||||
condition,
|
||||
msg = "Expected condition to be false, but was true."):
|
||||
"""Asserts that the given `condition` is false.
|
||||
|
||||
Args:
|
||||
env: The test environment returned by `unittest.begin`.
|
||||
condition: A value that will be evaluated in a Boolean context.
|
||||
msg: An optional message that will be printed that describes the failure.
|
||||
If omitted, a default will be used.
|
||||
"""
|
||||
if condition:
|
||||
_fail(env, msg)
|
||||
|
||||
def _assert_false(env,
|
||||
condition,
|
||||
msg="Expected condition to be false, but was true."):
|
||||
"""Asserts that the given `condition` is false.
|
||||
def _assert_equals(env, expected, actual, msg = None):
|
||||
"""Asserts that the given `expected` and `actual` values are equal.
|
||||
|
||||
Args:
|
||||
env: The test environment returned by `unittest.begin`.
|
||||
condition: A value that will be evaluated in a Boolean context.
|
||||
msg: An optional message that will be printed that describes the failure.
|
||||
If omitted, a default will be used.
|
||||
"""
|
||||
if condition:
|
||||
_fail(env, msg)
|
||||
Args:
|
||||
env: The test environment returned by `unittest.begin`.
|
||||
expected: The expected value of some computation.
|
||||
actual: The actual value returned by some computation.
|
||||
msg: An optional message that will be printed that describes the failure.
|
||||
If omitted, a default will be used.
|
||||
"""
|
||||
if expected != actual:
|
||||
expectation_msg = 'Expected "%s", but got "%s"' % (expected, actual)
|
||||
if msg:
|
||||
full_msg = "%s (%s)" % (msg, expectation_msg)
|
||||
else:
|
||||
full_msg = expectation_msg
|
||||
_fail(env, full_msg)
|
||||
|
||||
def _assert_set_equals(env, expected, actual, msg = None):
|
||||
"""Asserts that the given `expected` and `actual` sets are equal.
|
||||
|
||||
def _assert_equals(env, expected, actual, msg=None):
|
||||
"""Asserts that the given `expected` and `actual` values are equal.
|
||||
Args:
|
||||
env: The test environment returned by `unittest.begin`.
|
||||
expected: The expected set resulting from some computation.
|
||||
actual: The actual set returned by some computation.
|
||||
msg: An optional message that will be printed that describes the failure.
|
||||
If omitted, a default will be used.
|
||||
"""
|
||||
if type(actual) != type(depset()) or not sets.is_equal(expected, actual):
|
||||
expectation_msg = "Expected %r, but got %r" % (expected, actual)
|
||||
if msg:
|
||||
full_msg = "%s (%s)" % (msg, expectation_msg)
|
||||
else:
|
||||
full_msg = expectation_msg
|
||||
_fail(env, full_msg)
|
||||
|
||||
Args:
|
||||
env: The test environment returned by `unittest.begin`.
|
||||
expected: The expected value of some computation.
|
||||
actual: The actual value returned by some computation.
|
||||
msg: An optional message that will be printed that describes the failure.
|
||||
If omitted, a default will be used.
|
||||
"""
|
||||
if expected != actual:
|
||||
expectation_msg = 'Expected "%s", but got "%s"' % (expected, actual)
|
||||
if msg:
|
||||
full_msg = "%s (%s)" % (msg, expectation_msg)
|
||||
else:
|
||||
full_msg = expectation_msg
|
||||
_fail(env, full_msg)
|
||||
def _assert_new_set_equals(env, expected, actual, msg = None):
|
||||
"""Asserts that the given `expected` and `actual` sets are equal.
|
||||
|
||||
|
||||
def _assert_set_equals(env, expected, actual, msg=None):
|
||||
"""Asserts that the given `expected` and `actual` sets are equal.
|
||||
|
||||
Args:
|
||||
env: The test environment returned by `unittest.begin`.
|
||||
expected: The expected set resulting from some computation.
|
||||
actual: The actual set returned by some computation.
|
||||
msg: An optional message that will be printed that describes the failure.
|
||||
If omitted, a default will be used.
|
||||
"""
|
||||
if type(actual) != type(depset()) or not sets.is_equal(expected, actual):
|
||||
expectation_msg = "Expected %r, but got %r" % (expected, actual)
|
||||
if msg:
|
||||
full_msg = "%s (%s)" % (msg, expectation_msg)
|
||||
else:
|
||||
full_msg = expectation_msg
|
||||
_fail(env, full_msg)
|
||||
|
||||
def _assert_new_set_equals(env, expected, actual, msg=None):
|
||||
"""Asserts that the given `expected` and `actual` sets are equal.
|
||||
|
||||
Args:
|
||||
env: The test environment returned by `unittest.begin`.
|
||||
expected: The expected set resulting from some computation.
|
||||
actual: The actual set returned by some computation.
|
||||
msg: An optional message that will be printed that describes the failure.
|
||||
If omitted, a default will be used.
|
||||
"""
|
||||
if not new_sets.is_equal(expected, actual):
|
||||
expectation_msg = "Expected %r, but got %r" % (expected, actual)
|
||||
if msg:
|
||||
full_msg = "%s (%s)" % (msg, expectation_msg)
|
||||
else:
|
||||
full_msg = expectation_msg
|
||||
_fail(env, full_msg)
|
||||
Args:
|
||||
env: The test environment returned by `unittest.begin`.
|
||||
expected: The expected set resulting from some computation.
|
||||
actual: The actual set returned by some computation.
|
||||
msg: An optional message that will be printed that describes the failure.
|
||||
If omitted, a default will be used.
|
||||
"""
|
||||
if not new_sets.is_equal(expected, actual):
|
||||
expectation_msg = "Expected %r, but got %r" % (expected, actual)
|
||||
if msg:
|
||||
full_msg = "%s (%s)" % (msg, expectation_msg)
|
||||
else:
|
||||
full_msg = expectation_msg
|
||||
_fail(env, full_msg)
|
||||
|
||||
asserts = struct(
|
||||
equals=_assert_equals,
|
||||
false=_assert_false,
|
||||
set_equals=_assert_set_equals,
|
||||
equals = _assert_equals,
|
||||
false = _assert_false,
|
||||
set_equals = _assert_set_equals,
|
||||
new_set_equals = _assert_new_set_equals,
|
||||
true=_assert_true,
|
||||
true = _assert_true,
|
||||
)
|
||||
|
||||
unittest = struct(
|
||||
make=_make,
|
||||
suite=_suite,
|
||||
begin=_begin,
|
||||
end=_end,
|
||||
fail=_fail,
|
||||
make = _make,
|
||||
suite = _suite,
|
||||
begin = _begin,
|
||||
end = _end,
|
||||
fail = _fail,
|
||||
)
|
||||
|
|
154
lib/versions.bzl
154
lib/versions.bzl
|
@ -15,111 +15,113 @@
|
|||
"""Skylib module containing functions for checking Bazel versions."""
|
||||
|
||||
def _get_bazel_version():
|
||||
"""Returns the current Bazel version"""
|
||||
|
||||
return native.bazel_version
|
||||
"""Returns the current Bazel version"""
|
||||
|
||||
return native.bazel_version
|
||||
|
||||
def _extract_version_number(bazel_version):
|
||||
"""Extracts the semantic version number from a version string
|
||||
"""Extracts the semantic version number from a version string
|
||||
|
||||
Args:
|
||||
bazel_version: the version string that begins with the semantic version
|
||||
e.g. "1.2.3rc1 abc1234" where "abc1234" is a commit hash.
|
||||
Args:
|
||||
bazel_version: the version string that begins with the semantic version
|
||||
e.g. "1.2.3rc1 abc1234" where "abc1234" is a commit hash.
|
||||
|
||||
Returns:
|
||||
The semantic version string, like "1.2.3".
|
||||
"""
|
||||
for i in range(len(bazel_version)):
|
||||
c = bazel_version[i]
|
||||
if not (c.isdigit() or c == "."):
|
||||
return bazel_version[:i]
|
||||
return bazel_version
|
||||
Returns:
|
||||
The semantic version string, like "1.2.3".
|
||||
"""
|
||||
for i in range(len(bazel_version)):
|
||||
c = bazel_version[i]
|
||||
if not (c.isdigit() or c == "."):
|
||||
return bazel_version[:i]
|
||||
return bazel_version
|
||||
|
||||
# Parse the bazel version string from `native.bazel_version`.
|
||||
# e.g.
|
||||
# "0.10.0rc1 abc123d" => (0, 10, 0)
|
||||
# "0.3.0" => (0, 3, 0)
|
||||
def _parse_bazel_version(bazel_version):
|
||||
"""Parses a version string into a 3-tuple of ints
|
||||
"""Parses a version string into a 3-tuple of ints
|
||||
|
||||
int tuples can be compared directly using binary operators (<, >).
|
||||
int tuples can be compared directly using binary operators (<, >).
|
||||
|
||||
Args:
|
||||
bazel_version: the Bazel version string
|
||||
Args:
|
||||
bazel_version: the Bazel version string
|
||||
|
||||
Returns:
|
||||
An int 3-tuple of a (major, minor, patch) version.
|
||||
"""
|
||||
|
||||
version = _extract_version_number(bazel_version)
|
||||
return tuple([int(n) for n in version.split(".")])
|
||||
Returns:
|
||||
An int 3-tuple of a (major, minor, patch) version.
|
||||
"""
|
||||
|
||||
version = _extract_version_number(bazel_version)
|
||||
return tuple([int(n) for n in version.split(".")])
|
||||
|
||||
def _is_at_most(threshold, version):
|
||||
"""Check that a version is lower or equals to a threshold.
|
||||
"""Check that a version is lower or equals to a threshold.
|
||||
|
||||
Args:
|
||||
threshold: the maximum version string
|
||||
version: the version string to be compared to the threshold
|
||||
|
||||
Returns:
|
||||
True if version <= threshold.
|
||||
"""
|
||||
return _parse_bazel_version(version) <= _parse_bazel_version(threshold)
|
||||
Args:
|
||||
threshold: the maximum version string
|
||||
version: the version string to be compared to the threshold
|
||||
|
||||
Returns:
|
||||
True if version <= threshold.
|
||||
"""
|
||||
return _parse_bazel_version(version) <= _parse_bazel_version(threshold)
|
||||
|
||||
def _is_at_least(threshold, version):
|
||||
"""Check that a version is higher or equals to a threshold.
|
||||
"""Check that a version is higher or equals to a threshold.
|
||||
|
||||
Args:
|
||||
threshold: the minimum version string
|
||||
version: the version string to be compared to the threshold
|
||||
Args:
|
||||
threshold: the minimum version string
|
||||
version: the version string to be compared to the threshold
|
||||
|
||||
Returns:
|
||||
True if version >= threshold.
|
||||
"""
|
||||
Returns:
|
||||
True if version >= threshold.
|
||||
"""
|
||||
|
||||
return _parse_bazel_version(version) >= _parse_bazel_version(threshold)
|
||||
return _parse_bazel_version(version) >= _parse_bazel_version(threshold)
|
||||
|
||||
def _check_bazel_version(minimum_bazel_version, maximum_bazel_version = None, bazel_version = None):
|
||||
"""Check that the version of Bazel is valid within the specified range.
|
||||
|
||||
def _check_bazel_version(minimum_bazel_version, maximum_bazel_version=None, bazel_version=None):
|
||||
"""Check that the version of Bazel is valid within the specified range.
|
||||
Args:
|
||||
minimum_bazel_version: minimum version of Bazel expected
|
||||
maximum_bazel_version: maximum version of Bazel expected
|
||||
bazel_version: the version of Bazel to check. Used for testing, defaults to native.bazel_version
|
||||
"""
|
||||
if not bazel_version:
|
||||
if "bazel_version" not in dir(native):
|
||||
fail("\nCurrent Bazel version is lower than 0.2.1, expected at least %s\n" % minimum_bazel_version)
|
||||
elif not native.bazel_version:
|
||||
print("\nCurrent Bazel is not a release version, cannot check for compatibility.")
|
||||
print("Make sure that you are running at least Bazel %s.\n" % minimum_bazel_version)
|
||||
return
|
||||
else:
|
||||
bazel_version = native.bazel_version
|
||||
|
||||
Args:
|
||||
minimum_bazel_version: minimum version of Bazel expected
|
||||
maximum_bazel_version: maximum version of Bazel expected
|
||||
bazel_version: the version of Bazel to check. Used for testing, defaults to native.bazel_version
|
||||
"""
|
||||
if not bazel_version:
|
||||
if "bazel_version" not in dir(native):
|
||||
fail("\nCurrent Bazel version is lower than 0.2.1, expected at least %s\n" % minimum_bazel_version)
|
||||
elif not native.bazel_version:
|
||||
print("\nCurrent Bazel is not a release version, cannot check for compatibility.")
|
||||
print("Make sure that you are running at least Bazel %s.\n" % minimum_bazel_version)
|
||||
return
|
||||
else:
|
||||
bazel_version = native.bazel_version
|
||||
if not _is_at_least(
|
||||
threshold = minimum_bazel_version,
|
||||
version = bazel_version,
|
||||
):
|
||||
fail("\nCurrent Bazel version is {}, expected at least {}\n".format(
|
||||
bazel_version,
|
||||
minimum_bazel_version,
|
||||
))
|
||||
|
||||
if not _is_at_least(
|
||||
threshold = minimum_bazel_version,
|
||||
version = bazel_version):
|
||||
fail("\nCurrent Bazel version is {}, expected at least {}\n".format(
|
||||
bazel_version, minimum_bazel_version))
|
||||
if maximum_bazel_version:
|
||||
if not _is_at_most(
|
||||
threshold = maximum_bazel_version,
|
||||
version = bazel_version,
|
||||
):
|
||||
fail("\nCurrent Bazel version is {}, expected at most {}\n".format(
|
||||
bazel_version,
|
||||
maximum_bazel_version,
|
||||
))
|
||||
|
||||
if maximum_bazel_version:
|
||||
if not _is_at_most(
|
||||
threshold = maximum_bazel_version,
|
||||
version = bazel_version):
|
||||
fail("\nCurrent Bazel version is {}, expected at most {}\n".format(
|
||||
bazel_version, maximum_bazel_version))
|
||||
|
||||
pass
|
||||
pass
|
||||
|
||||
versions = struct(
|
||||
get=_get_bazel_version,
|
||||
parse=_parse_bazel_version,
|
||||
check=_check_bazel_version,
|
||||
is_at_most=_is_at_most,
|
||||
is_at_least=_is_at_least,
|
||||
get = _get_bazel_version,
|
||||
parse = _parse_bazel_version,
|
||||
check = _check_bazel_version,
|
||||
is_at_most = _is_at_most,
|
||||
is_at_least = _is_at_least,
|
||||
)
|
||||
|
|
|
@ -15,46 +15,46 @@
|
|||
"""Skylib module containing a library rule for aggregating rules files."""
|
||||
|
||||
SkylarkLibraryInfo = provider(
|
||||
'Information on contained Skylark rules.',
|
||||
fields={
|
||||
'srcs': 'Top level rules files.',
|
||||
'transitive_srcs': 'Transitive closure of rules files required for ' +
|
||||
'interpretation of the srcs',
|
||||
"Information on contained Skylark rules.",
|
||||
fields = {
|
||||
"srcs": "Top level rules files.",
|
||||
"transitive_srcs": "Transitive closure of rules files required for " +
|
||||
"interpretation of the srcs",
|
||||
},
|
||||
)
|
||||
|
||||
def _skylark_library_impl(ctx):
|
||||
deps_files = [depset(x.files, order="postorder") for x in ctx.attr.deps]
|
||||
all_files = depset(ctx.files.srcs, order="postorder", transitive=deps_files)
|
||||
return [
|
||||
# All dependent files should be listed in both `files` and in `runfiles`;
|
||||
# this ensures that a `skylark_library` can be referenced as `data` from
|
||||
# a separate program, or from `tools` of a genrule().
|
||||
DefaultInfo(
|
||||
files=all_files,
|
||||
runfiles=ctx.runfiles(files=list(all_files)),
|
||||
),
|
||||
deps_files = [depset(x.files, order = "postorder") for x in ctx.attr.deps]
|
||||
all_files = depset(ctx.files.srcs, order = "postorder", transitive = deps_files)
|
||||
return [
|
||||
# All dependent files should be listed in both `files` and in `runfiles`;
|
||||
# this ensures that a `skylark_library` can be referenced as `data` from
|
||||
# a separate program, or from `tools` of a genrule().
|
||||
DefaultInfo(
|
||||
files = all_files,
|
||||
runfiles = ctx.runfiles(files = list(all_files)),
|
||||
),
|
||||
|
||||
# We also define our own provider struct, for aggregation and testing.
|
||||
SkylarkLibraryInfo(
|
||||
srcs=ctx.files.srcs,
|
||||
transitive_srcs=all_files,
|
||||
),
|
||||
]
|
||||
# We also define our own provider struct, for aggregation and testing.
|
||||
SkylarkLibraryInfo(
|
||||
srcs = ctx.files.srcs,
|
||||
transitive_srcs = all_files,
|
||||
),
|
||||
]
|
||||
|
||||
skylark_library = rule(
|
||||
implementation=_skylark_library_impl,
|
||||
attrs={
|
||||
implementation = _skylark_library_impl,
|
||||
attrs = {
|
||||
"srcs": attr.label_list(
|
||||
allow_files=[".bzl"],
|
||||
allow_files = [".bzl"],
|
||||
),
|
||||
"deps": attr.label_list(
|
||||
allow_files=[".bzl"],
|
||||
providers=[
|
||||
allow_files = [".bzl"],
|
||||
providers = [
|
||||
[SkylarkLibraryInfo],
|
||||
],
|
||||
)
|
||||
}
|
||||
),
|
||||
},
|
||||
)
|
||||
"""Creates a logical collection of Skylark .bzl files.
|
||||
|
||||
|
|
|
@ -14,68 +14,99 @@
|
|||
|
||||
"""Unit tests for collections.bzl."""
|
||||
|
||||
load("//:lib.bzl", "collections", "asserts", "unittest")
|
||||
|
||||
load("//:lib.bzl", "asserts", "collections", "unittest")
|
||||
|
||||
def _after_each_test(ctx):
|
||||
"""Unit tests for collections.after_each."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for collections.after_each."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
asserts.equals(env, [], collections.after_each("1", []))
|
||||
asserts.equals(env, ["a", "1"], collections.after_each("1", ["a"]))
|
||||
asserts.equals(env, ["a", "1", "b", "1"],
|
||||
collections.after_each("1", ["a", "b"]))
|
||||
asserts.equals(env, [], collections.after_each("1", []))
|
||||
asserts.equals(env, ["a", "1"], collections.after_each("1", ["a"]))
|
||||
asserts.equals(
|
||||
env,
|
||||
["a", "1", "b", "1"],
|
||||
collections.after_each("1", ["a", "b"]),
|
||||
)
|
||||
|
||||
# We don't care what type the separator is, we just put it there; so None
|
||||
# should be just as valid as anything else.
|
||||
asserts.equals(env, ["a", None, "b", None],
|
||||
collections.after_each(None, ["a", "b"]))
|
||||
# We don't care what type the separator is, we just put it there; so None
|
||||
# should be just as valid as anything else.
|
||||
asserts.equals(
|
||||
env,
|
||||
["a", None, "b", None],
|
||||
collections.after_each(None, ["a", "b"]),
|
||||
)
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
after_each_test = unittest.make(_after_each_test)
|
||||
|
||||
|
||||
def _before_each_test(ctx):
|
||||
"""Unit tests for collections.before_each."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for collections.before_each."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
asserts.equals(env, [], collections.before_each("1", []))
|
||||
asserts.equals(env, ["1", "a"], collections.before_each("1", ["a"]))
|
||||
asserts.equals(env, ["1", "a", "1", "b"],
|
||||
collections.before_each("1", ["a", "b"]))
|
||||
asserts.equals(env, [], collections.before_each("1", []))
|
||||
asserts.equals(env, ["1", "a"], collections.before_each("1", ["a"]))
|
||||
asserts.equals(
|
||||
env,
|
||||
["1", "a", "1", "b"],
|
||||
collections.before_each("1", ["a", "b"]),
|
||||
)
|
||||
|
||||
# We don't care what type the separator is, we just put it there; so None
|
||||
# should be just as valid as anything else.
|
||||
asserts.equals(env, [None, "a", None, "b"],
|
||||
collections.before_each(None, ["a", "b"]))
|
||||
# We don't care what type the separator is, we just put it there; so None
|
||||
# should be just as valid as anything else.
|
||||
asserts.equals(
|
||||
env,
|
||||
[None, "a", None, "b"],
|
||||
collections.before_each(None, ["a", "b"]),
|
||||
)
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
before_each_test = unittest.make(_before_each_test)
|
||||
|
||||
|
||||
def _uniq_test(ctx):
|
||||
env = unittest.begin(ctx)
|
||||
asserts.equals(env, collections.uniq([0, 1, 2, 3]), [0, 1, 2, 3])
|
||||
asserts.equals(env, collections.uniq([]), [])
|
||||
asserts.equals(env, collections.uniq([1, 1, 1, 1, 1]), [1])
|
||||
asserts.equals(env, collections.uniq([True, 5, "foo", 5, False, struct(a=1),
|
||||
True, struct(b=2), "bar", (1,), "foo",
|
||||
struct(a=1), (1,)]),
|
||||
[True, 5, "foo", False, struct(a=1), struct(b=2),
|
||||
"bar", (1,)])
|
||||
env = unittest.begin(ctx)
|
||||
asserts.equals(env, collections.uniq([0, 1, 2, 3]), [0, 1, 2, 3])
|
||||
asserts.equals(env, collections.uniq([]), [])
|
||||
asserts.equals(env, collections.uniq([1, 1, 1, 1, 1]), [1])
|
||||
asserts.equals(
|
||||
env,
|
||||
collections.uniq([
|
||||
True,
|
||||
5,
|
||||
"foo",
|
||||
5,
|
||||
False,
|
||||
struct(a = 1),
|
||||
True,
|
||||
struct(b = 2),
|
||||
"bar",
|
||||
(1,),
|
||||
"foo",
|
||||
struct(a = 1),
|
||||
(1,),
|
||||
]),
|
||||
[
|
||||
True,
|
||||
5,
|
||||
"foo",
|
||||
False,
|
||||
struct(a = 1),
|
||||
struct(b = 2),
|
||||
"bar",
|
||||
(1,),
|
||||
],
|
||||
)
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
uniq_test = unittest.make(_uniq_test)
|
||||
|
||||
|
||||
def collections_test_suite():
|
||||
"""Creates the test targets and test suite for collections.bzl tests."""
|
||||
unittest.suite(
|
||||
"collections_tests",
|
||||
after_each_test,
|
||||
before_each_test,
|
||||
uniq_test,
|
||||
)
|
||||
"""Creates the test targets and test suite for collections.bzl tests."""
|
||||
unittest.suite(
|
||||
"collections_tests",
|
||||
after_each_test,
|
||||
before_each_test,
|
||||
uniq_test,
|
||||
)
|
||||
|
|
|
@ -14,54 +14,61 @@
|
|||
|
||||
"""Unit tests for dicts.bzl."""
|
||||
|
||||
load("//:lib.bzl", "dicts", "asserts", "unittest")
|
||||
|
||||
load("//:lib.bzl", "asserts", "dicts", "unittest")
|
||||
|
||||
def _add_test(ctx):
|
||||
"""Unit tests for dicts.add."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for dicts.add."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
# Test zero- and one-argument behavior.
|
||||
asserts.equals(env, {}, dicts.add())
|
||||
asserts.equals(env, {"a": 1}, dicts.add({"a": 1}))
|
||||
# Test zero- and one-argument behavior.
|
||||
asserts.equals(env, {}, dicts.add())
|
||||
asserts.equals(env, {"a": 1}, dicts.add({"a": 1}))
|
||||
|
||||
# Test simple two-argument behavior.
|
||||
asserts.equals(env, {"a": 1, "b": 2}, dicts.add({"a": 1}, {"b": 2}))
|
||||
# Test simple two-argument behavior.
|
||||
asserts.equals(env, {"a": 1, "b": 2}, dicts.add({"a": 1}, {"b": 2}))
|
||||
|
||||
# Test simple more-than-two-argument behavior.
|
||||
asserts.equals(env, {"a": 1, "b": 2, "c": 3, "d": 4},
|
||||
dicts.add({"a": 1}, {"b": 2}, {"c": 3}, {"d": 4}))
|
||||
# Test simple more-than-two-argument behavior.
|
||||
asserts.equals(
|
||||
env,
|
||||
{"a": 1, "b": 2, "c": 3, "d": 4},
|
||||
dicts.add({"a": 1}, {"b": 2}, {"c": 3}, {"d": 4}),
|
||||
)
|
||||
|
||||
# Test same-key overriding.
|
||||
asserts.equals(env, {"a": 100}, dicts.add({"a": 1}, {"a": 100}))
|
||||
asserts.equals(env, {"a": 10}, dicts.add({"a": 1}, {"a": 100}, {"a": 10}))
|
||||
asserts.equals(env, {"a": 100, "b": 10},
|
||||
dicts.add({"a": 1}, {"a": 100}, {"b": 10}))
|
||||
asserts.equals(env, {"a": 10}, dicts.add({"a": 1}, {}, {"a": 10}))
|
||||
asserts.equals(env, {"a": 10, "b": 5},
|
||||
dicts.add({"a": 1}, {"a": 10, "b": 5}))
|
||||
# Test same-key overriding.
|
||||
asserts.equals(env, {"a": 100}, dicts.add({"a": 1}, {"a": 100}))
|
||||
asserts.equals(env, {"a": 10}, dicts.add({"a": 1}, {"a": 100}, {"a": 10}))
|
||||
asserts.equals(
|
||||
env,
|
||||
{"a": 100, "b": 10},
|
||||
dicts.add({"a": 1}, {"a": 100}, {"b": 10}),
|
||||
)
|
||||
asserts.equals(env, {"a": 10}, dicts.add({"a": 1}, {}, {"a": 10}))
|
||||
asserts.equals(
|
||||
env,
|
||||
{"a": 10, "b": 5},
|
||||
dicts.add({"a": 1}, {"a": 10, "b": 5}),
|
||||
)
|
||||
|
||||
# Test some other boundary cases.
|
||||
asserts.equals(env, {"a": 1}, dicts.add({"a": 1}, {}))
|
||||
# Test some other boundary cases.
|
||||
asserts.equals(env, {"a": 1}, dicts.add({"a": 1}, {}))
|
||||
|
||||
# Since dictionaries are passed around by reference, make sure that the
|
||||
# result of dicts.add is always a *copy* by modifying it afterwards and
|
||||
# ensuring that the original argument doesn't also reflect the change. We do
|
||||
# this to protect against someone who might attempt to optimize the function
|
||||
# by returning the argument itself in the one-argument case.
|
||||
original = {"a": 1}
|
||||
result = dicts.add(original)
|
||||
result["a"] = 2
|
||||
asserts.equals(env, 1, original["a"])
|
||||
# Since dictionaries are passed around by reference, make sure that the
|
||||
# result of dicts.add is always a *copy* by modifying it afterwards and
|
||||
# ensuring that the original argument doesn't also reflect the change. We do
|
||||
# this to protect against someone who might attempt to optimize the function
|
||||
# by returning the argument itself in the one-argument case.
|
||||
original = {"a": 1}
|
||||
result = dicts.add(original)
|
||||
result["a"] = 2
|
||||
asserts.equals(env, 1, original["a"])
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
add_test = unittest.make(_add_test)
|
||||
|
||||
|
||||
def dicts_test_suite():
|
||||
"""Creates the test targets and test suite for dicts.bzl tests."""
|
||||
unittest.suite(
|
||||
"dicts_tests",
|
||||
add_test,
|
||||
)
|
||||
"""Creates the test targets and test suite for dicts.bzl tests."""
|
||||
unittest.suite(
|
||||
"dicts_tests",
|
||||
add_test,
|
||||
)
|
||||
|
|
|
@ -14,272 +14,264 @@
|
|||
|
||||
"""Unit tests for new_sets.bzl."""
|
||||
|
||||
load("//:lib.bzl", "new_sets", "asserts", "unittest")
|
||||
|
||||
load("//:lib.bzl", "asserts", "new_sets", "unittest")
|
||||
|
||||
def _is_equal_test(ctx):
|
||||
"""Unit tests for new_sets.is_equal."""
|
||||
"""Unit tests for new_sets.is_equal."""
|
||||
|
||||
# Note that if this test fails, the results for the other `sets` tests will
|
||||
# be inconclusive because they use `asserts.new_set_equals`, which in turn
|
||||
# calls `new_sets.is_equal`.
|
||||
env = unittest.begin(ctx)
|
||||
# Note that if this test fails, the results for the other `sets` tests will
|
||||
# be inconclusive because they use `asserts.new_set_equals`, which in turn
|
||||
# calls `new_sets.is_equal`.
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
asserts.true(env, new_sets.is_equal(new_sets.make(), new_sets.make()))
|
||||
asserts.false(env, new_sets.is_equal(new_sets.make(), new_sets.make([1])))
|
||||
asserts.false(env, new_sets.is_equal(new_sets.make([1]), new_sets.make()))
|
||||
asserts.true(env, new_sets.is_equal(new_sets.make([1]), new_sets.make([1])))
|
||||
asserts.false(env, new_sets.is_equal(new_sets.make([1]), new_sets.make([1, 2])))
|
||||
asserts.false(env, new_sets.is_equal(new_sets.make([1]), new_sets.make([2])))
|
||||
asserts.false(env, new_sets.is_equal(new_sets.make([1]), new_sets.make([1, 2])))
|
||||
asserts.true(env, new_sets.is_equal(new_sets.make(), new_sets.make()))
|
||||
asserts.false(env, new_sets.is_equal(new_sets.make(), new_sets.make([1])))
|
||||
asserts.false(env, new_sets.is_equal(new_sets.make([1]), new_sets.make()))
|
||||
asserts.true(env, new_sets.is_equal(new_sets.make([1]), new_sets.make([1])))
|
||||
asserts.false(env, new_sets.is_equal(new_sets.make([1]), new_sets.make([1, 2])))
|
||||
asserts.false(env, new_sets.is_equal(new_sets.make([1]), new_sets.make([2])))
|
||||
asserts.false(env, new_sets.is_equal(new_sets.make([1]), new_sets.make([1, 2])))
|
||||
|
||||
# Verify that the implementation is not using == on the sets directly.
|
||||
asserts.true(env, new_sets.is_equal(new_sets.make(depset([1])), new_sets.make(depset([1]))))
|
||||
# Verify that the implementation is not using == on the sets directly.
|
||||
asserts.true(env, new_sets.is_equal(new_sets.make(depset([1])), new_sets.make(depset([1]))))
|
||||
|
||||
# If passing a list, verify that duplicate elements are ignored.
|
||||
asserts.true(env, new_sets.is_equal(new_sets.make([1, 1]), new_sets.make([1])))
|
||||
# If passing a list, verify that duplicate elements are ignored.
|
||||
asserts.true(env, new_sets.is_equal(new_sets.make([1, 1]), new_sets.make([1])))
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
is_equal_test = unittest.make(_is_equal_test)
|
||||
|
||||
|
||||
def _is_subset_test(ctx):
|
||||
"""Unit tests for new_sets.is_subset."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for new_sets.is_subset."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
asserts.true(env, new_sets.is_subset(new_sets.make(), new_sets.make()))
|
||||
asserts.true(env, new_sets.is_subset(new_sets.make(), new_sets.make([1])))
|
||||
asserts.false(env, new_sets.is_subset(new_sets.make([1]), new_sets.make()))
|
||||
asserts.true(env, new_sets.is_subset(new_sets.make([1]), new_sets.make([1])))
|
||||
asserts.true(env, new_sets.is_subset(new_sets.make([1]), new_sets.make([1, 2])))
|
||||
asserts.false(env, new_sets.is_subset(new_sets.make([1]), new_sets.make([2])))
|
||||
asserts.true(env, new_sets.is_subset(new_sets.make([1]), new_sets.make(depset([1, 2]))))
|
||||
asserts.true(env, new_sets.is_subset(new_sets.make(), new_sets.make()))
|
||||
asserts.true(env, new_sets.is_subset(new_sets.make(), new_sets.make([1])))
|
||||
asserts.false(env, new_sets.is_subset(new_sets.make([1]), new_sets.make()))
|
||||
asserts.true(env, new_sets.is_subset(new_sets.make([1]), new_sets.make([1])))
|
||||
asserts.true(env, new_sets.is_subset(new_sets.make([1]), new_sets.make([1, 2])))
|
||||
asserts.false(env, new_sets.is_subset(new_sets.make([1]), new_sets.make([2])))
|
||||
asserts.true(env, new_sets.is_subset(new_sets.make([1]), new_sets.make(depset([1, 2]))))
|
||||
|
||||
# If passing a list, verify that duplicate elements are ignored.
|
||||
asserts.true(env, new_sets.is_subset(new_sets.make([1, 1]), new_sets.make([1, 2])))
|
||||
# If passing a list, verify that duplicate elements are ignored.
|
||||
asserts.true(env, new_sets.is_subset(new_sets.make([1, 1]), new_sets.make([1, 2])))
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
is_subset_test = unittest.make(_is_subset_test)
|
||||
|
||||
|
||||
def _disjoint_test(ctx):
|
||||
"""Unit tests for new_sets.disjoint."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for new_sets.disjoint."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
asserts.true(env, new_sets.disjoint(new_sets.make(), new_sets.make()))
|
||||
asserts.true(env, new_sets.disjoint(new_sets.make(), new_sets.make([1])))
|
||||
asserts.true(env, new_sets.disjoint(new_sets.make([1]), new_sets.make()))
|
||||
asserts.false(env, new_sets.disjoint(new_sets.make([1]), new_sets.make([1])))
|
||||
asserts.false(env, new_sets.disjoint(new_sets.make([1]), new_sets.make([1, 2])))
|
||||
asserts.true(env, new_sets.disjoint(new_sets.make([1]), new_sets.make([2])))
|
||||
asserts.true(env, new_sets.disjoint(new_sets.make([1]), new_sets.make(depset([2]))))
|
||||
asserts.true(env, new_sets.disjoint(new_sets.make(), new_sets.make()))
|
||||
asserts.true(env, new_sets.disjoint(new_sets.make(), new_sets.make([1])))
|
||||
asserts.true(env, new_sets.disjoint(new_sets.make([1]), new_sets.make()))
|
||||
asserts.false(env, new_sets.disjoint(new_sets.make([1]), new_sets.make([1])))
|
||||
asserts.false(env, new_sets.disjoint(new_sets.make([1]), new_sets.make([1, 2])))
|
||||
asserts.true(env, new_sets.disjoint(new_sets.make([1]), new_sets.make([2])))
|
||||
asserts.true(env, new_sets.disjoint(new_sets.make([1]), new_sets.make(depset([2]))))
|
||||
|
||||
# If passing a list, verify that duplicate elements are ignored.
|
||||
asserts.false(env, new_sets.disjoint(new_sets.make([1, 1]), new_sets.make([1, 2])))
|
||||
# If passing a list, verify that duplicate elements are ignored.
|
||||
asserts.false(env, new_sets.disjoint(new_sets.make([1, 1]), new_sets.make([1, 2])))
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
disjoint_test = unittest.make(_disjoint_test)
|
||||
|
||||
|
||||
def _intersection_test(ctx):
|
||||
"""Unit tests for new_sets.intersection."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for new_sets.intersection."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
asserts.new_set_equals(env, new_sets.make(), new_sets.intersection(new_sets.make(), new_sets.make()))
|
||||
asserts.new_set_equals(env, new_sets.make(), new_sets.intersection(new_sets.make(), new_sets.make([1])))
|
||||
asserts.new_set_equals(env, new_sets.make(), new_sets.intersection(new_sets.make([1]), new_sets.make()))
|
||||
asserts.new_set_equals(env, new_sets.make([1]), new_sets.intersection(new_sets.make([1]), new_sets.make([1])))
|
||||
asserts.new_set_equals(env, new_sets.make([1]), new_sets.intersection(new_sets.make([1]), new_sets.make([1, 2])))
|
||||
asserts.new_set_equals(env, new_sets.make(), new_sets.intersection(new_sets.make([1]), new_sets.make([2])))
|
||||
asserts.new_set_equals(env, new_sets.make([1]), new_sets.intersection(new_sets.make([1]), new_sets.make(depset([1]))))
|
||||
asserts.new_set_equals(env, new_sets.make(), new_sets.intersection(new_sets.make(), new_sets.make()))
|
||||
asserts.new_set_equals(env, new_sets.make(), new_sets.intersection(new_sets.make(), new_sets.make([1])))
|
||||
asserts.new_set_equals(env, new_sets.make(), new_sets.intersection(new_sets.make([1]), new_sets.make()))
|
||||
asserts.new_set_equals(env, new_sets.make([1]), new_sets.intersection(new_sets.make([1]), new_sets.make([1])))
|
||||
asserts.new_set_equals(env, new_sets.make([1]), new_sets.intersection(new_sets.make([1]), new_sets.make([1, 2])))
|
||||
asserts.new_set_equals(env, new_sets.make(), new_sets.intersection(new_sets.make([1]), new_sets.make([2])))
|
||||
asserts.new_set_equals(env, new_sets.make([1]), new_sets.intersection(new_sets.make([1]), new_sets.make(depset([1]))))
|
||||
|
||||
# If passing a list, verify that duplicate elements are ignored.
|
||||
asserts.new_set_equals(env, new_sets.make([1]), new_sets.intersection(new_sets.make([1, 1]), new_sets.make([1, 2])))
|
||||
# If passing a list, verify that duplicate elements are ignored.
|
||||
asserts.new_set_equals(env, new_sets.make([1]), new_sets.intersection(new_sets.make([1, 1]), new_sets.make([1, 2])))
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
intersection_test = unittest.make(_intersection_test)
|
||||
|
||||
|
||||
def _union_test(ctx):
|
||||
"""Unit tests for new_sets.union."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for new_sets.union."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
asserts.new_set_equals(env, new_sets.make(), new_sets.union())
|
||||
asserts.new_set_equals(env, new_sets.make([1]), new_sets.union(new_sets.make([1])))
|
||||
asserts.new_set_equals(env, new_sets.make(), new_sets.union(new_sets.make(), new_sets.make()))
|
||||
asserts.new_set_equals(env, new_sets.make([1]), new_sets.union(new_sets.make(), new_sets.make([1])))
|
||||
asserts.new_set_equals(env, new_sets.make([1]), new_sets.union(new_sets.make([1]), new_sets.make()))
|
||||
asserts.new_set_equals(env, new_sets.make([1]), new_sets.union(new_sets.make([1]), new_sets.make([1])))
|
||||
asserts.new_set_equals(env, new_sets.make([1, 2]), new_sets.union(new_sets.make([1]), new_sets.make([1, 2])))
|
||||
asserts.new_set_equals(env, new_sets.make([1, 2]), new_sets.union(new_sets.make([1]), new_sets.make([2])))
|
||||
asserts.new_set_equals(env, new_sets.make([1]), new_sets.union(new_sets.make([1]), new_sets.make(depset([1]))))
|
||||
asserts.new_set_equals(env, new_sets.make(), new_sets.union())
|
||||
asserts.new_set_equals(env, new_sets.make([1]), new_sets.union(new_sets.make([1])))
|
||||
asserts.new_set_equals(env, new_sets.make(), new_sets.union(new_sets.make(), new_sets.make()))
|
||||
asserts.new_set_equals(env, new_sets.make([1]), new_sets.union(new_sets.make(), new_sets.make([1])))
|
||||
asserts.new_set_equals(env, new_sets.make([1]), new_sets.union(new_sets.make([1]), new_sets.make()))
|
||||
asserts.new_set_equals(env, new_sets.make([1]), new_sets.union(new_sets.make([1]), new_sets.make([1])))
|
||||
asserts.new_set_equals(env, new_sets.make([1, 2]), new_sets.union(new_sets.make([1]), new_sets.make([1, 2])))
|
||||
asserts.new_set_equals(env, new_sets.make([1, 2]), new_sets.union(new_sets.make([1]), new_sets.make([2])))
|
||||
asserts.new_set_equals(env, new_sets.make([1]), new_sets.union(new_sets.make([1]), new_sets.make(depset([1]))))
|
||||
|
||||
# If passing a list, verify that duplicate elements are ignored.
|
||||
asserts.new_set_equals(env, new_sets.make([1, 2]), new_sets.union(new_sets.make([1, 1]), new_sets.make([1, 2])))
|
||||
# If passing a list, verify that duplicate elements are ignored.
|
||||
asserts.new_set_equals(env, new_sets.make([1, 2]), new_sets.union(new_sets.make([1, 1]), new_sets.make([1, 2])))
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
union_test = unittest.make(_union_test)
|
||||
|
||||
|
||||
def _difference_test(ctx):
|
||||
"""Unit tests for new_sets.difference."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for new_sets.difference."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
asserts.new_set_equals(env, new_sets.make(), new_sets.difference(new_sets.make(), new_sets.make()))
|
||||
asserts.new_set_equals(env, new_sets.make(), new_sets.difference(new_sets.make(), new_sets.make([1])))
|
||||
asserts.new_set_equals(env, new_sets.make([1]), new_sets.difference(new_sets.make([1]), new_sets.make()))
|
||||
asserts.new_set_equals(env, new_sets.make(), new_sets.difference(new_sets.make([1]), new_sets.make([1])))
|
||||
asserts.new_set_equals(env, new_sets.make(), new_sets.difference(new_sets.make([1]), new_sets.make([1, 2])))
|
||||
asserts.new_set_equals(env, new_sets.make([1]), new_sets.difference(new_sets.make([1]), new_sets.make([2])))
|
||||
asserts.new_set_equals(env, new_sets.make(), new_sets.difference(new_sets.make([1]), new_sets.make(depset([1]))))
|
||||
asserts.new_set_equals(env, new_sets.make(), new_sets.difference(new_sets.make(), new_sets.make()))
|
||||
asserts.new_set_equals(env, new_sets.make(), new_sets.difference(new_sets.make(), new_sets.make([1])))
|
||||
asserts.new_set_equals(env, new_sets.make([1]), new_sets.difference(new_sets.make([1]), new_sets.make()))
|
||||
asserts.new_set_equals(env, new_sets.make(), new_sets.difference(new_sets.make([1]), new_sets.make([1])))
|
||||
asserts.new_set_equals(env, new_sets.make(), new_sets.difference(new_sets.make([1]), new_sets.make([1, 2])))
|
||||
asserts.new_set_equals(env, new_sets.make([1]), new_sets.difference(new_sets.make([1]), new_sets.make([2])))
|
||||
asserts.new_set_equals(env, new_sets.make(), new_sets.difference(new_sets.make([1]), new_sets.make(depset([1]))))
|
||||
|
||||
# If passing a list, verify that duplicate elements are ignored.
|
||||
asserts.new_set_equals(env, new_sets.make([2]), new_sets.difference(new_sets.make([1, 2]), new_sets.make([1, 1])))
|
||||
# If passing a list, verify that duplicate elements are ignored.
|
||||
asserts.new_set_equals(env, new_sets.make([2]), new_sets.difference(new_sets.make([1, 2]), new_sets.make([1, 1])))
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
difference_test = unittest.make(_difference_test)
|
||||
|
||||
|
||||
def _to_list_test(ctx):
|
||||
"""Unit tests for new_sets.to_list."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for new_sets.to_list."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
asserts.equals(env, [], new_sets.to_list(new_sets.make()))
|
||||
asserts.equals(env, [1], new_sets.to_list(new_sets.make([1, 1, 1])))
|
||||
asserts.equals(env, [1, 2, 3], new_sets.to_list(new_sets.make([1, 2, 3])))
|
||||
asserts.equals(env, [], new_sets.to_list(new_sets.make()))
|
||||
asserts.equals(env, [1], new_sets.to_list(new_sets.make([1, 1, 1])))
|
||||
asserts.equals(env, [1, 2, 3], new_sets.to_list(new_sets.make([1, 2, 3])))
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
to_list_test = unittest.make(_to_list_test)
|
||||
|
||||
|
||||
def _make_test(ctx):
|
||||
"""Unit tests for new_sets.make."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for new_sets.make."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
asserts.equals(env, {}, new_sets.make()._values)
|
||||
asserts.equals(env, {x: None for x in [1, 2, 3]}, new_sets.make([1, 1, 2, 2, 3, 3])._values)
|
||||
asserts.equals(env, {1: None, 2: None}, new_sets.make(depset([1, 2]))._values)
|
||||
asserts.equals(env, {}, new_sets.make()._values)
|
||||
asserts.equals(env, {x: None for x in [1, 2, 3]}, new_sets.make([1, 1, 2, 2, 3, 3])._values)
|
||||
asserts.equals(env, {1: None, 2: None}, new_sets.make(depset([1, 2]))._values)
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
make_test = unittest.make(_make_test)
|
||||
|
||||
|
||||
def _copy_test(ctx):
|
||||
"""Unit tests for new_sets.copy."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for new_sets.copy."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
asserts.new_set_equals(env, new_sets.copy(new_sets.make()), new_sets.make())
|
||||
asserts.new_set_equals(env, new_sets.copy(new_sets.make([1, 2, 3])), new_sets.make([1, 2, 3]))
|
||||
# Ensure mutating the copy does not mutate the original
|
||||
original = new_sets.make([1, 2, 3])
|
||||
copy = new_sets.copy(original)
|
||||
copy._values[5] = None
|
||||
asserts.false(env, new_sets.is_equal(original, copy))
|
||||
asserts.new_set_equals(env, new_sets.copy(new_sets.make()), new_sets.make())
|
||||
asserts.new_set_equals(env, new_sets.copy(new_sets.make([1, 2, 3])), new_sets.make([1, 2, 3]))
|
||||
|
||||
unittest.end(env)
|
||||
# Ensure mutating the copy does not mutate the original
|
||||
original = new_sets.make([1, 2, 3])
|
||||
copy = new_sets.copy(original)
|
||||
copy._values[5] = None
|
||||
asserts.false(env, new_sets.is_equal(original, copy))
|
||||
|
||||
unittest.end(env)
|
||||
|
||||
copy_test = unittest.make(_copy_test)
|
||||
|
||||
|
||||
def _insert_test(ctx):
|
||||
"""Unit tests for new_sets.insert."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for new_sets.insert."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
asserts.new_set_equals(env, new_sets.make([1, 2, 3]), new_sets.insert(new_sets.make([1, 2]), 3))
|
||||
# Ensure mutating the inserted set does mutate the original set.
|
||||
original = new_sets.make([1, 2, 3])
|
||||
after_insert = new_sets.insert(original, 4)
|
||||
asserts.new_set_equals(env, original, after_insert,
|
||||
msg="Insert creates a new set which is an O(n) operation, insert should be O(1).")
|
||||
asserts.new_set_equals(env, new_sets.make([1, 2, 3]), new_sets.insert(new_sets.make([1, 2]), 3))
|
||||
|
||||
unittest.end(env)
|
||||
# Ensure mutating the inserted set does mutate the original set.
|
||||
original = new_sets.make([1, 2, 3])
|
||||
after_insert = new_sets.insert(original, 4)
|
||||
asserts.new_set_equals(
|
||||
env,
|
||||
original,
|
||||
after_insert,
|
||||
msg = "Insert creates a new set which is an O(n) operation, insert should be O(1).",
|
||||
)
|
||||
|
||||
unittest.end(env)
|
||||
|
||||
insert_test = unittest.make(_insert_test)
|
||||
|
||||
|
||||
def _contains_test(ctx):
|
||||
"""Unit tests for new_sets.contains."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for new_sets.contains."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
asserts.false(env, new_sets.contains(new_sets.make(), 1))
|
||||
asserts.true(env, new_sets.contains(new_sets.make([1]), 1))
|
||||
asserts.true(env, new_sets.contains(new_sets.make([1, 2]), 1))
|
||||
asserts.false(env, new_sets.contains(new_sets.make([2, 3]), 1))
|
||||
asserts.false(env, new_sets.contains(new_sets.make(), 1))
|
||||
asserts.true(env, new_sets.contains(new_sets.make([1]), 1))
|
||||
asserts.true(env, new_sets.contains(new_sets.make([1, 2]), 1))
|
||||
asserts.false(env, new_sets.contains(new_sets.make([2, 3]), 1))
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
contains_test = unittest.make(_contains_test)
|
||||
|
||||
|
||||
def _length_test(ctx):
|
||||
"""Unit test for new_sets.length."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit test for new_sets.length."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
asserts.equals(env, 0, new_sets.length(new_sets.make()))
|
||||
asserts.equals(env, 1, new_sets.length(new_sets.make([1])))
|
||||
asserts.equals(env, 2, new_sets.length(new_sets.make([1, 2])))
|
||||
asserts.equals(env, 0, new_sets.length(new_sets.make()))
|
||||
asserts.equals(env, 1, new_sets.length(new_sets.make([1])))
|
||||
asserts.equals(env, 2, new_sets.length(new_sets.make([1, 2])))
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
length_test = unittest.make(_length_test)
|
||||
|
||||
|
||||
def _remove_test(ctx):
|
||||
"""Unit test for new_sets.remove."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit test for new_sets.remove."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
asserts.new_set_equals(env, new_sets.make([1, 2]), new_sets.remove(new_sets.make([1, 2, 3]), 3))
|
||||
# Ensure mutating the inserted set does mutate the original set.
|
||||
original = new_sets.make([1, 2, 3])
|
||||
after_removal = new_sets.remove(original, 3)
|
||||
asserts.new_set_equals(env, original, after_removal)
|
||||
asserts.new_set_equals(env, new_sets.make([1, 2]), new_sets.remove(new_sets.make([1, 2, 3]), 3))
|
||||
|
||||
unittest.end(env)
|
||||
# Ensure mutating the inserted set does mutate the original set.
|
||||
original = new_sets.make([1, 2, 3])
|
||||
after_removal = new_sets.remove(original, 3)
|
||||
asserts.new_set_equals(env, original, after_removal)
|
||||
|
||||
unittest.end(env)
|
||||
|
||||
remove_test = unittest.make(_remove_test)
|
||||
|
||||
|
||||
def _repr_str_test(ctx):
|
||||
"""Unit test for new_sets.repr and new_sets.str."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit test for new_sets.repr and new_sets.str."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
asserts.equals(env, "[]", new_sets.repr(new_sets.make()))
|
||||
asserts.equals(env, "[1]", new_sets.repr(new_sets.make([1])))
|
||||
asserts.equals(env, "[1, 2]", new_sets.repr(new_sets.make([1, 2])))
|
||||
asserts.equals(env, "[]", new_sets.repr(new_sets.make()))
|
||||
asserts.equals(env, "[1]", new_sets.repr(new_sets.make([1])))
|
||||
asserts.equals(env, "[1, 2]", new_sets.repr(new_sets.make([1, 2])))
|
||||
|
||||
asserts.equals(env, "[]", new_sets.str(new_sets.make()))
|
||||
asserts.equals(env, "[1]", new_sets.str(new_sets.make([1])))
|
||||
asserts.equals(env, "[1, 2]", new_sets.str(new_sets.make([1, 2])))
|
||||
asserts.equals(env, "[]", new_sets.str(new_sets.make()))
|
||||
asserts.equals(env, "[1]", new_sets.str(new_sets.make([1])))
|
||||
asserts.equals(env, "[1, 2]", new_sets.str(new_sets.make([1, 2])))
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
repr_str_test = unittest.make(_repr_str_test)
|
||||
|
||||
|
||||
def new_sets_test_suite():
|
||||
"""Creates the test targets and test suite for new_sets.bzl tests."""
|
||||
unittest.suite(
|
||||
"new_sets_tests",
|
||||
disjoint_test,
|
||||
intersection_test,
|
||||
is_equal_test,
|
||||
is_subset_test,
|
||||
difference_test,
|
||||
union_test,
|
||||
to_list_test,
|
||||
make_test,
|
||||
copy_test,
|
||||
insert_test,
|
||||
contains_test,
|
||||
length_test,
|
||||
remove_test,
|
||||
repr_str_test,
|
||||
)
|
||||
"""Creates the test targets and test suite for new_sets.bzl tests."""
|
||||
unittest.suite(
|
||||
"new_sets_tests",
|
||||
disjoint_test,
|
||||
intersection_test,
|
||||
is_equal_test,
|
||||
is_subset_test,
|
||||
difference_test,
|
||||
union_test,
|
||||
to_list_test,
|
||||
make_test,
|
||||
copy_test,
|
||||
insert_test,
|
||||
contains_test,
|
||||
length_test,
|
||||
remove_test,
|
||||
repr_str_test,
|
||||
)
|
||||
|
|
|
@ -14,72 +14,70 @@
|
|||
|
||||
"""Unit tests for partial.bzl."""
|
||||
|
||||
load("//:lib.bzl", "partial", "asserts", "unittest")
|
||||
|
||||
load("//:lib.bzl", "asserts", "partial", "unittest")
|
||||
|
||||
def _make_noargs_nokwargs():
|
||||
"""Test utility for no args no kwargs case"""
|
||||
return 1
|
||||
"""Test utility for no args no kwargs case"""
|
||||
return 1
|
||||
|
||||
def _make_args_nokwargs(arg1, arg2, arg3):
|
||||
"""Test utility for args no kwargs case"""
|
||||
return arg1 + arg2 + arg3
|
||||
"""Test utility for args no kwargs case"""
|
||||
return arg1 + arg2 + arg3
|
||||
|
||||
def _make_args_kwargs(arg1, arg2, arg3, **kwargs):
|
||||
"""Test utility for args and kwargs case"""
|
||||
return arg1 + arg2 + arg3 + kwargs["x"] + kwargs["y"]
|
||||
"""Test utility for args and kwargs case"""
|
||||
return arg1 + arg2 + arg3 + kwargs["x"] + kwargs["y"]
|
||||
|
||||
def _call_noargs_nokwargs(call_arg1):
|
||||
"""Test utility no args no kwargs case where values passed from call site"""
|
||||
return call_arg1;
|
||||
"""Test utility no args no kwargs case where values passed from call site"""
|
||||
return call_arg1
|
||||
|
||||
def _call_args_nokwargs(func_arg1, call_arg1):
|
||||
"""Test utility for args no kwargs case where values passed from call site"""
|
||||
return func_arg1 + call_arg1;
|
||||
"""Test utility for args no kwargs case where values passed from call site"""
|
||||
return func_arg1 + call_arg1
|
||||
|
||||
def _call_args_kwargs(func_arg1, call_arg1, func_mult, call_mult):
|
||||
"""Test utility for args and kwargs case where values passed from call site"""
|
||||
return (func_arg1 + call_arg1) * func_mult * call_mult;
|
||||
"""Test utility for args and kwargs case where values passed from call site"""
|
||||
return (func_arg1 + call_arg1) * func_mult * call_mult
|
||||
|
||||
def _make_call_test(ctx):
|
||||
"""Unit tests for partial.make and partial.call."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for partial.make and partial.call."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
# Test cases where there are no args (or kwargs) at the make site, only
|
||||
# at the call site.
|
||||
foo = partial.make(_make_noargs_nokwargs)
|
||||
asserts.equals(env, 1, partial.call(foo))
|
||||
# Test cases where there are no args (or kwargs) at the make site, only
|
||||
# at the call site.
|
||||
foo = partial.make(_make_noargs_nokwargs)
|
||||
asserts.equals(env, 1, partial.call(foo))
|
||||
|
||||
foo = partial.make(_make_args_nokwargs)
|
||||
asserts.equals(env, 6, partial.call(foo, 1, 2, 3))
|
||||
foo = partial.make(_make_args_nokwargs)
|
||||
asserts.equals(env, 6, partial.call(foo, 1, 2, 3))
|
||||
|
||||
foo = partial.make(_make_args_kwargs)
|
||||
asserts.equals(env, 15, partial.call(foo, 1, 2, 3, x=4, y=5))
|
||||
foo = partial.make(_make_args_kwargs)
|
||||
asserts.equals(env, 15, partial.call(foo, 1, 2, 3, x = 4, y = 5))
|
||||
|
||||
# Test cases where there are args (and/or kwargs) at the make site and the
|
||||
# call site.
|
||||
foo = partial.make(_call_noargs_nokwargs, 100)
|
||||
asserts.equals(env, 100, partial.call(foo))
|
||||
# Test cases where there are args (and/or kwargs) at the make site and the
|
||||
# call site.
|
||||
foo = partial.make(_call_noargs_nokwargs, 100)
|
||||
asserts.equals(env, 100, partial.call(foo))
|
||||
|
||||
foo = partial.make(_call_args_nokwargs, 100)
|
||||
asserts.equals(env, 112, partial.call(foo, 12))
|
||||
foo = partial.make(_call_args_nokwargs, 100)
|
||||
asserts.equals(env, 112, partial.call(foo, 12))
|
||||
|
||||
foo = partial.make(_call_args_kwargs, 100, func_mult=10)
|
||||
asserts.equals(env, 2240, partial.call(foo, 12, call_mult=2))
|
||||
foo = partial.make(_call_args_kwargs, 100, func_mult = 10)
|
||||
asserts.equals(env, 2240, partial.call(foo, 12, call_mult = 2))
|
||||
|
||||
# Test case where there are args and kwargs ath the make site, and the call
|
||||
# site overrides some make site args.
|
||||
foo = partial.make(_call_args_kwargs, 100, func_mult=10)
|
||||
asserts.equals(env, 1120, partial.call(foo, 12, func_mult=5, call_mult=2))
|
||||
# Test case where there are args and kwargs ath the make site, and the call
|
||||
# site overrides some make site args.
|
||||
foo = partial.make(_call_args_kwargs, 100, func_mult = 10)
|
||||
asserts.equals(env, 1120, partial.call(foo, 12, func_mult = 5, call_mult = 2))
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
make_call_test = unittest.make(_make_call_test)
|
||||
|
||||
|
||||
def partial_test_suite():
|
||||
"""Creates the test targets and test suite for partial.bzl tests."""
|
||||
unittest.suite(
|
||||
"partial_tests",
|
||||
make_call_test,
|
||||
)
|
||||
"""Creates the test targets and test suite for partial.bzl tests."""
|
||||
unittest.suite(
|
||||
"partial_tests",
|
||||
make_call_test,
|
||||
)
|
||||
|
|
|
@ -14,271 +14,271 @@
|
|||
|
||||
"""Unit tests for paths.bzl."""
|
||||
|
||||
load("//:lib.bzl", "paths", "asserts", "unittest")
|
||||
|
||||
load("//:lib.bzl", "asserts", "paths", "unittest")
|
||||
|
||||
def _basename_test(ctx):
|
||||
"""Unit tests for paths.basename."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for paths.basename."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
# Verify some degenerate cases.
|
||||
asserts.equals(env, "", paths.basename(""))
|
||||
asserts.equals(env, "", paths.basename("/"))
|
||||
asserts.equals(env, "bar", paths.basename("foo///bar"))
|
||||
# Verify some degenerate cases.
|
||||
asserts.equals(env, "", paths.basename(""))
|
||||
asserts.equals(env, "", paths.basename("/"))
|
||||
asserts.equals(env, "bar", paths.basename("foo///bar"))
|
||||
|
||||
# Verify some realistic cases.
|
||||
asserts.equals(env, "foo", paths.basename("foo"))
|
||||
asserts.equals(env, "foo", paths.basename("/foo"))
|
||||
asserts.equals(env, "foo", paths.basename("bar/foo"))
|
||||
asserts.equals(env, "foo", paths.basename("/bar/foo"))
|
||||
# Verify some realistic cases.
|
||||
asserts.equals(env, "foo", paths.basename("foo"))
|
||||
asserts.equals(env, "foo", paths.basename("/foo"))
|
||||
asserts.equals(env, "foo", paths.basename("bar/foo"))
|
||||
asserts.equals(env, "foo", paths.basename("/bar/foo"))
|
||||
|
||||
# Verify that we correctly duplicate Python's os.path.basename behavior,
|
||||
# where a trailing slash means the basename is empty.
|
||||
asserts.equals(env, "", paths.basename("foo/"))
|
||||
asserts.equals(env, "", paths.basename("/foo/"))
|
||||
# Verify that we correctly duplicate Python's os.path.basename behavior,
|
||||
# where a trailing slash means the basename is empty.
|
||||
asserts.equals(env, "", paths.basename("foo/"))
|
||||
asserts.equals(env, "", paths.basename("/foo/"))
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
basename_test = unittest.make(_basename_test)
|
||||
|
||||
|
||||
def _dirname_test(ctx):
|
||||
"""Unit tests for paths.dirname."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for paths.dirname."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
# Verify some degenerate cases.
|
||||
asserts.equals(env, "", paths.dirname(""))
|
||||
asserts.equals(env, "/", paths.dirname("/"))
|
||||
asserts.equals(env, "foo", paths.dirname("foo///bar"))
|
||||
# Verify some degenerate cases.
|
||||
asserts.equals(env, "", paths.dirname(""))
|
||||
asserts.equals(env, "/", paths.dirname("/"))
|
||||
asserts.equals(env, "foo", paths.dirname("foo///bar"))
|
||||
|
||||
# Verify some realistic cases.
|
||||
asserts.equals(env, "", paths.dirname("foo"))
|
||||
asserts.equals(env, "/", paths.dirname("/foo"))
|
||||
asserts.equals(env, "bar", paths.dirname("bar/foo"))
|
||||
asserts.equals(env, "/bar", paths.dirname("/bar/foo"))
|
||||
# Verify some realistic cases.
|
||||
asserts.equals(env, "", paths.dirname("foo"))
|
||||
asserts.equals(env, "/", paths.dirname("/foo"))
|
||||
asserts.equals(env, "bar", paths.dirname("bar/foo"))
|
||||
asserts.equals(env, "/bar", paths.dirname("/bar/foo"))
|
||||
|
||||
# Verify that we correctly duplicate Python's os.path.dirname behavior,
|
||||
# where a trailing slash means the dirname is the same as the original
|
||||
# path (without the trailing slash).
|
||||
asserts.equals(env, "foo", paths.dirname("foo/"))
|
||||
asserts.equals(env, "/foo", paths.dirname("/foo/"))
|
||||
# Verify that we correctly duplicate Python's os.path.dirname behavior,
|
||||
# where a trailing slash means the dirname is the same as the original
|
||||
# path (without the trailing slash).
|
||||
asserts.equals(env, "foo", paths.dirname("foo/"))
|
||||
asserts.equals(env, "/foo", paths.dirname("/foo/"))
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
dirname_test = unittest.make(_dirname_test)
|
||||
|
||||
|
||||
def _is_absolute_test(ctx):
|
||||
"""Unit tests for paths.is_absolute."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for paths.is_absolute."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
# Try a degenerate case.
|
||||
asserts.false(env, paths.is_absolute(""))
|
||||
# Try a degenerate case.
|
||||
asserts.false(env, paths.is_absolute(""))
|
||||
|
||||
# Try some relative paths.
|
||||
asserts.false(env, paths.is_absolute("foo"))
|
||||
asserts.false(env, paths.is_absolute("foo/"))
|
||||
asserts.false(env, paths.is_absolute("foo/bar"))
|
||||
# Try some relative paths.
|
||||
asserts.false(env, paths.is_absolute("foo"))
|
||||
asserts.false(env, paths.is_absolute("foo/"))
|
||||
asserts.false(env, paths.is_absolute("foo/bar"))
|
||||
|
||||
# Try some absolute paths.
|
||||
asserts.true(env, paths.is_absolute("/"))
|
||||
asserts.true(env, paths.is_absolute("/foo"))
|
||||
asserts.true(env, paths.is_absolute("/foo/"))
|
||||
asserts.true(env, paths.is_absolute("/foo/bar"))
|
||||
# Try some absolute paths.
|
||||
asserts.true(env, paths.is_absolute("/"))
|
||||
asserts.true(env, paths.is_absolute("/foo"))
|
||||
asserts.true(env, paths.is_absolute("/foo/"))
|
||||
asserts.true(env, paths.is_absolute("/foo/bar"))
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
is_absolute_test = unittest.make(_is_absolute_test)
|
||||
|
||||
|
||||
def _join_test(ctx):
|
||||
"""Unit tests for paths.join."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for paths.join."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
# Try a degenerate case.
|
||||
asserts.equals(env, "", paths.join(""))
|
||||
# Try a degenerate case.
|
||||
asserts.equals(env, "", paths.join(""))
|
||||
|
||||
# Try some basic paths.
|
||||
asserts.equals(env, "foo", paths.join("foo"))
|
||||
asserts.equals(env, "foo/bar", paths.join("foo", "bar"))
|
||||
asserts.equals(env, "foo/bar/baz", paths.join("foo", "bar", "baz"))
|
||||
# Try some basic paths.
|
||||
asserts.equals(env, "foo", paths.join("foo"))
|
||||
asserts.equals(env, "foo/bar", paths.join("foo", "bar"))
|
||||
asserts.equals(env, "foo/bar/baz", paths.join("foo", "bar", "baz"))
|
||||
|
||||
# Make sure an initially absolute path stays absolute.
|
||||
asserts.equals(env, "/foo", paths.join("/foo"))
|
||||
asserts.equals(env, "/foo/bar", paths.join("/foo", "bar"))
|
||||
# Make sure an initially absolute path stays absolute.
|
||||
asserts.equals(env, "/foo", paths.join("/foo"))
|
||||
asserts.equals(env, "/foo/bar", paths.join("/foo", "bar"))
|
||||
|
||||
# Make sure an absolute path later in the list resets the result.
|
||||
asserts.equals(env, "/baz", paths.join("foo", "bar", "/baz"))
|
||||
asserts.equals(env, "/baz", paths.join("foo", "/bar", "/baz"))
|
||||
asserts.equals(env, "/bar/baz", paths.join("foo", "/bar", "baz"))
|
||||
asserts.equals(env, "/bar", paths.join("/foo", "/bar"))
|
||||
# Make sure an absolute path later in the list resets the result.
|
||||
asserts.equals(env, "/baz", paths.join("foo", "bar", "/baz"))
|
||||
asserts.equals(env, "/baz", paths.join("foo", "/bar", "/baz"))
|
||||
asserts.equals(env, "/bar/baz", paths.join("foo", "/bar", "baz"))
|
||||
asserts.equals(env, "/bar", paths.join("/foo", "/bar"))
|
||||
|
||||
# Make sure a leading empty segment doesn't make it absolute.
|
||||
asserts.equals(env, "foo", paths.join("", "foo"))
|
||||
# Make sure a leading empty segment doesn't make it absolute.
|
||||
asserts.equals(env, "foo", paths.join("", "foo"))
|
||||
|
||||
# Try some trailing slash scenarios.
|
||||
asserts.equals(env, "foo/", paths.join("foo", ""))
|
||||
asserts.equals(env, "foo/", paths.join("foo/"))
|
||||
asserts.equals(env, "foo/", paths.join("foo/", ""))
|
||||
asserts.equals(env, "foo//", paths.join("foo//", ""))
|
||||
asserts.equals(env, "foo//", paths.join("foo//"))
|
||||
asserts.equals(env, "foo/bar/baz/", paths.join("foo/", "bar/", "baz", ""))
|
||||
asserts.equals(env, "foo/bar/baz/", paths.join("foo/", "bar/", "baz/"))
|
||||
asserts.equals(env, "foo/bar/baz/", paths.join("foo/", "bar/", "baz/", ""))
|
||||
# Try some trailing slash scenarios.
|
||||
asserts.equals(env, "foo/", paths.join("foo", ""))
|
||||
asserts.equals(env, "foo/", paths.join("foo/"))
|
||||
asserts.equals(env, "foo/", paths.join("foo/", ""))
|
||||
asserts.equals(env, "foo//", paths.join("foo//", ""))
|
||||
asserts.equals(env, "foo//", paths.join("foo//"))
|
||||
asserts.equals(env, "foo/bar/baz/", paths.join("foo/", "bar/", "baz", ""))
|
||||
asserts.equals(env, "foo/bar/baz/", paths.join("foo/", "bar/", "baz/"))
|
||||
asserts.equals(env, "foo/bar/baz/", paths.join("foo/", "bar/", "baz/", ""))
|
||||
|
||||
# Make sure that adjacent empty segments don't add extra path separators.
|
||||
asserts.equals(env, "foo/", paths.join("foo", "", ""))
|
||||
asserts.equals(env, "foo", paths.join("", "", "foo"))
|
||||
asserts.equals(env, "foo/bar", paths.join("foo", "", "", "bar"))
|
||||
# Make sure that adjacent empty segments don't add extra path separators.
|
||||
asserts.equals(env, "foo/", paths.join("foo", "", ""))
|
||||
asserts.equals(env, "foo", paths.join("", "", "foo"))
|
||||
asserts.equals(env, "foo/bar", paths.join("foo", "", "", "bar"))
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
join_test = unittest.make(_join_test)
|
||||
|
||||
|
||||
def _normalize_test(ctx):
|
||||
"""Unit tests for paths.normalize."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for paths.normalize."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
# Try the most basic case.
|
||||
asserts.equals(env, ".", paths.normalize(""))
|
||||
# Try the most basic case.
|
||||
asserts.equals(env, ".", paths.normalize(""))
|
||||
|
||||
# Try some basic adjacent-slash removal.
|
||||
asserts.equals(env, "foo/bar", paths.normalize("foo//bar"))
|
||||
asserts.equals(env, "foo/bar", paths.normalize("foo////bar"))
|
||||
# Try some basic adjacent-slash removal.
|
||||
asserts.equals(env, "foo/bar", paths.normalize("foo//bar"))
|
||||
asserts.equals(env, "foo/bar", paths.normalize("foo////bar"))
|
||||
|
||||
# Try some "." removal.
|
||||
asserts.equals(env, "foo/bar", paths.normalize("foo/./bar"))
|
||||
asserts.equals(env, "foo/bar", paths.normalize("./foo/bar"))
|
||||
asserts.equals(env, "foo/bar", paths.normalize("foo/bar/."))
|
||||
asserts.equals(env, "/", paths.normalize("/."))
|
||||
# Try some "." removal.
|
||||
asserts.equals(env, "foo/bar", paths.normalize("foo/./bar"))
|
||||
asserts.equals(env, "foo/bar", paths.normalize("./foo/bar"))
|
||||
asserts.equals(env, "foo/bar", paths.normalize("foo/bar/."))
|
||||
asserts.equals(env, "/", paths.normalize("/."))
|
||||
|
||||
# Try some ".." removal.
|
||||
asserts.equals(env, "bar", paths.normalize("foo/../bar"))
|
||||
asserts.equals(env, "foo", paths.normalize("foo/bar/.."))
|
||||
asserts.equals(env, ".", paths.normalize("foo/.."))
|
||||
asserts.equals(env, ".", paths.normalize("foo/bar/../.."))
|
||||
asserts.equals(env, "..", paths.normalize("foo/../.."))
|
||||
asserts.equals(env, "/", paths.normalize("/foo/../.."))
|
||||
asserts.equals(env, "../../c", paths.normalize("a/b/../../../../c/d/.."))
|
||||
# Try some ".." removal.
|
||||
asserts.equals(env, "bar", paths.normalize("foo/../bar"))
|
||||
asserts.equals(env, "foo", paths.normalize("foo/bar/.."))
|
||||
asserts.equals(env, ".", paths.normalize("foo/.."))
|
||||
asserts.equals(env, ".", paths.normalize("foo/bar/../.."))
|
||||
asserts.equals(env, "..", paths.normalize("foo/../.."))
|
||||
asserts.equals(env, "/", paths.normalize("/foo/../.."))
|
||||
asserts.equals(env, "../../c", paths.normalize("a/b/../../../../c/d/.."))
|
||||
|
||||
# Make sure one or two initial slashes are preserved, but three or more are
|
||||
# collapsed to a single slash.
|
||||
asserts.equals(env, "/foo", paths.normalize("/foo"))
|
||||
asserts.equals(env, "//foo", paths.normalize("//foo"))
|
||||
asserts.equals(env, "/foo", paths.normalize("///foo"))
|
||||
# Make sure one or two initial slashes are preserved, but three or more are
|
||||
# collapsed to a single slash.
|
||||
asserts.equals(env, "/foo", paths.normalize("/foo"))
|
||||
asserts.equals(env, "//foo", paths.normalize("//foo"))
|
||||
asserts.equals(env, "/foo", paths.normalize("///foo"))
|
||||
|
||||
# Trailing slashes should be removed unless the entire path is a trailing
|
||||
# slash.
|
||||
asserts.equals(env, "/", paths.normalize("/"))
|
||||
asserts.equals(env, "foo", paths.normalize("foo/"))
|
||||
asserts.equals(env, "foo/bar", paths.normalize("foo/bar/"))
|
||||
# Trailing slashes should be removed unless the entire path is a trailing
|
||||
# slash.
|
||||
asserts.equals(env, "/", paths.normalize("/"))
|
||||
asserts.equals(env, "foo", paths.normalize("foo/"))
|
||||
asserts.equals(env, "foo/bar", paths.normalize("foo/bar/"))
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
normalize_test = unittest.make(_normalize_test)
|
||||
|
||||
|
||||
def _relativize_test(ctx):
|
||||
"""Unit tests for paths.relativize."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for paths.relativize."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
# Make sure that relative-to-current-directory works in all forms.
|
||||
asserts.equals(env, "foo", paths.relativize("foo", ""))
|
||||
asserts.equals(env, "foo", paths.relativize("foo", "."))
|
||||
# Make sure that relative-to-current-directory works in all forms.
|
||||
asserts.equals(env, "foo", paths.relativize("foo", ""))
|
||||
asserts.equals(env, "foo", paths.relativize("foo", "."))
|
||||
|
||||
# Try some regular cases.
|
||||
asserts.equals(env, "bar", paths.relativize("foo/bar", "foo"))
|
||||
asserts.equals(env, "baz", paths.relativize("foo/bar/baz", "foo/bar"))
|
||||
asserts.equals(env, "bar/baz", paths.relativize("foo/bar/baz", "foo"))
|
||||
# Try some regular cases.
|
||||
asserts.equals(env, "bar", paths.relativize("foo/bar", "foo"))
|
||||
asserts.equals(env, "baz", paths.relativize("foo/bar/baz", "foo/bar"))
|
||||
asserts.equals(env, "bar/baz", paths.relativize("foo/bar/baz", "foo"))
|
||||
|
||||
# Try a case where a parent directory is normalized away.
|
||||
asserts.equals(env, "baz", paths.relativize("foo/bar/../baz", "foo"))
|
||||
# Try a case where a parent directory is normalized away.
|
||||
asserts.equals(env, "baz", paths.relativize("foo/bar/../baz", "foo"))
|
||||
|
||||
# Relative paths work, as long as they share a common start.
|
||||
asserts.equals(env, "file", paths.relativize("../foo/bar/baz/file", "../foo/bar/baz"))
|
||||
asserts.equals(env, "baz/file", paths.relativize("../foo/bar/baz/file", "../foo/bar"))
|
||||
# Relative paths work, as long as they share a common start.
|
||||
asserts.equals(env, "file", paths.relativize("../foo/bar/baz/file", "../foo/bar/baz"))
|
||||
asserts.equals(env, "baz/file", paths.relativize("../foo/bar/baz/file", "../foo/bar"))
|
||||
|
||||
# TODO(allevato): Test failure cases, once that is possible.
|
||||
# TODO(allevato): Test failure cases, once that is possible.
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
relativize_test = unittest.make(_relativize_test)
|
||||
|
||||
|
||||
def _replace_extension_test(ctx):
|
||||
"""Unit tests for paths.replace_extension."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for paths.replace_extension."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
# Try some degenerate cases.
|
||||
asserts.equals(env, ".foo", paths.replace_extension("", ".foo"))
|
||||
asserts.equals(env, "/.foo", paths.replace_extension("/", ".foo"))
|
||||
asserts.equals(env, "foo.bar", paths.replace_extension("foo", ".bar"))
|
||||
# Try some degenerate cases.
|
||||
asserts.equals(env, ".foo", paths.replace_extension("", ".foo"))
|
||||
asserts.equals(env, "/.foo", paths.replace_extension("/", ".foo"))
|
||||
asserts.equals(env, "foo.bar", paths.replace_extension("foo", ".bar"))
|
||||
|
||||
# Try a directory with an extension and basename that doesn't have one.
|
||||
asserts.equals(env, "foo.bar/baz.quux",
|
||||
paths.replace_extension("foo.bar/baz", ".quux"))
|
||||
# Try a directory with an extension and basename that doesn't have one.
|
||||
asserts.equals(
|
||||
env,
|
||||
"foo.bar/baz.quux",
|
||||
paths.replace_extension("foo.bar/baz", ".quux"),
|
||||
)
|
||||
|
||||
# Now try some things with legit extensions.
|
||||
asserts.equals(env, "a.z", paths.replace_extension("a.b", ".z"))
|
||||
asserts.equals(env, "a.b.z", paths.replace_extension("a.b.c", ".z"))
|
||||
asserts.equals(env, "a/b.z", paths.replace_extension("a/b.c", ".z"))
|
||||
asserts.equals(env, "a.b/c.z", paths.replace_extension("a.b/c.d", ".z"))
|
||||
asserts.equals(env, ".a/b.z", paths.replace_extension(".a/b.c", ".z"))
|
||||
asserts.equals(env, ".a.z", paths.replace_extension(".a.b", ".z"))
|
||||
# Now try some things with legit extensions.
|
||||
asserts.equals(env, "a.z", paths.replace_extension("a.b", ".z"))
|
||||
asserts.equals(env, "a.b.z", paths.replace_extension("a.b.c", ".z"))
|
||||
asserts.equals(env, "a/b.z", paths.replace_extension("a/b.c", ".z"))
|
||||
asserts.equals(env, "a.b/c.z", paths.replace_extension("a.b/c.d", ".z"))
|
||||
asserts.equals(env, ".a/b.z", paths.replace_extension(".a/b.c", ".z"))
|
||||
asserts.equals(env, ".a.z", paths.replace_extension(".a.b", ".z"))
|
||||
|
||||
# Verify that we don't insert a period on the extension if none is provided.
|
||||
asserts.equals(env, "foobaz", paths.replace_extension("foo.bar", "baz"))
|
||||
# Verify that we don't insert a period on the extension if none is provided.
|
||||
asserts.equals(env, "foobaz", paths.replace_extension("foo.bar", "baz"))
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
replace_extension_test = unittest.make(_replace_extension_test)
|
||||
|
||||
|
||||
def _split_extension_test(ctx):
|
||||
"""Unit tests for paths.split_extension."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for paths.split_extension."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
# Try some degenerate cases.
|
||||
asserts.equals(env, ("", ""), paths.split_extension(""))
|
||||
asserts.equals(env, ("/", ""), paths.split_extension("/"))
|
||||
asserts.equals(env, ("foo", ""), paths.split_extension("foo"))
|
||||
# Try some degenerate cases.
|
||||
asserts.equals(env, ("", ""), paths.split_extension(""))
|
||||
asserts.equals(env, ("/", ""), paths.split_extension("/"))
|
||||
asserts.equals(env, ("foo", ""), paths.split_extension("foo"))
|
||||
|
||||
# Try some paths whose basenames start with ".".
|
||||
asserts.equals(env, (".", ""), paths.split_extension("."))
|
||||
asserts.equals(env, (".bashrc", ""), paths.split_extension(".bashrc"))
|
||||
asserts.equals(env, ("foo/.bashrc", ""), paths.split_extension("foo/.bashrc"))
|
||||
asserts.equals(env, (".foo/.bashrc", ""),
|
||||
paths.split_extension(".foo/.bashrc"))
|
||||
# Try some paths whose basenames start with ".".
|
||||
asserts.equals(env, (".", ""), paths.split_extension("."))
|
||||
asserts.equals(env, (".bashrc", ""), paths.split_extension(".bashrc"))
|
||||
asserts.equals(env, ("foo/.bashrc", ""), paths.split_extension("foo/.bashrc"))
|
||||
asserts.equals(
|
||||
env,
|
||||
(".foo/.bashrc", ""),
|
||||
paths.split_extension(".foo/.bashrc"),
|
||||
)
|
||||
|
||||
# Try some directories with extensions with basenames that don't have one.
|
||||
asserts.equals(env, ("foo.bar/baz", ""), paths.split_extension("foo.bar/baz"))
|
||||
asserts.equals(env, ("foo.bar/.bashrc", ""),
|
||||
paths.split_extension("foo.bar/.bashrc"))
|
||||
# Try some directories with extensions with basenames that don't have one.
|
||||
asserts.equals(env, ("foo.bar/baz", ""), paths.split_extension("foo.bar/baz"))
|
||||
asserts.equals(
|
||||
env,
|
||||
("foo.bar/.bashrc", ""),
|
||||
paths.split_extension("foo.bar/.bashrc"),
|
||||
)
|
||||
|
||||
# Now try some things that will actually get split.
|
||||
asserts.equals(env, ("a", ".b"), paths.split_extension("a.b"))
|
||||
asserts.equals(env, ("a.b", ".c"), paths.split_extension("a.b.c"))
|
||||
asserts.equals(env, ("a/b", ".c"), paths.split_extension("a/b.c"))
|
||||
asserts.equals(env, ("a.b/c", ".d"), paths.split_extension("a.b/c.d"))
|
||||
asserts.equals(env, (".a/b", ".c"), paths.split_extension(".a/b.c"))
|
||||
asserts.equals(env, (".a", ".b"), paths.split_extension(".a.b"))
|
||||
# Now try some things that will actually get split.
|
||||
asserts.equals(env, ("a", ".b"), paths.split_extension("a.b"))
|
||||
asserts.equals(env, ("a.b", ".c"), paths.split_extension("a.b.c"))
|
||||
asserts.equals(env, ("a/b", ".c"), paths.split_extension("a/b.c"))
|
||||
asserts.equals(env, ("a.b/c", ".d"), paths.split_extension("a.b/c.d"))
|
||||
asserts.equals(env, (".a/b", ".c"), paths.split_extension(".a/b.c"))
|
||||
asserts.equals(env, (".a", ".b"), paths.split_extension(".a.b"))
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
split_extension_test = unittest.make(_split_extension_test)
|
||||
|
||||
|
||||
def paths_test_suite():
|
||||
"""Creates the test targets and test suite for paths.bzl tests."""
|
||||
unittest.suite(
|
||||
"paths_tests",
|
||||
basename_test,
|
||||
dirname_test,
|
||||
is_absolute_test,
|
||||
join_test,
|
||||
normalize_test,
|
||||
relativize_test,
|
||||
replace_extension_test,
|
||||
split_extension_test,
|
||||
)
|
||||
"""Creates the test targets and test suite for paths.bzl tests."""
|
||||
unittest.suite(
|
||||
"paths_tests",
|
||||
basename_test,
|
||||
dirname_test,
|
||||
is_absolute_test,
|
||||
join_test,
|
||||
normalize_test,
|
||||
relativize_test,
|
||||
replace_extension_test,
|
||||
split_extension_test,
|
||||
)
|
||||
|
|
|
@ -14,40 +14,51 @@
|
|||
|
||||
"""Unit tests for selects.bzl."""
|
||||
|
||||
load("//:lib.bzl", "selects", "asserts", "unittest")
|
||||
|
||||
load("//:lib.bzl", "asserts", "selects", "unittest")
|
||||
|
||||
def _with_or_test(ctx):
|
||||
"""Unit tests for with_or."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for with_or."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
# We actually test on with_or_dict because Skylark can't get the
|
||||
# dictionary from a select().
|
||||
# We actually test on with_or_dict because Skylark can't get the
|
||||
# dictionary from a select().
|
||||
|
||||
# Test select()-compatible input syntax.
|
||||
input_dict = {":foo": ":d1", "//conditions:default": ":d1"}
|
||||
asserts.equals(env, input_dict, selects.with_or_dict(input_dict))
|
||||
# Test select()-compatible input syntax.
|
||||
input_dict = {":foo": ":d1", "//conditions:default": ":d1"}
|
||||
asserts.equals(env, input_dict, selects.with_or_dict(input_dict))
|
||||
|
||||
# Test OR syntax.
|
||||
or_dict = {(":foo", ":bar"): ":d1"}
|
||||
asserts.equals(env, {":foo": ":d1", ":bar": ":d1"},
|
||||
selects.with_or_dict(or_dict))
|
||||
# Test OR syntax.
|
||||
or_dict = {(":foo", ":bar"): ":d1"}
|
||||
asserts.equals(
|
||||
env,
|
||||
{":foo": ":d1", ":bar": ":d1"},
|
||||
selects.with_or_dict(or_dict),
|
||||
)
|
||||
|
||||
# Test mixed syntax.
|
||||
mixed_dict = {":foo": ":d1", (":bar", ":baz"): ":d2",
|
||||
"//conditions:default": ":d3"}
|
||||
asserts.equals(env, {":foo": ":d1", ":bar": ":d2", ":baz": ":d2",
|
||||
"//conditions:default": ":d3"},
|
||||
selects.with_or_dict(mixed_dict))
|
||||
# Test mixed syntax.
|
||||
mixed_dict = {
|
||||
":foo": ":d1",
|
||||
(":bar", ":baz"): ":d2",
|
||||
"//conditions:default": ":d3",
|
||||
}
|
||||
asserts.equals(
|
||||
env,
|
||||
{
|
||||
":foo": ":d1",
|
||||
":bar": ":d2",
|
||||
":baz": ":d2",
|
||||
"//conditions:default": ":d3",
|
||||
},
|
||||
selects.with_or_dict(mixed_dict),
|
||||
)
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
with_or_test = unittest.make(_with_or_test)
|
||||
|
||||
|
||||
def selects_test_suite():
|
||||
"""Creates the test targets and test suite for selects.bzl tests."""
|
||||
unittest.suite(
|
||||
"selects_tests",
|
||||
with_or_test,
|
||||
)
|
||||
"""Creates the test targets and test suite for selects.bzl tests."""
|
||||
unittest.suite(
|
||||
"selects_tests",
|
||||
with_or_test,
|
||||
)
|
||||
|
|
|
@ -14,146 +14,139 @@
|
|||
|
||||
"""Unit tests for sets.bzl."""
|
||||
|
||||
load("//:lib.bzl", "sets", "asserts", "unittest")
|
||||
|
||||
load("//:lib.bzl", "asserts", "sets", "unittest")
|
||||
|
||||
def _is_equal_test(ctx):
|
||||
"""Unit tests for sets.is_equal."""
|
||||
"""Unit tests for sets.is_equal."""
|
||||
|
||||
# Note that if this test fails, the results for the other `sets` tests will
|
||||
# be inconclusive because they use `asserts.set_equals`, which in turn calls
|
||||
# `sets.is_equal`.
|
||||
env = unittest.begin(ctx)
|
||||
# Note that if this test fails, the results for the other `sets` tests will
|
||||
# be inconclusive because they use `asserts.set_equals`, which in turn calls
|
||||
# `sets.is_equal`.
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
asserts.true(env, sets.is_equal([], []))
|
||||
asserts.false(env, sets.is_equal([], [1]))
|
||||
asserts.false(env, sets.is_equal([1], []))
|
||||
asserts.true(env, sets.is_equal([1], [1]))
|
||||
asserts.false(env, sets.is_equal([1], [1, 2]))
|
||||
asserts.false(env, sets.is_equal([1], [2]))
|
||||
asserts.false(env, sets.is_equal([1], depset([1, 2])))
|
||||
asserts.true(env, sets.is_equal([], []))
|
||||
asserts.false(env, sets.is_equal([], [1]))
|
||||
asserts.false(env, sets.is_equal([1], []))
|
||||
asserts.true(env, sets.is_equal([1], [1]))
|
||||
asserts.false(env, sets.is_equal([1], [1, 2]))
|
||||
asserts.false(env, sets.is_equal([1], [2]))
|
||||
asserts.false(env, sets.is_equal([1], depset([1, 2])))
|
||||
|
||||
# Verify that the implementation is not using == on the sets directly.
|
||||
asserts.true(env, sets.is_equal(depset([1]), depset([1])))
|
||||
# Verify that the implementation is not using == on the sets directly.
|
||||
asserts.true(env, sets.is_equal(depset([1]), depset([1])))
|
||||
|
||||
# If passing a list, verify that duplicate elements are ignored.
|
||||
asserts.true(env, sets.is_equal([1, 1], [1]))
|
||||
# If passing a list, verify that duplicate elements are ignored.
|
||||
asserts.true(env, sets.is_equal([1, 1], [1]))
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
is_equal_test = unittest.make(_is_equal_test)
|
||||
|
||||
|
||||
def _is_subset_test(ctx):
|
||||
"""Unit tests for sets.is_subset."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for sets.is_subset."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
asserts.true(env, sets.is_subset([], []))
|
||||
asserts.true(env, sets.is_subset([], [1]))
|
||||
asserts.false(env, sets.is_subset([1], []))
|
||||
asserts.true(env, sets.is_subset([1], [1]))
|
||||
asserts.true(env, sets.is_subset([1], [1, 2]))
|
||||
asserts.false(env, sets.is_subset([1], [2]))
|
||||
asserts.true(env, sets.is_subset([1], depset([1, 2])))
|
||||
asserts.true(env, sets.is_subset([], []))
|
||||
asserts.true(env, sets.is_subset([], [1]))
|
||||
asserts.false(env, sets.is_subset([1], []))
|
||||
asserts.true(env, sets.is_subset([1], [1]))
|
||||
asserts.true(env, sets.is_subset([1], [1, 2]))
|
||||
asserts.false(env, sets.is_subset([1], [2]))
|
||||
asserts.true(env, sets.is_subset([1], depset([1, 2])))
|
||||
|
||||
# If passing a list, verify that duplicate elements are ignored.
|
||||
asserts.true(env, sets.is_subset([1, 1], [1, 2]))
|
||||
# If passing a list, verify that duplicate elements are ignored.
|
||||
asserts.true(env, sets.is_subset([1, 1], [1, 2]))
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
is_subset_test = unittest.make(_is_subset_test)
|
||||
|
||||
|
||||
def _disjoint_test(ctx):
|
||||
"""Unit tests for sets.disjoint."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for sets.disjoint."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
asserts.true(env, sets.disjoint([], []))
|
||||
asserts.true(env, sets.disjoint([], [1]))
|
||||
asserts.true(env, sets.disjoint([1], []))
|
||||
asserts.false(env, sets.disjoint([1], [1]))
|
||||
asserts.false(env, sets.disjoint([1], [1, 2]))
|
||||
asserts.true(env, sets.disjoint([1], [2]))
|
||||
asserts.true(env, sets.disjoint([1], depset([2])))
|
||||
asserts.true(env, sets.disjoint([], []))
|
||||
asserts.true(env, sets.disjoint([], [1]))
|
||||
asserts.true(env, sets.disjoint([1], []))
|
||||
asserts.false(env, sets.disjoint([1], [1]))
|
||||
asserts.false(env, sets.disjoint([1], [1, 2]))
|
||||
asserts.true(env, sets.disjoint([1], [2]))
|
||||
asserts.true(env, sets.disjoint([1], depset([2])))
|
||||
|
||||
# If passing a list, verify that duplicate elements are ignored.
|
||||
asserts.false(env, sets.disjoint([1, 1], [1, 2]))
|
||||
# If passing a list, verify that duplicate elements are ignored.
|
||||
asserts.false(env, sets.disjoint([1, 1], [1, 2]))
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
disjoint_test = unittest.make(_disjoint_test)
|
||||
|
||||
|
||||
def _intersection_test(ctx):
|
||||
"""Unit tests for sets.intersection."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for sets.intersection."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
asserts.set_equals(env, [], sets.intersection([], []))
|
||||
asserts.set_equals(env, [], sets.intersection([], [1]))
|
||||
asserts.set_equals(env, [], sets.intersection([1], []))
|
||||
asserts.set_equals(env, [1], sets.intersection([1], [1]))
|
||||
asserts.set_equals(env, [1], sets.intersection([1], [1, 2]))
|
||||
asserts.set_equals(env, [], sets.intersection([1], [2]))
|
||||
asserts.set_equals(env, [1], sets.intersection([1], depset([1])))
|
||||
asserts.set_equals(env, [], sets.intersection([], []))
|
||||
asserts.set_equals(env, [], sets.intersection([], [1]))
|
||||
asserts.set_equals(env, [], sets.intersection([1], []))
|
||||
asserts.set_equals(env, [1], sets.intersection([1], [1]))
|
||||
asserts.set_equals(env, [1], sets.intersection([1], [1, 2]))
|
||||
asserts.set_equals(env, [], sets.intersection([1], [2]))
|
||||
asserts.set_equals(env, [1], sets.intersection([1], depset([1])))
|
||||
|
||||
# If passing a list, verify that duplicate elements are ignored.
|
||||
asserts.set_equals(env, [1], sets.intersection([1, 1], [1, 2]))
|
||||
# If passing a list, verify that duplicate elements are ignored.
|
||||
asserts.set_equals(env, [1], sets.intersection([1, 1], [1, 2]))
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
intersection_test = unittest.make(_intersection_test)
|
||||
|
||||
|
||||
def _union_test(ctx):
|
||||
"""Unit tests for sets.union."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for sets.union."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
asserts.set_equals(env, [], sets.union())
|
||||
asserts.set_equals(env, [1], sets.union([1]))
|
||||
asserts.set_equals(env, [], sets.union([], []))
|
||||
asserts.set_equals(env, [1], sets.union([], [1]))
|
||||
asserts.set_equals(env, [1], sets.union([1], []))
|
||||
asserts.set_equals(env, [1], sets.union([1], [1]))
|
||||
asserts.set_equals(env, [1, 2], sets.union([1], [1, 2]))
|
||||
asserts.set_equals(env, [1, 2], sets.union([1], [2]))
|
||||
asserts.set_equals(env, [1], sets.union([1], depset([1])))
|
||||
asserts.set_equals(env, [], sets.union())
|
||||
asserts.set_equals(env, [1], sets.union([1]))
|
||||
asserts.set_equals(env, [], sets.union([], []))
|
||||
asserts.set_equals(env, [1], sets.union([], [1]))
|
||||
asserts.set_equals(env, [1], sets.union([1], []))
|
||||
asserts.set_equals(env, [1], sets.union([1], [1]))
|
||||
asserts.set_equals(env, [1, 2], sets.union([1], [1, 2]))
|
||||
asserts.set_equals(env, [1, 2], sets.union([1], [2]))
|
||||
asserts.set_equals(env, [1], sets.union([1], depset([1])))
|
||||
|
||||
# If passing a list, verify that duplicate elements are ignored.
|
||||
asserts.set_equals(env, [1, 2], sets.union([1, 1], [1, 2]))
|
||||
# If passing a list, verify that duplicate elements are ignored.
|
||||
asserts.set_equals(env, [1, 2], sets.union([1, 1], [1, 2]))
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
union_test = unittest.make(_union_test)
|
||||
|
||||
|
||||
def _difference_test(ctx):
|
||||
"""Unit tests for sets.difference."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for sets.difference."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
asserts.set_equals(env, [], sets.difference([], []))
|
||||
asserts.set_equals(env, [], sets.difference([], [1]))
|
||||
asserts.set_equals(env, [1], sets.difference([1], []))
|
||||
asserts.set_equals(env, [], sets.difference([1], [1]))
|
||||
asserts.set_equals(env, [], sets.difference([1], [1, 2]))
|
||||
asserts.set_equals(env, [1], sets.difference([1], [2]))
|
||||
asserts.set_equals(env, [], sets.difference([1], depset([1])))
|
||||
asserts.set_equals(env, [], sets.difference([], []))
|
||||
asserts.set_equals(env, [], sets.difference([], [1]))
|
||||
asserts.set_equals(env, [1], sets.difference([1], []))
|
||||
asserts.set_equals(env, [], sets.difference([1], [1]))
|
||||
asserts.set_equals(env, [], sets.difference([1], [1, 2]))
|
||||
asserts.set_equals(env, [1], sets.difference([1], [2]))
|
||||
asserts.set_equals(env, [], sets.difference([1], depset([1])))
|
||||
|
||||
# If passing a list, verify that duplicate elements are ignored.
|
||||
asserts.set_equals(env, [2], sets.difference([1, 2], [1, 1]))
|
||||
# If passing a list, verify that duplicate elements are ignored.
|
||||
asserts.set_equals(env, [2], sets.difference([1, 2], [1, 1]))
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
difference_test = unittest.make(_difference_test)
|
||||
|
||||
|
||||
def sets_test_suite():
|
||||
"""Creates the test targets and test suite for sets.bzl tests."""
|
||||
unittest.suite(
|
||||
"sets_tests",
|
||||
disjoint_test,
|
||||
intersection_test,
|
||||
is_equal_test,
|
||||
is_subset_test,
|
||||
difference_test,
|
||||
union_test,
|
||||
)
|
||||
"""Creates the test targets and test suite for sets.bzl tests."""
|
||||
unittest.suite(
|
||||
"sets_tests",
|
||||
disjoint_test,
|
||||
intersection_test,
|
||||
is_equal_test,
|
||||
is_subset_test,
|
||||
difference_test,
|
||||
union_test,
|
||||
)
|
||||
|
|
|
@ -14,98 +14,94 @@
|
|||
|
||||
"""Unit tests for shell.bzl."""
|
||||
|
||||
load("//:lib.bzl", "shell", "asserts", "unittest")
|
||||
|
||||
load("//:lib.bzl", "asserts", "shell", "unittest")
|
||||
|
||||
def _shell_array_literal_test(ctx):
|
||||
"""Unit tests for shell.array_literal."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for shell.array_literal."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
asserts.equals(env, "()", shell.array_literal([]))
|
||||
asserts.equals(env, "('1')", shell.array_literal([1]))
|
||||
asserts.equals(env, "('1' '2' '3')", shell.array_literal([1, 2, 3]))
|
||||
asserts.equals(env, "('$foo')", shell.array_literal(["$foo"]))
|
||||
asserts.equals(env, "('qu\"o\"te')", shell.array_literal(['qu"o"te']))
|
||||
asserts.equals(env, "()", shell.array_literal([]))
|
||||
asserts.equals(env, "('1')", shell.array_literal([1]))
|
||||
asserts.equals(env, "('1' '2' '3')", shell.array_literal([1, 2, 3]))
|
||||
asserts.equals(env, "('$foo')", shell.array_literal(["$foo"]))
|
||||
asserts.equals(env, "('qu\"o\"te')", shell.array_literal(['qu"o"te']))
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
shell_array_literal_test = unittest.make(_shell_array_literal_test)
|
||||
|
||||
|
||||
def _shell_quote_test(ctx):
|
||||
"""Unit tests for shell.quote."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for shell.quote."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
asserts.equals(env, "'foo'", shell.quote("foo"))
|
||||
asserts.equals(env, "'foo bar'", shell.quote("foo bar"))
|
||||
asserts.equals(env, "'three spaces'", shell.quote("three spaces"))
|
||||
asserts.equals(env, "' leading'", shell.quote(" leading"))
|
||||
asserts.equals(env, "'trailing '", shell.quote("trailing "))
|
||||
asserts.equals(env, "'new\nline'", shell.quote("new\nline"))
|
||||
asserts.equals(env, "'tab\tcharacter'", shell.quote("tab\tcharacter"))
|
||||
asserts.equals(env, "'$foo'", shell.quote("$foo"))
|
||||
asserts.equals(env, "'qu\"o\"te'", shell.quote('qu"o"te'))
|
||||
asserts.equals(env, "'it'\\''s'", shell.quote("it's"))
|
||||
asserts.equals(env, "'foo\\bar'", shell.quote(r"foo\bar"))
|
||||
asserts.equals(env, "'back`echo q`uote'", shell.quote(r"back`echo q`uote"))
|
||||
asserts.equals(env, "'foo'", shell.quote("foo"))
|
||||
asserts.equals(env, "'foo bar'", shell.quote("foo bar"))
|
||||
asserts.equals(env, "'three spaces'", shell.quote("three spaces"))
|
||||
asserts.equals(env, "' leading'", shell.quote(" leading"))
|
||||
asserts.equals(env, "'trailing '", shell.quote("trailing "))
|
||||
asserts.equals(env, "'new\nline'", shell.quote("new\nline"))
|
||||
asserts.equals(env, "'tab\tcharacter'", shell.quote("tab\tcharacter"))
|
||||
asserts.equals(env, "'$foo'", shell.quote("$foo"))
|
||||
asserts.equals(env, "'qu\"o\"te'", shell.quote('qu"o"te'))
|
||||
asserts.equals(env, "'it'\\''s'", shell.quote("it's"))
|
||||
asserts.equals(env, "'foo\\bar'", shell.quote("foo\\bar"))
|
||||
asserts.equals(env, "'back`echo q`uote'", shell.quote("back`echo q`uote"))
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
shell_quote_test = unittest.make(_shell_quote_test)
|
||||
|
||||
|
||||
def _shell_spawn_e2e_test_impl(ctx):
|
||||
"""Test spawning a real shell."""
|
||||
args = [
|
||||
"foo",
|
||||
"foo bar",
|
||||
"three spaces",
|
||||
" leading",
|
||||
"trailing ",
|
||||
"new\nline",
|
||||
"tab\tcharacter",
|
||||
"$foo",
|
||||
'qu"o"te',
|
||||
"it's",
|
||||
r"foo\bar",
|
||||
"back`echo q`uote",
|
||||
]
|
||||
script_content = "\n".join([
|
||||
"#!/bin/bash",
|
||||
"myarray=" + shell.array_literal(args),
|
||||
'output=$(echo "${myarray[@]}")',
|
||||
# For logging:
|
||||
'echo "DEBUG: output=[${output}]" >&2',
|
||||
# The following is a shell representation of what the echo of the quoted
|
||||
# array will look like. It looks a bit confusing considering it's shell
|
||||
# quoted into Python. Shell using single quotes to minimize shell
|
||||
# escaping, so only the single quote needs to be escaped as '\'', all
|
||||
# others are essentially kept literally.
|
||||
"expected='foo foo bar three spaces leading trailing new",
|
||||
"line tab\tcharacter $foo qu\"o\"te it'\\''s foo\\bar back`echo q`uote'",
|
||||
'[[ "${output}" == "${expected}" ]]',
|
||||
])
|
||||
script_file = ctx.actions.declare_file("%s.sh" % (ctx.label.name))
|
||||
ctx.actions.write(
|
||||
output = script_file,
|
||||
content = script_content,
|
||||
is_executable = True,
|
||||
)
|
||||
return [
|
||||
DefaultInfo(executable=script_file),
|
||||
]
|
||||
"""Test spawning a real shell."""
|
||||
args = [
|
||||
"foo",
|
||||
"foo bar",
|
||||
"three spaces",
|
||||
" leading",
|
||||
"trailing ",
|
||||
"new\nline",
|
||||
"tab\tcharacter",
|
||||
"$foo",
|
||||
'qu"o"te',
|
||||
"it's",
|
||||
"foo\\bar",
|
||||
"back`echo q`uote",
|
||||
]
|
||||
script_content = "\n".join([
|
||||
"#!/bin/bash",
|
||||
"myarray=" + shell.array_literal(args),
|
||||
'output=$(echo "${myarray[@]}")',
|
||||
# For logging:
|
||||
'echo "DEBUG: output=[${output}]" >&2',
|
||||
# The following is a shell representation of what the echo of the quoted
|
||||
# array will look like. It looks a bit confusing considering it's shell
|
||||
# quoted into Python. Shell using single quotes to minimize shell
|
||||
# escaping, so only the single quote needs to be escaped as '\'', all
|
||||
# others are essentially kept literally.
|
||||
"expected='foo foo bar three spaces leading trailing new",
|
||||
"line tab\tcharacter $foo qu\"o\"te it'\\''s foo\\bar back`echo q`uote'",
|
||||
'[[ "${output}" == "${expected}" ]]',
|
||||
])
|
||||
script_file = ctx.actions.declare_file("%s.sh" % (ctx.label.name))
|
||||
ctx.actions.write(
|
||||
output = script_file,
|
||||
content = script_content,
|
||||
is_executable = True,
|
||||
)
|
||||
return [
|
||||
DefaultInfo(executable = script_file),
|
||||
]
|
||||
|
||||
shell_spawn_e2e_test = rule(
|
||||
test = True,
|
||||
implementation = _shell_spawn_e2e_test_impl,
|
||||
)
|
||||
|
||||
|
||||
def shell_test_suite():
|
||||
"""Creates the test targets and test suite for shell.bzl tests."""
|
||||
unittest.suite(
|
||||
"shell_tests",
|
||||
shell_array_literal_test,
|
||||
shell_quote_test,
|
||||
shell_spawn_e2e_test,
|
||||
)
|
||||
"""Creates the test targets and test suite for shell.bzl tests."""
|
||||
unittest.suite(
|
||||
"shell_tests",
|
||||
shell_array_literal_test,
|
||||
shell_quote_test,
|
||||
shell_spawn_e2e_test,
|
||||
)
|
||||
|
|
|
@ -14,36 +14,40 @@
|
|||
|
||||
"""Unit tests for structs.bzl."""
|
||||
|
||||
load("//:lib.bzl", "structs", "asserts", "unittest")
|
||||
|
||||
load("//:lib.bzl", "asserts", "structs", "unittest")
|
||||
|
||||
def _add_test(ctx):
|
||||
"""Unit tests for dicts.add."""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for dicts.add."""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
# Test zero- and one-argument behavior.
|
||||
asserts.equals(env, {}, structs.to_dict(struct()))
|
||||
asserts.equals(env, {"a": 1}, structs.to_dict(struct(a=1)))
|
||||
# Test zero- and one-argument behavior.
|
||||
asserts.equals(env, {}, structs.to_dict(struct()))
|
||||
asserts.equals(env, {"a": 1}, structs.to_dict(struct(a = 1)))
|
||||
|
||||
# Test simple two-argument behavior.
|
||||
asserts.equals(env, {"a": 1, "b": 2}, structs.to_dict(struct(a=1, b=2)))
|
||||
# Test simple two-argument behavior.
|
||||
asserts.equals(env, {"a": 1, "b": 2}, structs.to_dict(struct(a = 1, b = 2)))
|
||||
|
||||
# Test simple more-than-two-argument behavior.
|
||||
asserts.equals(env, {"a": 1, "b": 2, "c": 3, "d": 4},
|
||||
structs.to_dict(struct(a=1, b=2, c=3, d=4)))
|
||||
# Test simple more-than-two-argument behavior.
|
||||
asserts.equals(
|
||||
env,
|
||||
{"a": 1, "b": 2, "c": 3, "d": 4},
|
||||
structs.to_dict(struct(a = 1, b = 2, c = 3, d = 4)),
|
||||
)
|
||||
|
||||
# Test transformation is not applied transitively.
|
||||
asserts.equals(env, {"a": 1, "b": struct(bb=1)},
|
||||
structs.to_dict(struct(a=1, b=struct(bb=1))))
|
||||
# Test transformation is not applied transitively.
|
||||
asserts.equals(
|
||||
env,
|
||||
{"a": 1, "b": struct(bb = 1)},
|
||||
structs.to_dict(struct(a = 1, b = struct(bb = 1))),
|
||||
)
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
add_test = unittest.make(_add_test)
|
||||
|
||||
|
||||
def structs_test_suite():
|
||||
"""Creates the test targets and test suite for structs.bzl tests."""
|
||||
unittest.suite(
|
||||
"structs_tests",
|
||||
add_test,
|
||||
)
|
||||
"""Creates the test targets and test suite for structs.bzl tests."""
|
||||
unittest.suite(
|
||||
"structs_tests",
|
||||
add_test,
|
||||
)
|
||||
|
|
|
@ -13,14 +13,12 @@
|
|||
# limitations under the License.
|
||||
"""Unit tests for types.bzl."""
|
||||
|
||||
load("//:lib.bzl", "types", "asserts", "unittest")
|
||||
|
||||
load("//:lib.bzl", "asserts", "types", "unittest")
|
||||
|
||||
def _a_function():
|
||||
"""A dummy function for testing."""
|
||||
pass
|
||||
|
||||
|
||||
def _is_string_test(ctx):
|
||||
"""Unit tests for types.is_string."""
|
||||
|
||||
|
@ -39,10 +37,8 @@ def _is_string_test(ctx):
|
|||
|
||||
unittest.end(env)
|
||||
|
||||
|
||||
is_string_test = unittest.make(_is_string_test)
|
||||
|
||||
|
||||
def _is_bool_test(ctx):
|
||||
"""Unit tests for types.is_bool."""
|
||||
|
||||
|
@ -61,10 +57,8 @@ def _is_bool_test(ctx):
|
|||
|
||||
unittest.end(env)
|
||||
|
||||
|
||||
is_bool_test = unittest.make(_is_bool_test)
|
||||
|
||||
|
||||
def _is_list_test(ctx):
|
||||
"""Unit tests for types.is_list."""
|
||||
|
||||
|
@ -83,10 +77,8 @@ def _is_list_test(ctx):
|
|||
|
||||
unittest.end(env)
|
||||
|
||||
|
||||
is_list_test = unittest.make(_is_list_test)
|
||||
|
||||
|
||||
def _is_none_test(ctx):
|
||||
"""Unit tests for types.is_none."""
|
||||
|
||||
|
@ -105,10 +97,8 @@ def _is_none_test(ctx):
|
|||
|
||||
unittest.end(env)
|
||||
|
||||
|
||||
is_none_test = unittest.make(_is_none_test)
|
||||
|
||||
|
||||
def _is_int_test(ctx):
|
||||
"""Unit tests for types.is_int."""
|
||||
|
||||
|
@ -128,17 +118,15 @@ def _is_int_test(ctx):
|
|||
|
||||
unittest.end(env)
|
||||
|
||||
|
||||
is_int_test = unittest.make(_is_int_test)
|
||||
|
||||
|
||||
def _is_tuple_test(ctx):
|
||||
"""Unit tests for types.is_tuple."""
|
||||
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
asserts.true(env, types.is_tuple(()))
|
||||
asserts.true(env, types.is_tuple((1, )))
|
||||
asserts.true(env, types.is_tuple((1,)))
|
||||
|
||||
asserts.false(env, types.is_tuple(1))
|
||||
asserts.false(env, types.is_tuple("s"))
|
||||
|
@ -151,17 +139,15 @@ def _is_tuple_test(ctx):
|
|||
|
||||
unittest.end(env)
|
||||
|
||||
|
||||
is_tuple_test = unittest.make(_is_tuple_test)
|
||||
|
||||
|
||||
def _is_dict_test(ctx):
|
||||
"""Unit tests for types.is_dict."""
|
||||
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
asserts.true(env, types.is_dict({}))
|
||||
asserts.true(env, types.is_dict({'key': 'value'}))
|
||||
asserts.true(env, types.is_dict({"key": "value"}))
|
||||
|
||||
asserts.false(env, types.is_dict(1))
|
||||
asserts.false(env, types.is_dict("s"))
|
||||
|
@ -174,10 +160,8 @@ def _is_dict_test(ctx):
|
|||
|
||||
unittest.end(env)
|
||||
|
||||
|
||||
is_dict_test = unittest.make(_is_dict_test)
|
||||
|
||||
|
||||
def _is_function_test(ctx):
|
||||
"""Unit tests for types.is_dict."""
|
||||
|
||||
|
@ -196,10 +180,8 @@ def _is_function_test(ctx):
|
|||
|
||||
unittest.end(env)
|
||||
|
||||
|
||||
is_function_test = unittest.make(_is_function_test)
|
||||
|
||||
|
||||
def types_test_suite():
|
||||
"""Creates the test targets and test suite for types.bzl tests."""
|
||||
unittest.suite(
|
||||
|
|
|
@ -14,55 +14,55 @@
|
|||
|
||||
"""Unit tests for versions.bzl."""
|
||||
|
||||
load("//:lib.bzl", "versions", "asserts", "unittest")
|
||||
load("//:lib.bzl", "asserts", "unittest", "versions")
|
||||
|
||||
def _parse_test(ctx):
|
||||
"""Unit tests for versions.parse"""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for versions.parse"""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
asserts.equals(env, (0, 10, 0), versions.parse("0.10.0rc1 abcd123"))
|
||||
asserts.equals(env, (0, 4, 0), versions.parse("0.4.0 abcd123"))
|
||||
asserts.equals(env, (0, 4, 0), versions.parse("0.4.0"))
|
||||
asserts.equals(env, (0, 4, 0), versions.parse("0.4.0rc"))
|
||||
asserts.equals(env, (0, 10, 0), versions.parse("0.10.0rc1 abcd123"))
|
||||
asserts.equals(env, (0, 4, 0), versions.parse("0.4.0 abcd123"))
|
||||
asserts.equals(env, (0, 4, 0), versions.parse("0.4.0"))
|
||||
asserts.equals(env, (0, 4, 0), versions.parse("0.4.0rc"))
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
def _version_comparison_test(ctx):
|
||||
"""Unit tests for versions.is_at_least and is_at_most"""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for versions.is_at_least and is_at_most"""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
asserts.false(env, versions.is_at_least("0.11.0 123abcd", "0.10.0rc1 abcd123"))
|
||||
asserts.true(env, versions.is_at_least("0.9.0", "0.10.0rc2"))
|
||||
asserts.true(env, versions.is_at_least("0.9.0", "0.9.0rc3"))
|
||||
asserts.true(env, versions.is_at_least("0.9.0", "1.2.3"))
|
||||
asserts.false(env, versions.is_at_least("0.11.0 123abcd", "0.10.0rc1 abcd123"))
|
||||
asserts.true(env, versions.is_at_least("0.9.0", "0.10.0rc2"))
|
||||
asserts.true(env, versions.is_at_least("0.9.0", "0.9.0rc3"))
|
||||
asserts.true(env, versions.is_at_least("0.9.0", "1.2.3"))
|
||||
|
||||
asserts.false(env, versions.is_at_most("0.4.0 123abcd", "0.10.0rc1 abcd123"))
|
||||
asserts.true(env, versions.is_at_most("0.4.0", "0.3.0rc2"))
|
||||
asserts.true(env, versions.is_at_most("0.4.0", "0.4.0rc3"))
|
||||
asserts.true(env, versions.is_at_most("1.4.0", "0.4.0rc3"))
|
||||
asserts.false(env, versions.is_at_most("0.4.0 123abcd", "0.10.0rc1 abcd123"))
|
||||
asserts.true(env, versions.is_at_most("0.4.0", "0.3.0rc2"))
|
||||
asserts.true(env, versions.is_at_most("0.4.0", "0.4.0rc3"))
|
||||
asserts.true(env, versions.is_at_most("1.4.0", "0.4.0rc3"))
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
def _check_test(ctx):
|
||||
"""Unit tests for versions.check"""
|
||||
env = unittest.begin(ctx)
|
||||
"""Unit tests for versions.check"""
|
||||
env = unittest.begin(ctx)
|
||||
|
||||
asserts.equals(env, None, versions.check("0.4.5 abcdef", bazel_version="0.10.0rc1 abcd123"))
|
||||
asserts.equals(env, None, versions.check("0.4.5", bazel_version="0.4.5"))
|
||||
asserts.equals(env, None, versions.check("0.4.5", bazel_version="0.10.0rc1 abcd123"))
|
||||
asserts.equals(env, None, versions.check("0.4.5", maximum_bazel_version="1.0.0", bazel_version="0.10.0rc1 abcd123"))
|
||||
asserts.equals(env, None, versions.check("0.4.5 abcdef", bazel_version = "0.10.0rc1 abcd123"))
|
||||
asserts.equals(env, None, versions.check("0.4.5", bazel_version = "0.4.5"))
|
||||
asserts.equals(env, None, versions.check("0.4.5", bazel_version = "0.10.0rc1 abcd123"))
|
||||
asserts.equals(env, None, versions.check("0.4.5", maximum_bazel_version = "1.0.0", bazel_version = "0.10.0rc1 abcd123"))
|
||||
|
||||
unittest.end(env)
|
||||
unittest.end(env)
|
||||
|
||||
parse_test = unittest.make(_parse_test)
|
||||
version_comparison_test = unittest.make(_version_comparison_test)
|
||||
check_test = unittest.make(_check_test)
|
||||
|
||||
def versions_test_suite():
|
||||
"""Creates the test targets and test suite for versions.bzl tests."""
|
||||
unittest.suite(
|
||||
"versions_tests",
|
||||
parse_test,
|
||||
version_comparison_test,
|
||||
check_test,
|
||||
)
|
||||
"""Creates the test targets and test suite for versions.bzl tests."""
|
||||
unittest.suite(
|
||||
"versions_tests",
|
||||
parse_test,
|
||||
version_comparison_test,
|
||||
check_test,
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue