Damien Martin-Guillerez | f88f4d8 | 2015-09-25 13:56:55 +0000 | [diff] [blame] | 1 | // Copyright 2014 The Bazel Authors. All rights reserved. |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 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 | package com.google.devtools.build.lib.util; |
| 15 | |
Ulf Adams | 795895a | 2015-03-06 15:58:35 +0000 | [diff] [blame] | 16 | import static com.google.common.truth.Truth.assertThat; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 17 | import static com.google.devtools.build.lib.util.StringUtilities.combineKeys; |
| 18 | import static com.google.devtools.build.lib.util.StringUtilities.joinLines; |
| 19 | import static com.google.devtools.build.lib.util.StringUtilities.layoutTable; |
| 20 | import static com.google.devtools.build.lib.util.StringUtilities.prettyPrintBytes; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 21 | import static org.junit.Assert.fail; |
| 22 | |
| 23 | import com.google.common.collect.Maps; |
lberki | aea56b3 | 2017-05-30 12:35:33 +0200 | [diff] [blame] | 24 | import java.util.Arrays; |
| 25 | import java.util.HashMap; |
| 26 | import java.util.Map; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 27 | import org.junit.Test; |
| 28 | import org.junit.runner.RunWith; |
| 29 | import org.junit.runners.JUnit4; |
| 30 | |
lberki | aea56b3 | 2017-05-30 12:35:33 +0200 | [diff] [blame] | 31 | /** A test for {@link StringUtilities}. */ |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 32 | @RunWith(JUnit4.class) |
| 33 | public class StringUtilitiesTest { |
| 34 | |
| 35 | // Tests of StringUtilities.joinLines() |
| 36 | |
| 37 | @Test |
| 38 | public void emptyLinesYieldsEmptyString() { |
Ulf Adams | 795895a | 2015-03-06 15:58:35 +0000 | [diff] [blame] | 39 | assertThat(joinLines()).isEmpty(); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 40 | } |
| 41 | |
| 42 | @Test |
| 43 | public void twoLinesGetjoinedNicely() { |
lberki | 78cfa8d | 2017-05-30 17:00:48 +0200 | [diff] [blame] | 44 | assertThat(joinLines("line 1", "line 2")).isEqualTo("line 1\nline 2"); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 45 | } |
| 46 | |
| 47 | @Test |
| 48 | public void aTrailingNewlineIsAvailableWhenYouNeedIt() { |
lberki | 78cfa8d | 2017-05-30 17:00:48 +0200 | [diff] [blame] | 49 | assertThat(joinLines("two lines", "with trailing newline", "")) |
| 50 | .isEqualTo("two lines\nwith trailing newline\n"); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 51 | } |
| 52 | |
| 53 | // Tests of StringUtilities.combineKeys() |
| 54 | |
| 55 | /** Simple sanity test of format */ |
| 56 | @Test |
| 57 | public void combineKeysFormat() { |
lberki | 78cfa8d | 2017-05-30 17:00:48 +0200 | [diff] [blame] | 58 | assertThat(combineKeys("a", "b!c", "<d>")).isEqualTo("<a><b!!c><!<d!>>"); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 59 | } |
| 60 | |
| 61 | /** |
| 62 | * Test that combining different keys gives different results, |
| 63 | * i.e. that there are no collisions. |
| 64 | * We test all combinations of up to 3 keys from the test_keys |
| 65 | * array (defined below). |
| 66 | */ |
| 67 | @Test |
| 68 | public void testCombineKeys() { |
| 69 | // This map is really just used as a set, but |
| 70 | // if the test fails, the values in the map may be |
| 71 | // useful for debugging. |
| 72 | Map<String,String[]> map = new HashMap<>(); |
| 73 | for (int numKeys = 0; numKeys <= 3; numKeys++) { |
| 74 | testCombineKeys(map, numKeys, new String[numKeys]); |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | private void testCombineKeys(Map<String,String[]> map, |
| 79 | int n, String[] keys) { |
| 80 | if (n == 0) { |
| 81 | String[] keys_copy = keys.clone(); |
| 82 | String combined_key = combineKeys(keys_copy); |
| 83 | String[] prev_keys = map.put(combined_key, keys_copy); |
| 84 | if (prev_keys != null) { |
Ulf Adams | 795895a | 2015-03-06 15:58:35 +0000 | [diff] [blame] | 85 | fail("combineKeys collision:\n" |
| 86 | + "key sequence 1: " + Arrays.toString(prev_keys) + "\n" |
| 87 | + "key sequence 2: " + Arrays.toString(keys_copy) + "\n" |
| 88 | + "combined key sequence 1: " + combineKeys(prev_keys) + "\n" |
| 89 | + "combined key sequence 2: " + combineKeys(keys_copy) + "\n"); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 90 | } |
| 91 | } else { |
| 92 | for (String key : test_keys) { |
| 93 | keys[n - 1] = key; |
| 94 | testCombineKeys(map, n - 1, keys); |
| 95 | } |
| 96 | } |
| 97 | } |
| 98 | |
| 99 | private static final String[] test_keys = { |
| 100 | // ordinary strings |
| 101 | "", "a", "word", "//depot/foo/bar", |
| 102 | // likely delimiter characters |
| 103 | " ", ",", "\\", "\"", "\'", "\0", "\u00ff", |
| 104 | // strings starting in special delimiter |
| 105 | " foo", ",foo", "\\foo", "\"foo", "\'foo", "\0foo", "\u00fffoo", |
| 106 | // strings ending in special delimiter |
| 107 | "bar ", "bar,", "bar\\", "bar\"", "bar\'", "bar\0", "bar\u00ff", |
| 108 | // white-box testing of the delimiters that combineKeys() uses |
| 109 | "<", ">", "!", "!<", "!>", "!!", "<!", ">!" |
| 110 | }; |
| 111 | |
| 112 | @Test |
| 113 | public void replaceAllLiteral() throws Exception { |
lberki | 78cfa8d | 2017-05-30 17:00:48 +0200 | [diff] [blame] | 114 | assertThat(StringUtilities.replaceAllLiteral("bababa", "ba", "ab")).isEqualTo("ababab"); |
Ulf Adams | 795895a | 2015-03-06 15:58:35 +0000 | [diff] [blame] | 115 | assertThat(StringUtilities.replaceAllLiteral("bababa", "ba", "")).isEmpty(); |
lberki | 78cfa8d | 2017-05-30 17:00:48 +0200 | [diff] [blame] | 116 | assertThat(StringUtilities.replaceAllLiteral("bababa", "", "ab")).isEqualTo("bababa"); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 117 | } |
| 118 | |
| 119 | @Test |
| 120 | public void testLayoutTable() throws Exception { |
| 121 | Map<String, String> data = Maps.newTreeMap(); |
| 122 | data.put("foo", "bar"); |
| 123 | data.put("bang", "baz"); |
| 124 | data.put("lengthy key", "lengthy value"); |
| 125 | |
lberki | 78cfa8d | 2017-05-30 17:00:48 +0200 | [diff] [blame] | 126 | assertThat(layoutTable(data)) |
| 127 | .isEqualTo(joinLines("bang: baz", "foo: bar", "lengthy key: lengthy value")); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 128 | } |
| 129 | |
| 130 | @Test |
| 131 | public void testPrettyPrintBytes() { |
| 132 | String[] expected = { |
| 133 | "2B", |
| 134 | "23B", |
| 135 | "234B", |
| 136 | "2345B", |
| 137 | "23KB", |
| 138 | "234KB", |
| 139 | "2345KB", |
| 140 | "23MB", |
| 141 | "234MB", |
| 142 | "2345MB", |
| 143 | "23456MB", |
| 144 | "234GB", |
| 145 | "2345GB", |
| 146 | "23456GB", |
| 147 | }; |
| 148 | double x = 2.3456; |
| 149 | for (int ii = 0; ii < expected.length; ++ii) { |
lberki | 78cfa8d | 2017-05-30 17:00:48 +0200 | [diff] [blame] | 150 | assertThat(prettyPrintBytes((long) x)).isEqualTo(expected[ii]); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 151 | x = x * 10.0; |
| 152 | } |
| 153 | } |
| 154 | |
| 155 | @Test |
| 156 | public void sanitizeControlChars() { |
lberki | 78cfa8d | 2017-05-30 17:00:48 +0200 | [diff] [blame] | 157 | assertThat(StringUtilities.sanitizeControlChars("\000")).isEqualTo("<?>"); |
| 158 | assertThat(StringUtilities.sanitizeControlChars("\001")).isEqualTo("<?>"); |
| 159 | assertThat(StringUtilities.sanitizeControlChars("\r")).isEqualTo("\\r"); |
| 160 | assertThat(StringUtilities.sanitizeControlChars(" abc123")).isEqualTo(" abc123"); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 161 | } |
| 162 | |
| 163 | @Test |
| 164 | public void containsSubarray() { |
lberki | aea56b3 | 2017-05-30 12:35:33 +0200 | [diff] [blame] | 165 | assertThat(StringUtilities.containsSubarray("abcde".toCharArray(), "ab".toCharArray())) |
| 166 | .isTrue(); |
| 167 | assertThat(StringUtilities.containsSubarray("abcde".toCharArray(), "de".toCharArray())) |
| 168 | .isTrue(); |
| 169 | assertThat(StringUtilities.containsSubarray("abcde".toCharArray(), "bc".toCharArray())) |
| 170 | .isTrue(); |
| 171 | assertThat(StringUtilities.containsSubarray("abcde".toCharArray(), "".toCharArray())).isTrue(); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 172 | } |
| 173 | |
| 174 | @Test |
| 175 | public void notContainsSubarray() { |
lberki | aea56b3 | 2017-05-30 12:35:33 +0200 | [diff] [blame] | 176 | assertThat(StringUtilities.containsSubarray("abc".toCharArray(), "abcd".toCharArray())) |
| 177 | .isFalse(); |
| 178 | assertThat(StringUtilities.containsSubarray("abc".toCharArray(), "def".toCharArray())) |
| 179 | .isFalse(); |
| 180 | assertThat(StringUtilities.containsSubarray("abcde".toCharArray(), "bd".toCharArray())) |
| 181 | .isFalse(); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 182 | } |
| 183 | |
| 184 | @Test |
| 185 | public void toPythonStyleFunctionName() { |
lberki | 78cfa8d | 2017-05-30 17:00:48 +0200 | [diff] [blame] | 186 | assertThat(StringUtilities.toPythonStyleFunctionName("a")).isEqualTo("a"); |
| 187 | assertThat(StringUtilities.toPythonStyleFunctionName("aB")).isEqualTo("a_b"); |
| 188 | assertThat(StringUtilities.toPythonStyleFunctionName("aBC")).isEqualTo("a_b_c"); |
| 189 | assertThat(StringUtilities.toPythonStyleFunctionName("aBcD")).isEqualTo("a_bc_d"); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 190 | } |
| 191 | } |