blob: 5b83f9f22ab7c15b6394662d50bb5caf774699da [file] [log] [blame]
Tony Allevato82b3ad62017-10-10 07:59:31 -07001# Copyright 2017 The Bazel Authors. All rights reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""Unit tests for shell.bzl."""
16
Thomas Van Lentenb5f40862018-08-24 15:00:13 -040017load("//lib:shell.bzl", "shell")
18load("//lib:unittest.bzl", "asserts", "unittest")
Tony Allevato82b3ad62017-10-10 07:59:31 -070019
20def _shell_array_literal_test(ctx):
Thomas Van Lentene5203c02018-06-12 13:09:57 -040021 """Unit tests for shell.array_literal."""
22 env = unittest.begin(ctx)
Tony Allevato82b3ad62017-10-10 07:59:31 -070023
Thomas Van Lentene5203c02018-06-12 13:09:57 -040024 asserts.equals(env, "()", shell.array_literal([]))
25 asserts.equals(env, "('1')", shell.array_literal([1]))
26 asserts.equals(env, "('1' '2' '3')", shell.array_literal([1, 2, 3]))
27 asserts.equals(env, "('$foo')", shell.array_literal(["$foo"]))
28 asserts.equals(env, "('qu\"o\"te')", shell.array_literal(['qu"o"te']))
Tony Allevato82b3ad62017-10-10 07:59:31 -070029
László Csomordaf51372018-12-04 16:14:08 +010030 return unittest.end(env)
Tony Allevato82b3ad62017-10-10 07:59:31 -070031
32shell_array_literal_test = unittest.make(_shell_array_literal_test)
33
Tony Allevato82b3ad62017-10-10 07:59:31 -070034def _shell_quote_test(ctx):
Thomas Van Lentene5203c02018-06-12 13:09:57 -040035 """Unit tests for shell.quote."""
36 env = unittest.begin(ctx)
Tony Allevato82b3ad62017-10-10 07:59:31 -070037
Thomas Van Lentene5203c02018-06-12 13:09:57 -040038 asserts.equals(env, "'foo'", shell.quote("foo"))
39 asserts.equals(env, "'foo bar'", shell.quote("foo bar"))
40 asserts.equals(env, "'three spaces'", shell.quote("three spaces"))
41 asserts.equals(env, "' leading'", shell.quote(" leading"))
42 asserts.equals(env, "'trailing '", shell.quote("trailing "))
43 asserts.equals(env, "'new\nline'", shell.quote("new\nline"))
44 asserts.equals(env, "'tab\tcharacter'", shell.quote("tab\tcharacter"))
45 asserts.equals(env, "'$foo'", shell.quote("$foo"))
46 asserts.equals(env, "'qu\"o\"te'", shell.quote('qu"o"te'))
47 asserts.equals(env, "'it'\\''s'", shell.quote("it's"))
48 asserts.equals(env, "'foo\\bar'", shell.quote("foo\\bar"))
49 asserts.equals(env, "'back`echo q`uote'", shell.quote("back`echo q`uote"))
Tony Allevato82b3ad62017-10-10 07:59:31 -070050
László Csomordaf51372018-12-04 16:14:08 +010051 return unittest.end(env)
Tony Allevato82b3ad62017-10-10 07:59:31 -070052
53shell_quote_test = unittest.make(_shell_quote_test)
54
László Csomor4c26bf42019-03-26 10:52:27 +010055def _shell_args_test_gen_impl(ctx):
56 """Test argument escaping: this rule writes a script for a sh_test."""
Thomas Van Lentene5203c02018-06-12 13:09:57 -040057 args = [
58 "foo",
59 "foo bar",
60 "three spaces",
61 " leading",
62 "trailing ",
63 "new\nline",
64 "tab\tcharacter",
65 "$foo",
66 'qu"o"te',
67 "it's",
68 "foo\\bar",
69 "back`echo q`uote",
70 ]
71 script_content = "\n".join([
Yesudeep Mangalapilly8e923ca2021-10-25 06:12:41 -070072 "#!/usr/bin/env bash",
Thomas Van Lentene5203c02018-06-12 13:09:57 -040073 "myarray=" + shell.array_literal(args),
74 'output=$(echo "${myarray[@]}")',
75 # For logging:
76 'echo "DEBUG: output=[${output}]" >&2',
77 # The following is a shell representation of what the echo of the quoted
78 # array will look like. It looks a bit confusing considering it's shell
79 # quoted into Python. Shell using single quotes to minimize shell
80 # escaping, so only the single quote needs to be escaped as '\'', all
81 # others are essentially kept literally.
82 "expected='foo foo bar three spaces leading trailing new",
83 "line tab\tcharacter $foo qu\"o\"te it'\\''s foo\\bar back`echo q`uote'",
84 '[[ "${output}" == "${expected}" ]]',
85 ])
László Csomor4c26bf42019-03-26 10:52:27 +010086 out = ctx.actions.declare_file(ctx.label.name + ".sh")
Thomas Van Lentene5203c02018-06-12 13:09:57 -040087 ctx.actions.write(
László Csomor4c26bf42019-03-26 10:52:27 +010088 output = out,
Thomas Van Lentene5203c02018-06-12 13:09:57 -040089 content = script_content,
90 is_executable = True,
91 )
László Csomor4c26bf42019-03-26 10:52:27 +010092 return [DefaultInfo(files = depset([out]))]
Tony Allevato82b3ad62017-10-10 07:59:31 -070093
László Csomor4c26bf42019-03-26 10:52:27 +010094shell_args_test_gen = rule(
95 implementation = _shell_args_test_gen_impl,
Tony Allevato82b3ad62017-10-10 07:59:31 -070096)
97
Tony Allevato82b3ad62017-10-10 07:59:31 -070098def shell_test_suite():
Thomas Van Lentene5203c02018-06-12 13:09:57 -040099 """Creates the test targets and test suite for shell.bzl tests."""
100 unittest.suite(
101 "shell_tests",
102 shell_array_literal_test,
103 shell_quote_test,
Thomas Van Lentene5203c02018-06-12 13:09:57 -0400104 )