diff --git a/.travis_build.sh b/.travis_build.sh index 1d27258..da84e28 100755 --- a/.travis_build.sh +++ b/.travis_build.sh @@ -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 diff --git a/lib.bzl b/lib.bzl index bf6bd42..bdea5ff 100644 --- a/lib.bzl +++ b/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 diff --git a/lib/collections.bzl b/lib/collections.bzl index 4a44c93..de612ff 100644 --- a/lib/collections.bzl +++ b/lib/collections.bzl @@ -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, ) diff --git a/lib/dicts.bzl b/lib/dicts.bzl index b1a0682..f702fa9 100644 --- a/lib/dicts.bzl +++ b/lib/dicts.bzl @@ -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, ) diff --git a/lib/new_sets.bzl b/lib/new_sets.bzl index 0a32aba..b6fb99d 100644 --- a/lib/new_sets.bzl +++ b/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, ) diff --git a/lib/partial.bzl b/lib/partial.bzl index 8bda88e..d70aa0f 100644 --- a/lib/partial.bzl +++ b/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, ) diff --git a/lib/paths.bzl b/lib/paths.bzl index 3722ac9..8e3fcae 100644 --- a/lib/paths.bzl +++ b/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, ) diff --git a/lib/selects.bzl b/lib/selects.bzl index 642ee99..4f9fea4 100755 --- a/lib/selects.bzl +++ b/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, ) diff --git a/lib/sets.bzl b/lib/sets.bzl index f3d1c08..0c300fa 100644 --- a/lib/sets.bzl +++ b/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, diff --git a/lib/shell.bzl b/lib/shell.bzl index ea79312..4a851ca 100644 --- a/lib/shell.bzl +++ b/lib/shell.bzl @@ -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, ) diff --git a/lib/structs.bzl b/lib/structs.bzl index 4ba6138..f291152 100644 --- a/lib/structs.bzl +++ b/lib/structs.bzl @@ -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, ) diff --git a/lib/types.bzl b/lib/types.bzl index b58774d..8baaeb7 100644 --- a/lib/types.bzl +++ b/lib/types.bzl @@ -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, ) diff --git a/lib/unittest.bzl b/lib/unittest.bzl index e342ee0..11af89f 100644 --- a/lib/unittest.bzl +++ b/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 "", 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("")[0] - # Derive the name of the implementation function for better test feedback. - # Skylark currently stringifies a function as "", 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("")[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, ) diff --git a/lib/versions.bzl b/lib/versions.bzl index ab89dbe..0298ef4 100644 --- a/lib/versions.bzl +++ b/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, ) diff --git a/skylark_library.bzl b/skylark_library.bzl index 5791b00..a91639d 100644 --- a/skylark_library.bzl +++ b/skylark_library.bzl @@ -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. diff --git a/tests/collections_tests.bzl b/tests/collections_tests.bzl index 0f5cd2c..db39eaf 100644 --- a/tests/collections_tests.bzl +++ b/tests/collections_tests.bzl @@ -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, + ) diff --git a/tests/dicts_tests.bzl b/tests/dicts_tests.bzl index 40b0655..a68cb09 100644 --- a/tests/dicts_tests.bzl +++ b/tests/dicts_tests.bzl @@ -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, + ) diff --git a/tests/new_sets_tests.bzl b/tests/new_sets_tests.bzl index 1b0c1ee..b6d3092 100644 --- a/tests/new_sets_tests.bzl +++ b/tests/new_sets_tests.bzl @@ -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, + ) diff --git a/tests/partial_tests.bzl b/tests/partial_tests.bzl index 6e4768b..a554ee6 100644 --- a/tests/partial_tests.bzl +++ b/tests/partial_tests.bzl @@ -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, + ) diff --git a/tests/paths_tests.bzl b/tests/paths_tests.bzl index c11473d..b8d95ec 100644 --- a/tests/paths_tests.bzl +++ b/tests/paths_tests.bzl @@ -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, + ) diff --git a/tests/selects_tests.bzl b/tests/selects_tests.bzl index 210fd32..59124a2 100644 --- a/tests/selects_tests.bzl +++ b/tests/selects_tests.bzl @@ -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, + ) diff --git a/tests/sets_tests.bzl b/tests/sets_tests.bzl index bddab69..cddcda9 100644 --- a/tests/sets_tests.bzl +++ b/tests/sets_tests.bzl @@ -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, + ) diff --git a/tests/shell_tests.bzl b/tests/shell_tests.bzl index d0a9769..18b7bc7 100644 --- a/tests/shell_tests.bzl +++ b/tests/shell_tests.bzl @@ -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, + ) diff --git a/tests/structs_tests.bzl b/tests/structs_tests.bzl index b072d5b..ba89294 100644 --- a/tests/structs_tests.bzl +++ b/tests/structs_tests.bzl @@ -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, + ) diff --git a/tests/types_tests.bzl b/tests/types_tests.bzl index 5237570..6420ca1 100644 --- a/tests/types_tests.bzl +++ b/tests/types_tests.bzl @@ -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( diff --git a/tests/versions_tests.bzl b/tests/versions_tests.bzl index 1dc01f4..d4234d0 100644 --- a/tests/versions_tests.bzl +++ b/tests/versions_tests.bzl @@ -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, + )