1 // Copyright 2017 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.base; 6 7 import androidx.test.filters.SmallTest; 8 9 import org.junit.Assert; 10 import org.junit.Before; 11 import org.junit.Test; 12 import org.junit.runner.RunWith; 13 import org.robolectric.annotation.Config; 14 15 import org.chromium.base.test.BaseRobolectricTestRunner; 16 import org.chromium.base.test.util.Feature; 17 18 import java.util.Map; 19 20 /** Tests for {@link CommandLine}. */ 21 @RunWith(BaseRobolectricTestRunner.class) 22 @Config(manifest = Config.NONE) 23 public class CommandLineTest { 24 // A reference command line. Note that switch2 is [brea\d], switch3 is [and "butter"], 25 // and switch4 is [a "quoted" 'food'!] 26 static final String[] INIT_SWITCHES = { 27 "init_command", 28 "--SWITCH", 29 "Arg", 30 "--switch2=brea\\d", 31 "--switch3=and \"butter\"", 32 "--switch4=a \"quoted\" 'food'!", 33 "--", 34 "--actually_an_arg" 35 }; 36 37 // The same command line, but in quoted string format. 38 static final char[] INIT_SWITCHES_BUFFER = 39 ("init_command --SWITCH Arg --switch2=brea\\d --switch3=\"and \\\"butt\"er\\\" " 40 + "--switch4='a \"quoted\" \\'food\\'!' " 41 + "-- --actually_an_arg") 42 .toCharArray(); 43 44 static final String CL_ADDED_SWITCH = "zappo-dappo-doggy-trainer"; 45 static final String CL_ADDED_SWITCH_2 = "username"; 46 static final String CL_ADDED_VALUE_2 = "bozo"; 47 48 private CommandLine mCommandLine; 49 50 @Before setUp()51 public void setUp() { 52 mCommandLine = new CommandLine.JavaCommandLine(null); 53 } 54 checkInitSwitches()55 void checkInitSwitches() { 56 CommandLine cl = mCommandLine; 57 Assert.assertFalse(cl.hasSwitch("init_command")); 58 Assert.assertFalse(cl.hasSwitch("switch")); 59 Assert.assertTrue(cl.hasSwitch("SWITCH")); 60 Assert.assertFalse(cl.hasSwitch("--SWITCH")); 61 Assert.assertFalse(cl.hasSwitch("Arg")); 62 Assert.assertFalse(cl.hasSwitch("actually_an_arg")); 63 Assert.assertEquals("brea\\d", cl.getSwitchValue("switch2")); 64 Assert.assertEquals("and \"butter\"", cl.getSwitchValue("switch3")); 65 Assert.assertEquals("a \"quoted\" 'food'!", cl.getSwitchValue("switch4")); 66 Assert.assertNull(cl.getSwitchValue("SWITCH")); 67 Assert.assertNull(cl.getSwitchValue("non-existant")); 68 } 69 checkSettingThenGettingThenRemoving()70 void checkSettingThenGettingThenRemoving() { 71 CommandLine cl = mCommandLine; 72 73 // Add a plain switch. 74 Assert.assertFalse(cl.hasSwitch(CL_ADDED_SWITCH)); 75 cl.appendSwitch(CL_ADDED_SWITCH); 76 Assert.assertTrue(cl.hasSwitch(CL_ADDED_SWITCH)); 77 78 // Add a switch paired with a value. 79 Assert.assertFalse(cl.hasSwitch(CL_ADDED_SWITCH_2)); 80 Assert.assertNull(cl.getSwitchValue(CL_ADDED_SWITCH_2)); 81 cl.appendSwitchWithValue(CL_ADDED_SWITCH_2, CL_ADDED_VALUE_2); 82 Assert.assertEquals(CL_ADDED_VALUE_2, cl.getSwitchValue(CL_ADDED_SWITCH_2)); 83 84 // Update a switch's value. 85 cl.appendSwitchWithValue(CL_ADDED_SWITCH_2, "updatedValue"); 86 Assert.assertEquals("updatedValue", cl.getSwitchValue(CL_ADDED_SWITCH_2)); 87 88 // Append a few new things. 89 final String[] switchesAndArgs = {"thing", "--superfast", "--speed=turbo"}; 90 Assert.assertFalse(cl.hasSwitch("thing")); 91 Assert.assertFalse(cl.hasSwitch("superfast")); 92 Assert.assertNull(cl.getSwitchValue("speed")); 93 cl.appendSwitchesAndArguments(switchesAndArgs); 94 Assert.assertFalse(cl.hasSwitch("thing")); 95 Assert.assertFalse(cl.hasSwitch("command")); 96 Assert.assertTrue(cl.hasSwitch("superfast")); 97 Assert.assertEquals("turbo", cl.getSwitchValue("speed")); 98 99 // Get all switches 100 Map<String, String> switches = cl.getSwitches(); 101 Assert.assertTrue(switches.containsKey(CL_ADDED_SWITCH)); 102 Assert.assertTrue(switches.containsKey(CL_ADDED_SWITCH_2)); 103 104 // Remove a plain switch. 105 cl.removeSwitch(CL_ADDED_SWITCH); 106 Assert.assertFalse(cl.hasSwitch(CL_ADDED_SWITCH)); 107 108 // Remove a switch with a value. 109 cl.removeSwitch(CL_ADDED_SWITCH_2); 110 Assert.assertFalse(cl.hasSwitch(CL_ADDED_SWITCH_2)); 111 Assert.assertNull(cl.getSwitchValue(CL_ADDED_SWITCH_2)); 112 113 // Get all switches again to verify it updated. 114 switches = cl.getSwitches(); 115 Assert.assertFalse(switches.containsKey(CL_ADDED_SWITCH)); 116 Assert.assertFalse(switches.containsKey(CL_ADDED_SWITCH_2)); 117 } 118 checkTokenizer(String[] expected, String toParse)119 void checkTokenizer(String[] expected, String toParse) { 120 String[] actual = CommandLine.tokenizeQuotedArguments(toParse.toCharArray()); 121 Assert.assertEquals(expected.length, actual.length); 122 for (int i = 0; i < expected.length; ++i) { 123 Assert.assertEquals("comparing element " + i, expected[i], actual[i]); 124 } 125 } 126 127 @Test 128 @SmallTest 129 @Feature({"Android-AppBase"}) testJavaInitialization()130 public void testJavaInitialization() { 131 mCommandLine = new CommandLine.JavaCommandLine(INIT_SWITCHES); 132 checkInitSwitches(); 133 checkSettingThenGettingThenRemoving(); 134 } 135 136 @Test 137 @SmallTest 138 @Feature({"Android-AppBase"}) testBufferInitialization()139 public void testBufferInitialization() { 140 mCommandLine = 141 new CommandLine.JavaCommandLine( 142 CommandLine.tokenizeQuotedArguments(INIT_SWITCHES_BUFFER)); 143 checkInitSwitches(); 144 checkSettingThenGettingThenRemoving(); 145 } 146 147 @Test 148 @SmallTest 149 @Feature({"Android-AppBase"}) testArgumentTokenizer()150 public void testArgumentTokenizer() { 151 String toParse = " a\"\\bc de\\\"f g\"\\h ij k\" \"lm"; 152 String[] expected = {"a\\bc de\"f g\\h", "ij", "k lm"}; 153 checkTokenizer(expected, toParse); 154 155 toParse = ""; 156 expected = new String[0]; 157 checkTokenizer(expected, toParse); 158 159 toParse = " \t\n"; 160 checkTokenizer(expected, toParse); 161 162 toParse = 163 " \"a'b\" 'c\"d' \"e\\\"f\" 'g\\'h' \"i\\'j\" 'k\\\"l'" + " m\"n\\'o\"p q'r\\\"s't"; 164 expected = 165 new String[] { 166 "a'b", "c\"d", "e\"f", "g'h", "i\\'j", "k\\\"l", "mn\\'op", "qr\\\"st" 167 }; 168 checkTokenizer(expected, toParse); 169 } 170 171 @Test 172 @SmallTest 173 @Feature({"Android-AppBase"}) testUpdatingArgList()174 public void testUpdatingArgList() { 175 CommandLine cl = mCommandLine; 176 cl.appendSwitch(CL_ADDED_SWITCH); 177 cl.appendSwitchWithValue(CL_ADDED_SWITCH_2, CL_ADDED_VALUE_2); 178 cl.appendSwitchWithValue(CL_ADDED_SWITCH_2, "updatedValue"); 179 180 final String[] expectedValueForBothSwitches = { 181 "", 182 "--" + CL_ADDED_SWITCH, 183 "--" + CL_ADDED_SWITCH_2 + "=" + CL_ADDED_VALUE_2, 184 "--" + CL_ADDED_SWITCH_2 + "=updatedValue", 185 }; 186 Assert.assertArrayEquals( 187 "Appending a switch multiple times should add multiple args", 188 expectedValueForBothSwitches, 189 mCommandLine.getCommandLineArguments()); 190 191 cl.removeSwitch(CL_ADDED_SWITCH_2); 192 final String[] expectedValueWithSecondSwitchRemoved = { 193 "", "--" + CL_ADDED_SWITCH, 194 }; 195 Assert.assertArrayEquals( 196 "Removing a switch should remove all its args", 197 expectedValueWithSecondSwitchRemoved, 198 mCommandLine.getCommandLineArguments()); 199 } 200 } 201