/*
* Copyright 2017 ThoughtWorks, Inc.
*
* 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.
*/
package com.thoughtworks.go.utils;
import org.junit.Test;
import java.util.regex.Matcher;
import static org.junit.Assert.assertEquals;
public class CommandUtilsTest {
@Test
public void quoteArgument() throws Exception {
String alreadyDoubleQuoted = "\"Hello there! I'm properly quoted\"";
String alreadyDoubleQuotedWithUnclosedQuote = "\"Hello there! I've got an unmatched double quote \" inside\"";
String noQuotes = "I have nothing";
String apostrophe = "don't";
String dontNeedQuoting = "ohrly?";
String singleQuotesInside = "java is a 'fun' language";
String doubleQuotesInside = "java is a \"fun\" language";
String unmatchedDoubleQuotes = "java is a \"fun' language";
String alreadyProperlyEscaped = "This\\ string\\ needs\\ \\'no\\'\\ further\\ \\\"escaping\\\"\\ at\\ all.";
String bashScript = "if [ \"${SOME_VARIABLE}\" != 'SOME_STRING' ]; then echo \"SOME_VARIABLE doesn't look right.\"; exit 1; fi";
String someQuotesEscapedSomeNot = "I was \\\"so\" lazy I forgot to escape the other quote";
assertEquals(alreadyDoubleQuoted, CommandUtils.quoteArgument(alreadyDoubleQuoted));
assertEquals(alreadyDoubleQuotedWithUnclosedQuote, CommandUtils.quoteArgument(alreadyDoubleQuotedWithUnclosedQuote));
assertEquals(wrapQuotes(noQuotes), CommandUtils.quoteArgument(noQuotes));
assertEquals(wrapQuotes(apostrophe), CommandUtils.quoteArgument(apostrophe));
assertEquals(dontNeedQuoting, CommandUtils.quoteArgument(dontNeedQuoting));
assertEquals(wrapQuotes(singleQuotesInside), CommandUtils.quoteArgument(singleQuotesInside));
assertEquals(wrapQuotes(doubleQuotesInside.replaceAll("\"", Matcher.quoteReplacement("\\\""))), CommandUtils.quoteArgument(doubleQuotesInside));
assertEquals(wrapQuotes(unmatchedDoubleQuotes.replaceAll("\"", Matcher.quoteReplacement("\\\""))), CommandUtils.quoteArgument(unmatchedDoubleQuotes));
assertEquals(alreadyProperlyEscaped, CommandUtils.quoteArgument(alreadyProperlyEscaped));
assertEquals(wrapQuotes(bashScript.replaceAll("\"", Matcher.quoteReplacement("\\\""))), CommandUtils.quoteArgument(bashScript));
assertEquals("Should blindly escape internal double quotes; don't try to be smart and fix " +
"only the unescaped quotes because that it would make it hard for users to determine why " +
"improperly quoted commands fail to execute",
wrapQuotes("I was \\\\\"so\\\" lazy I forgot to escape the other quote"), CommandUtils.quoteArgument(someQuotesEscapedSomeNot));
}
@Test
public void shellJoin() throws Exception {
String[] tokens = new String[]{
"bash",
"-c",
"if [ \"${SOME_VARIABLE}\" != 'SOME_STRING' ]; then echo \"SOME_VARIABLE doesn't look right.\"; exit 1; fi"
};
assertEquals("bash -c \"if [ \\\"${SOME_VARIABLE}\\\" != 'SOME_STRING' ]; then echo \\\"SOME_VARIABLE doesn't look right.\\\"; exit 1; fi\"", CommandUtils.shellJoin(tokens));
}
private String wrapQuotes(String s) {
return String.format("\"%s\"", s);
}
}