/*
* Copyright 2005 The Closure Compiler Authors.
*
* 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.google.javascript.jscomp;
import static com.google.common.truth.Truth.assertThat;
import com.google.common.collect.ImmutableSet;
import java.util.Collections;
import junit.framework.TestCase;
public final class DefaultNameGeneratorTest extends TestCase {
private static final ImmutableSet<String> RESERVED_NAMES = ImmutableSet.of("ba", "xba");
private static String[] generate(
DefaultNameGenerator ng, String prefix, int num) throws Exception {
String[] result = new String[num];
for (int i = 0; i < num; i++) {
result[i] = ng.generateNextName();
if (!result[i].startsWith(prefix)) {
fail("Error: " + result[i]);
}
}
return result;
}
public static void testNameGeneratorInvalidPrefixes() throws Exception {
try {
new DefaultNameGenerator(Collections.<String>emptySet(), "123abc", null);
fail("Constructor should throw exception when the first char of prefix "
+ "is invalid");
} catch (IllegalArgumentException ex) {
// The error messages should contain meaningful information.
assertThat(ex.getMessage()).contains("W, X, Y, Z, $]");
}
try {
new DefaultNameGenerator(Collections.<String>emptySet(), "abc%", null);
fail("Constructor should throw exception when one of prefix characters "
+ "is invalid");
} catch (IllegalArgumentException ex) {
assertThat(ex.getMessage()).contains("W, X, Y, Z, _, 0, 1");
}
}
public static void testGenerate() throws Exception {
DefaultNameGenerator ng = new DefaultNameGenerator(
RESERVED_NAMES, "", null);
String[] result = generate(ng, "", 106);
assertEquals("a", result[0]);
assertEquals("z", result[25]);
assertEquals("A", result[26]);
assertEquals("Z", result[51]);
assertEquals("$", result[52]);
assertEquals("aa", result[53]);
// ba is reserved
assertEquals("ca", result[54]);
assertEquals("$a", result[104]);
ng = new DefaultNameGenerator(RESERVED_NAMES, "x", null);
result = generate(ng, "x", 132);
// Expected: x, xa, ..., x$, xaa, ..., x$$
assertEquals("x", result[0]);
assertEquals("xa", result[1]);
assertEquals("x$", result[64]);
assertEquals("xaa", result[65]);
// xba is reserved
assertEquals("xca", result[66]);
}
public static void testReserve() throws Exception {
DefaultNameGenerator ng = new DefaultNameGenerator(
RESERVED_NAMES, "", new char[] {'$'});
String[] result = generate(ng, "", 106);
assertEquals("a", result[0]);
assertEquals("z", result[25]);
assertEquals("A", result[26]);
assertEquals("Z", result[51]);
assertEquals("aa", result[52]);
// ba is reserved
assertEquals("ca", result[53]);
assertEquals("ab", result[103]);
}
public static void testGenerateWithPriority1() throws Exception {
DefaultNameGenerator ng = new DefaultNameGenerator(
RESERVED_NAMES, "", null);
String[] result = generate(ng, "", 106);
assertEquals("a", result[0]);
assertEquals("z", result[25]);
assertEquals("A", result[26]);
assertEquals("Z", result[51]);
assertEquals("$", result[52]);
assertEquals("aa", result[53]);
ng.favors("b");
ng.reset(RESERVED_NAMES, "", null);
result = generate(ng, "", 106);
assertEquals("b", result[0]);
assertEquals("a", result[1]);
assertEquals("c", result[2]);
assertEquals("d", result[3]);
ng.favors("cc");
ng.reset(RESERVED_NAMES, "", null);
result = generate(ng, "", 106);
assertEquals("c", result[0]);
assertEquals("b", result[1]);
assertEquals("a", result[2]);
assertEquals("d", result[3]);
}
public static void testGenerateWithPriority2() throws Exception {
DefaultNameGenerator ng = new DefaultNameGenerator(
RESERVED_NAMES, "", null);
String[] result = generate(ng, "", 106);
assertEquals("a", result[0]);
assertEquals("z", result[25]);
assertEquals("A", result[26]);
assertEquals("Z", result[51]);
assertEquals("$", result[52]);
assertEquals("aa", result[53]);
ng.favors("function");
ng.favors("function");
ng.favors("function");
ng.reset(RESERVED_NAMES, "", null);
result = generate(ng, "", 106);
// All the letters of function should come first. In alphabetical order.
assertEquals("n", result[0]);
assertEquals("c", result[1]);
assertEquals("f", result[2]);
assertEquals("i", result[3]);
assertEquals("o", result[4]);
assertEquals("t", result[5]);
assertEquals("u", result[6]);
// Back to normal.
assertEquals("a", result[7]);
assertEquals("b", result[8]);
// c has been prioritized.
assertEquals("d", result[9]);
assertEquals("e", result[10]);
// This used to start with 'aa' but now n is prioritized over it.
assertEquals("nn", result[53]);
assertEquals("cn", result[54]);
}
public static void testGenerateWithPriority3() throws Exception {
DefaultNameGenerator ng = new DefaultNameGenerator(
RESERVED_NAMES, "", null);
String[] result = generate(ng, "", 106);
ng.favors("???");
ng.reset(RESERVED_NAMES, "", null);
result = generate(ng, "", 106);
assertEquals("a", result[0]);
}
}