blob: 32d517f60d289909eb8cc9b739527cce743ee000 [file] [log] [blame]
# Copyright 2017 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Unit tests for shell.bzl."""
load("//lib:shell.bzl", "shell")
load("//lib:unittest.bzl", "asserts", "unittest")
def _shell_array_literal_test(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']))
return 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)
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"))
return unittest.end(env)
shell_quote_test = unittest.make(_shell_quote_test)
def _shell_args_test_gen_impl(ctx):
"""Test argument escaping: this rule writes a script for a sh_test."""
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}" ]]',
])
out = ctx.actions.declare_file(ctx.label.name + ".sh")
ctx.actions.write(
output = out,
content = script_content,
is_executable = True,
)
return [DefaultInfo(files = depset([out]))]
shell_args_test_gen = rule(
implementation = _shell_args_test_gen_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,
)