package me.dinowernli.grpc.polyglot.command;
import java.util.Optional;
import com.google.common.collect.ImmutableList;
import com.google.protobuf.DescriptorProtos.FileDescriptorSet;
import me.dinowernli.grpc.polyglot.testing.RecordingOutput;
import org.junit.Before;
import org.junit.Test;
import polyglot.test.TestProto;
import polyglot.test.foo.FooProto;
import static com.google.common.truth.Truth.assertThat;
/** Unit tests for {@link ServiceList}. */
public class ServiceListTest {
private static FileDescriptorSet PROTO_FILE_DESCRIPTORS = FileDescriptorSet.newBuilder()
.addFile(TestProto.getDescriptor().toProto())
.addFile(FooProto.getDescriptor().toProto())
.build();
private static final String EXPECTED_SERVICE = "polyglot.test.TestService";
private static final ImmutableList<String> EXPECTED_METHOD_NAMES = ImmutableList.of(
"TestMethod", "TestMethodStream", "TestMethodClientStream", "TestMethodBidi");
private RecordingOutput recordingOutput;
@Before
public void setUp() throws Throwable {
recordingOutput = new RecordingOutput();
}
@Test
public void testServiceListOutput() throws Throwable {
ServiceList.listServices(
recordingOutput,
PROTO_FILE_DESCRIPTORS,
"",
Optional.empty(),
Optional.empty(),
Optional.empty());
recordingOutput.close();
validateOutput(recordingOutput.getContentsAsString(), EXPECTED_SERVICE, EXPECTED_METHOD_NAMES);
}
@Test
public void testServiceListOutputWithServiceFilter() throws Throwable {
ServiceList.listServices(
recordingOutput,
PROTO_FILE_DESCRIPTORS,
"",
Optional.of("TestService"),
Optional.empty(),
Optional.empty());
recordingOutput.close();
validateOutput(recordingOutput.getContentsAsString(), EXPECTED_SERVICE, EXPECTED_METHOD_NAMES);
}
@Test
public void testServiceListOutputWithMethodFilter() throws Throwable {
ServiceList.listServices(
recordingOutput,
PROTO_FILE_DESCRIPTORS,
"",
Optional.of("TestService"),
Optional.of("TestMethodStream"),
Optional.empty());
recordingOutput.close();
validateOutput(
recordingOutput.getContentsAsString(),
EXPECTED_SERVICE,
ImmutableList.of("TestMethodStream"));
}
@Test
public void testServiceListOutputWithMessageDetail() throws Throwable {
ServiceList.listServices(
recordingOutput,
PROTO_FILE_DESCRIPTORS,
"",
Optional.of("TestService"),
Optional.of("TestMethodStream"),
Optional.of(true));
recordingOutput.close();
validateMessageOutput(recordingOutput.getContentsAsString());
}
/** Compares the actual output with the expected output format */
private void validateOutput(
String output, String serviceName, ImmutableList<String> methodNames) {
// Assuming no filters, we expect output of the form (note that [tmp_path]
// is a placeholder):
//
// polyglot.test.TestService ->
// [tmp_path]/src/main/proto/testing/test_service.proto
// polyglot.test.TestService/TestMethod
// polyglot.test.TestService/TestMethodStream
// polyglot.test.TestService/TestMethodBidi
String[] lines = output.trim().split("\n");
assertThat(lines.length).isEqualTo(methodNames.size() + 1);
// Parse the first line (always [ServiceName] -> [FileName]
assertThat(lines[0]).startsWith(serviceName + " -> ");
// Parse the subsequent lines (always [ServiceName]/[MethodName])
for (int i = 0; i < methodNames.size(); i++) {
assertThat(lines[i + 1].trim()).isEqualTo(serviceName + "/" + methodNames.get(i));
}
}
/** Ensures that the message-rendering logic is correct */
private void validateMessageOutput(String output) {
// Assuming the filter is for TestService/TestMethodStream, then the message
// should render as:
//
// polyglot.test.TestService ->
// [tmp_path]/src/main/proto/testing/test_service.proto
// polyglot.test.TestService/TestMethodStream
// message[<optional> <single>]: STRING
// foo[<optional> <single>] {
// message[<optional> <single>]: STRING
// }
String[] lines = output.trim().split("\n");
// Parse the first line (always [ServiceName] -> [FileName]
assertThat(lines[0]).startsWith("polyglot.test.TestService -> ");
ImmutableList<String> expectedLines = ImmutableList.of(
"polyglot.test.TestService/TestMethodStream",
"message[<optional> <single>]: STRING",
"foo[<optional> <single>] {",
"message[<optional> <single>]: STRING",
"}");
for (int i = 0; i < expectedLines.size(); i++) {
assertThat(lines[i + 1].trim()).isEqualTo(expectedLines.get(i));
}
}
}