mirror of
https://github.com/github/codeql-action.git
synced 2025-12-27 17:50:07 +08:00
Co-authored-by: Andrew Eisenberg <aeisenberg@github.com> Co-authored-by: Henry Mercer <henrymercer@github.com>
316 lines
11 KiB
TypeScript
316 lines
11 KiB
TypeScript
|
|
public final class CodeBlockTest {
|
|
@Test public void equalsAndHashCode() {
|
|
CodeBlock a = CodeBlock.builder().build();
|
|
CodeBlock b = CodeBlock.builder().build();
|
|
assertThat(a.equals(b)).isTrue();
|
|
assertThat(a.hashCode()).isEqualTo(b.hashCode());
|
|
a = CodeBlock.builder().add("$L", "taco").build();
|
|
b = CodeBlock.builder().add("$L", "taco").build();
|
|
assertThat(a.equals(b)).isTrue();
|
|
assertThat(a.hashCode()).isEqualTo(b.hashCode());
|
|
}
|
|
|
|
@Test public void of() {
|
|
CodeBlock a = CodeBlock.of("$L taco", "delicious");
|
|
assertThat(a.toString()).isEqualTo("delicious taco");
|
|
}
|
|
|
|
@Test public void isEmpty() {
|
|
assertTrue(CodeBlock.builder().isEmpty());
|
|
assertTrue(CodeBlock.builder().add("").isEmpty());
|
|
assertFalse(CodeBlock.builder().add(" ").isEmpty());
|
|
}
|
|
|
|
@Test public void indentCannotBeIndexed() {
|
|
try {
|
|
CodeBlock.builder().add("$1>", "taco").build();
|
|
fail();
|
|
} catch (IllegalArgumentException exp) {
|
|
assertThat(exp)
|
|
.hasMessageThat()
|
|
.isEqualTo("$$, $>, $<, $[, $], $W, and $Z may not have an index");
|
|
}
|
|
}
|
|
|
|
@Test public void deindentCannotBeIndexed() {
|
|
try {
|
|
CodeBlock.builder().add("$1<", "taco").build();
|
|
fail();
|
|
} catch (IllegalArgumentException exp) {
|
|
assertThat(exp)
|
|
.hasMessageThat()
|
|
.isEqualTo("$$, $>, $<, $[, $], $W, and $Z may not have an index");
|
|
}
|
|
}
|
|
|
|
@Test public void dollarSignEscapeCannotBeIndexed() {
|
|
try {
|
|
CodeBlock.builder().add("$1$", "taco").build();
|
|
fail();
|
|
} catch (IllegalArgumentException exp) {
|
|
assertThat(exp)
|
|
.hasMessageThat()
|
|
.isEqualTo("$$, $>, $<, $[, $], $W, and $Z may not have an index");
|
|
}
|
|
}
|
|
|
|
@Test public void statementBeginningCannotBeIndexed() {
|
|
try {
|
|
CodeBlock.builder().add("$1[", "taco").build();
|
|
fail();
|
|
} catch (IllegalArgumentException exp) {
|
|
assertThat(exp)
|
|
.hasMessageThat()
|
|
.isEqualTo("$$, $>, $<, $[, $], $W, and $Z may not have an index");
|
|
}
|
|
}
|
|
|
|
@Test public void statementEndingCannotBeIndexed() {
|
|
try {
|
|
CodeBlock.builder().add("$1]", "taco").build();
|
|
fail();
|
|
} catch (IllegalArgumentException exp) {
|
|
assertThat(exp)
|
|
.hasMessageThat()
|
|
.isEqualTo("$$, $>, $<, $[, $], $W, and $Z may not have an index");
|
|
}
|
|
}
|
|
|
|
@Test public void nameFormatCanBeIndexed() {
|
|
CodeBlock block = CodeBlock.builder().add("$1N", "taco").build();
|
|
assertThat(block.toString()).isEqualTo("taco");
|
|
}
|
|
|
|
@Test public void literalFormatCanBeIndexed() {
|
|
CodeBlock block = CodeBlock.builder().add("$1L", "taco").build();
|
|
assertThat(block.toString()).isEqualTo("taco");
|
|
}
|
|
|
|
@Test public void stringFormatCanBeIndexed() {
|
|
CodeBlock block = CodeBlock.builder().add("$1S", "taco").build();
|
|
assertThat(block.toString()).isEqualTo("\"taco\"");
|
|
}
|
|
|
|
@Test public void typeFormatCanBeIndexed() {
|
|
CodeBlock block = CodeBlock.builder().add("$1T", String.class).build();
|
|
assertThat(block.toString()).isEqualTo("java.lang.String");
|
|
}
|
|
|
|
@Test public void simpleNamedArgument() {
|
|
Map<String, Object> map = new LinkedHashMap<>();
|
|
map.put("text", "taco");
|
|
CodeBlock block = CodeBlock.builder().addNamed("$text:S", map).build();
|
|
assertThat(block.toString()).isEqualTo("\"taco\"");
|
|
}
|
|
|
|
@Test public void repeatedNamedArgument() {
|
|
Map<String, Object> map = new LinkedHashMap<>();
|
|
map.put("text", "tacos");
|
|
CodeBlock block = CodeBlock.builder()
|
|
.addNamed("\"I like \" + $text:S + \". Do you like \" + $text:S + \"?\"", map)
|
|
.build();
|
|
assertThat(block.toString()).isEqualTo(
|
|
"\"I like \" + \"tacos\" + \". Do you like \" + \"tacos\" + \"?\"");
|
|
}
|
|
|
|
@Test public void namedAndNoArgFormat() {
|
|
Map<String, Object> map = new LinkedHashMap<>();
|
|
map.put("text", "tacos");
|
|
CodeBlock block = CodeBlock.builder()
|
|
.addNamed("$>\n$text:L for $$3.50", map).build();
|
|
assertThat(block.toString()).isEqualTo("\n tacos for $3.50");
|
|
}
|
|
|
|
@Test public void missingNamedArgument() {
|
|
try {
|
|
Map<String, Object> map = new LinkedHashMap<>();
|
|
CodeBlock.builder().addNamed("$text:S", map).build();
|
|
fail();
|
|
} catch(IllegalArgumentException expected) {
|
|
assertThat(expected).hasMessageThat().isEqualTo("Missing named argument for $text");
|
|
}
|
|
}
|
|
|
|
@Test public void lowerCaseNamed() {
|
|
try {
|
|
Map<String, Object> map = new LinkedHashMap<>();
|
|
map.put("Text", "tacos");
|
|
CodeBlock block = CodeBlock.builder().addNamed("$Text:S", map).build();
|
|
fail();
|
|
} catch(IllegalArgumentException expected) {
|
|
assertThat(expected).hasMessageThat().isEqualTo("argument 'Text' must start with a lowercase character");
|
|
}
|
|
}
|
|
|
|
@Test public void multipleNamedArguments() {
|
|
Map<String, Object> map = new LinkedHashMap<>();
|
|
map.put("pipe", System.class);
|
|
map.put("text", "tacos");
|
|
|
|
CodeBlock block = CodeBlock.builder()
|
|
.addNamed("$pipe:T.out.println(\"Let's eat some $text:L\");", map)
|
|
.build();
|
|
|
|
assertThat(block.toString()).isEqualTo(
|
|
"java.lang.System.out.println(\"Let's eat some tacos\");");
|
|
}
|
|
|
|
@Test public void namedNewline() {
|
|
Map<String, Object> map = new LinkedHashMap<>();
|
|
map.put("clazz", Integer.class);
|
|
CodeBlock block = CodeBlock.builder().addNamed("$clazz:T\n", map).build();
|
|
assertThat(block.toString()).isEqualTo("java.lang.Integer\n");
|
|
}
|
|
|
|
@Test public void danglingNamed() {
|
|
Map<String, Object> map = new LinkedHashMap<>();
|
|
map.put("clazz", Integer.class);
|
|
try {
|
|
CodeBlock.builder().addNamed("$clazz:T$", map).build();
|
|
fail();
|
|
} catch(IllegalArgumentException expected) {
|
|
assertThat(expected).hasMessageThat().isEqualTo("dangling $ at end");
|
|
}
|
|
}
|
|
|
|
@Test public void indexTooHigh() {
|
|
try {
|
|
CodeBlock.builder().add("$2T", String.class).build();
|
|
fail();
|
|
} catch (IllegalArgumentException expected) {
|
|
assertThat(expected).hasMessageThat().isEqualTo("index 2 for '$2T' not in range (received 1 arguments)");
|
|
}
|
|
}
|
|
|
|
@Test public void indexIsZero() {
|
|
try {
|
|
CodeBlock.builder().add("$0T", String.class).build();
|
|
fail();
|
|
} catch (IllegalArgumentException expected) {
|
|
assertThat(expected).hasMessageThat().isEqualTo("index 0 for '$0T' not in range (received 1 arguments)");
|
|
}
|
|
}
|
|
|
|
@Test public void indexIsNegative() {
|
|
try {
|
|
CodeBlock.builder().add("$-1T", String.class).build();
|
|
fail();
|
|
} catch (IllegalArgumentException expected) {
|
|
assertThat(expected).hasMessageThat().isEqualTo("invalid format string: '$-1T'");
|
|
}
|
|
}
|
|
|
|
@Test public void indexWithoutFormatType() {
|
|
try {
|
|
CodeBlock.builder().add("$1", String.class).build();
|
|
fail();
|
|
} catch (IllegalArgumentException expected) {
|
|
assertThat(expected).hasMessageThat().isEqualTo("dangling format characters in '$1'");
|
|
}
|
|
}
|
|
|
|
@Test public void indexWithoutFormatTypeNotAtStringEnd() {
|
|
try {
|
|
CodeBlock.builder().add("$1 taco", String.class).build();
|
|
fail();
|
|
} catch (IllegalArgumentException expected) {
|
|
assertThat(expected).hasMessageThat().isEqualTo("invalid format string: '$1 taco'");
|
|
}
|
|
}
|
|
|
|
@Test public void indexButNoArguments() {
|
|
try {
|
|
CodeBlock.builder().add("$1T").build();
|
|
fail();
|
|
} catch (IllegalArgumentException expected) {
|
|
assertThat(expected).hasMessageThat().isEqualTo("index 1 for '$1T' not in range (received 0 arguments)");
|
|
}
|
|
}
|
|
|
|
@Test public void formatIndicatorAlone() {
|
|
try {
|
|
CodeBlock.builder().add("$", String.class).build();
|
|
fail();
|
|
} catch (IllegalArgumentException expected) {
|
|
assertThat(expected).hasMessageThat().isEqualTo("dangling format characters in '$'");
|
|
}
|
|
}
|
|
|
|
@Test public void formatIndicatorWithoutIndexOrFormatType() {
|
|
try {
|
|
CodeBlock.builder().add("$ tacoString", String.class).build();
|
|
fail();
|
|
} catch (IllegalArgumentException expected) {
|
|
assertThat(expected).hasMessageThat().isEqualTo("invalid format string: '$ tacoString'");
|
|
}
|
|
}
|
|
|
|
@Test public void sameIndexCanBeUsedWithDifferentFormats() {
|
|
CodeBlock block = CodeBlock.builder()
|
|
.add("$1T.out.println($1S)", ClassName.get(System.class))
|
|
.build();
|
|
assertThat(block.toString()).isEqualTo("java.lang.System.out.println(\"java.lang.System\")");
|
|
}
|
|
|
|
@Test public void tooManyStatementEnters() {
|
|
CodeBlock codeBlock = CodeBlock.builder().add("$[$[").build();
|
|
try {
|
|
// We can't report this error until rendering type because code blocks might be composed.
|
|
codeBlock.toString();
|
|
fail();
|
|
} catch (IllegalStateException expected) {
|
|
assertThat(expected).hasMessageThat().isEqualTo("statement enter $[ followed by statement enter $[");
|
|
}
|
|
}
|
|
|
|
@Test public void statementExitWithoutStatementEnter() {
|
|
CodeBlock codeBlock = CodeBlock.builder().add("$]").build();
|
|
try {
|
|
// We can't report this error until rendering type because code blocks might be composed.
|
|
codeBlock.toString();
|
|
fail();
|
|
} catch (IllegalStateException expected) {
|
|
assertThat(expected).hasMessageThat().isEqualTo("statement exit $] has no matching statement enter $[");
|
|
}
|
|
}
|
|
|
|
@Test public void join() {
|
|
List<CodeBlock> codeBlocks = new ArrayList<>();
|
|
codeBlocks.add(CodeBlock.of("$S", "hello"));
|
|
codeBlocks.add(CodeBlock.of("$T", ClassName.get("world", "World")));
|
|
codeBlocks.add(CodeBlock.of("need tacos"));
|
|
|
|
CodeBlock joined = CodeBlock.join(codeBlocks, " || ");
|
|
assertThat(joined.toString()).isEqualTo("\"hello\" || world.World || need tacos");
|
|
}
|
|
|
|
@Test public void joining() {
|
|
List<CodeBlock> codeBlocks = new ArrayList<>();
|
|
codeBlocks.add(CodeBlock.of("$S", "hello"));
|
|
codeBlocks.add(CodeBlock.of("$T", ClassName.get("world", "World")));
|
|
codeBlocks.add(CodeBlock.of("need tacos"));
|
|
|
|
CodeBlock joined = codeBlocks.stream().collect(CodeBlock.joining(" || "));
|
|
assertThat(joined.toString()).isEqualTo("\"hello\" || world.World || need tacos");
|
|
}
|
|
|
|
@Test public void joiningSingle() {
|
|
List<CodeBlock> codeBlocks = new ArrayList<>();
|
|
codeBlocks.add(CodeBlock.of("$S", "hello"));
|
|
|
|
CodeBlock joined = codeBlocks.stream().collect(CodeBlock.joining(" || "));
|
|
assertThat(joined.toString()).isEqualTo("\"hello\"");
|
|
}
|
|
|
|
@Test public void joiningWithPrefixAndSuffix() {
|
|
List<CodeBlock> codeBlocks = new ArrayList<>();
|
|
codeBlocks.add(CodeBlock.of("$S", "hello"));
|
|
codeBlocks.add(CodeBlock.of("$T", ClassName.get("world", "World")));
|
|
codeBlocks.add(CodeBlock.of("need tacos"));
|
|
|
|
CodeBlock joined = codeBlocks.stream().collect(CodeBlock.joining(" || ", "start {", "} end"));
|
|
assertThat(joined.toString()).isEqualTo("start {\"hello\" || world.World || need tacos} end");
|
|
}
|
|
}
|