1*bcb5dc79SHONG Yifan# Copyright 2017 The Bazel Authors. All rights reserved. 2*bcb5dc79SHONG Yifan# 3*bcb5dc79SHONG Yifan# Licensed under the Apache License, Version 2.0 (the "License"); 4*bcb5dc79SHONG Yifan# you may not use this file except in compliance with the License. 5*bcb5dc79SHONG Yifan# You may obtain a copy of the License at 6*bcb5dc79SHONG Yifan# 7*bcb5dc79SHONG Yifan# http://www.apache.org/licenses/LICENSE-2.0 8*bcb5dc79SHONG Yifan# 9*bcb5dc79SHONG Yifan# Unless required by applicable law or agreed to in writing, software 10*bcb5dc79SHONG Yifan# distributed under the License is distributed on an "AS IS" BASIS, 11*bcb5dc79SHONG Yifan# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*bcb5dc79SHONG Yifan# See the License for the specific language governing permissions and 13*bcb5dc79SHONG Yifan# limitations under the License. 14*bcb5dc79SHONG Yifan 15*bcb5dc79SHONG Yifan"""Unit tests for shell.bzl.""" 16*bcb5dc79SHONG Yifan 17*bcb5dc79SHONG Yifanload("//lib:shell.bzl", "shell") 18*bcb5dc79SHONG Yifanload("//lib:unittest.bzl", "asserts", "unittest") 19*bcb5dc79SHONG Yifan 20*bcb5dc79SHONG Yifandef _shell_array_literal_test(ctx): 21*bcb5dc79SHONG Yifan """Unit tests for shell.array_literal.""" 22*bcb5dc79SHONG Yifan env = unittest.begin(ctx) 23*bcb5dc79SHONG Yifan 24*bcb5dc79SHONG Yifan asserts.equals(env, "()", shell.array_literal([])) 25*bcb5dc79SHONG Yifan asserts.equals(env, "('1')", shell.array_literal([1])) 26*bcb5dc79SHONG Yifan asserts.equals(env, "('1' '2' '3')", shell.array_literal([1, 2, 3])) 27*bcb5dc79SHONG Yifan asserts.equals(env, "('$foo')", shell.array_literal(["$foo"])) 28*bcb5dc79SHONG Yifan asserts.equals(env, "('qu\"o\"te')", shell.array_literal(['qu"o"te'])) 29*bcb5dc79SHONG Yifan 30*bcb5dc79SHONG Yifan return unittest.end(env) 31*bcb5dc79SHONG Yifan 32*bcb5dc79SHONG Yifanshell_array_literal_test = unittest.make(_shell_array_literal_test) 33*bcb5dc79SHONG Yifan 34*bcb5dc79SHONG Yifandef _shell_quote_test(ctx): 35*bcb5dc79SHONG Yifan """Unit tests for shell.quote.""" 36*bcb5dc79SHONG Yifan env = unittest.begin(ctx) 37*bcb5dc79SHONG Yifan 38*bcb5dc79SHONG Yifan asserts.equals(env, "'foo'", shell.quote("foo")) 39*bcb5dc79SHONG Yifan asserts.equals(env, "'foo bar'", shell.quote("foo bar")) 40*bcb5dc79SHONG Yifan asserts.equals(env, "'three spaces'", shell.quote("three spaces")) 41*bcb5dc79SHONG Yifan asserts.equals(env, "' leading'", shell.quote(" leading")) 42*bcb5dc79SHONG Yifan asserts.equals(env, "'trailing '", shell.quote("trailing ")) 43*bcb5dc79SHONG Yifan asserts.equals(env, "'new\nline'", shell.quote("new\nline")) 44*bcb5dc79SHONG Yifan asserts.equals(env, "'tab\tcharacter'", shell.quote("tab\tcharacter")) 45*bcb5dc79SHONG Yifan asserts.equals(env, "'$foo'", shell.quote("$foo")) 46*bcb5dc79SHONG Yifan asserts.equals(env, "'qu\"o\"te'", shell.quote('qu"o"te')) 47*bcb5dc79SHONG Yifan asserts.equals(env, "'it'\\''s'", shell.quote("it's")) 48*bcb5dc79SHONG Yifan asserts.equals(env, "'foo\\bar'", shell.quote("foo\\bar")) 49*bcb5dc79SHONG Yifan asserts.equals(env, "'back`echo q`uote'", shell.quote("back`echo q`uote")) 50*bcb5dc79SHONG Yifan 51*bcb5dc79SHONG Yifan return unittest.end(env) 52*bcb5dc79SHONG Yifan 53*bcb5dc79SHONG Yifanshell_quote_test = unittest.make(_shell_quote_test) 54*bcb5dc79SHONG Yifan 55*bcb5dc79SHONG Yifandef _shell_args_test_gen_impl(ctx): 56*bcb5dc79SHONG Yifan """Test argument escaping: this rule writes a script for a sh_test.""" 57*bcb5dc79SHONG Yifan args = [ 58*bcb5dc79SHONG Yifan "foo", 59*bcb5dc79SHONG Yifan "foo bar", 60*bcb5dc79SHONG Yifan "three spaces", 61*bcb5dc79SHONG Yifan " leading", 62*bcb5dc79SHONG Yifan "trailing ", 63*bcb5dc79SHONG Yifan "new\nline", 64*bcb5dc79SHONG Yifan "tab\tcharacter", 65*bcb5dc79SHONG Yifan "$foo", 66*bcb5dc79SHONG Yifan 'qu"o"te', 67*bcb5dc79SHONG Yifan "it's", 68*bcb5dc79SHONG Yifan "foo\\bar", 69*bcb5dc79SHONG Yifan "back`echo q`uote", 70*bcb5dc79SHONG Yifan ] 71*bcb5dc79SHONG Yifan script_content = "\n".join([ 72*bcb5dc79SHONG Yifan "#!/usr/bin/env bash", 73*bcb5dc79SHONG Yifan "myarray=" + shell.array_literal(args), 74*bcb5dc79SHONG Yifan 'output=$(echo "${myarray[@]}")', 75*bcb5dc79SHONG Yifan # For logging: 76*bcb5dc79SHONG Yifan 'echo "DEBUG: output=[${output}]" >&2', 77*bcb5dc79SHONG Yifan # The following is a shell representation of what the echo of the quoted 78*bcb5dc79SHONG Yifan # array will look like. It looks a bit confusing considering it's shell 79*bcb5dc79SHONG Yifan # quoted into Python. Shell using single quotes to minimize shell 80*bcb5dc79SHONG Yifan # escaping, so only the single quote needs to be escaped as '\'', all 81*bcb5dc79SHONG Yifan # others are essentially kept literally. 82*bcb5dc79SHONG Yifan "expected='foo foo bar three spaces leading trailing new", 83*bcb5dc79SHONG Yifan "line tab\tcharacter $foo qu\"o\"te it'\\''s foo\\bar back`echo q`uote'", 84*bcb5dc79SHONG Yifan '[[ "${output}" == "${expected}" ]]', 85*bcb5dc79SHONG Yifan ]) 86*bcb5dc79SHONG Yifan out = ctx.actions.declare_file(ctx.label.name + ".sh") 87*bcb5dc79SHONG Yifan ctx.actions.write( 88*bcb5dc79SHONG Yifan output = out, 89*bcb5dc79SHONG Yifan content = script_content, 90*bcb5dc79SHONG Yifan is_executable = True, 91*bcb5dc79SHONG Yifan ) 92*bcb5dc79SHONG Yifan return [DefaultInfo(files = depset([out]))] 93*bcb5dc79SHONG Yifan 94*bcb5dc79SHONG Yifanshell_args_test_gen = rule( 95*bcb5dc79SHONG Yifan implementation = _shell_args_test_gen_impl, 96*bcb5dc79SHONG Yifan) 97*bcb5dc79SHONG Yifan 98*bcb5dc79SHONG Yifandef shell_test_suite(): 99*bcb5dc79SHONG Yifan """Creates the test targets and test suite for shell.bzl tests.""" 100*bcb5dc79SHONG Yifan unittest.suite( 101*bcb5dc79SHONG Yifan "shell_tests", 102*bcb5dc79SHONG Yifan shell_array_literal_test, 103*bcb5dc79SHONG Yifan shell_quote_test, 104*bcb5dc79SHONG Yifan ) 105