PiperOrigin-RevId: 665539414pull/17878/head
parent
8bb789e462
commit
737803eec4
6 changed files with 182 additions and 9 deletions
@ -0,0 +1,52 @@ |
||||
package com.google.protobuf; |
||||
|
||||
/** |
||||
* ProtobufToStringOutput controls the output format of {@link Message#toString()}. Specifically, for |
||||
* the Runnable object passed to `callWithDebugFormat` and `callWithTextFormat`, Message.toString() |
||||
* will always output the specified format unless ProtobufToStringOutput is used again to change the |
||||
* output format. |
||||
*/ |
||||
public final class ProtobufToStringOutput { |
||||
private enum OutputMode { |
||||
DEBUG_FORMAT, |
||||
TEXT_FORMAT |
||||
} |
||||
|
||||
private static final ThreadLocal<OutputMode> outputMode = |
||||
new ThreadLocal<OutputMode>() { |
||||
@Override |
||||
protected OutputMode initialValue() { |
||||
return OutputMode.TEXT_FORMAT; |
||||
} |
||||
}; |
||||
|
||||
private ProtobufToStringOutput() {} |
||||
|
||||
@CanIgnoreReturnValue |
||||
private static OutputMode setOutputMode(OutputMode newMode) { |
||||
OutputMode oldMode = outputMode.get(); |
||||
outputMode.set(newMode); |
||||
return oldMode; |
||||
} |
||||
|
||||
private static void callWithSpecificFormat(Runnable impl, OutputMode mode) { |
||||
OutputMode oldMode = setOutputMode(mode); |
||||
try { |
||||
impl.run(); |
||||
} finally { |
||||
OutputMode unused = setOutputMode(oldMode); |
||||
} |
||||
} |
||||
|
||||
public static void callWithDebugFormat(Runnable impl) { |
||||
callWithSpecificFormat(impl, OutputMode.DEBUG_FORMAT); |
||||
} |
||||
|
||||
public static void callWithTextFormat(Runnable impl) { |
||||
callWithSpecificFormat(impl, OutputMode.TEXT_FORMAT); |
||||
} |
||||
|
||||
public static boolean shouldOutputDebugFormat() { |
||||
return outputMode.get() == OutputMode.DEBUG_FORMAT; |
||||
} |
||||
} |
@ -0,0 +1,103 @@ |
||||
package com.google.protobuf; |
||||
|
||||
import static com.google.common.truth.Truth.assertThat; |
||||
|
||||
import protobuf_unittest.UnittestProto.RedactedFields; |
||||
import protobuf_unittest.UnittestProto.TestNestedMessageRedaction; |
||||
import java.util.ArrayList; |
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.junit.runner.RunWith; |
||||
import org.junit.runners.JUnit4; |
||||
|
||||
@RunWith(JUnit4.class) |
||||
public final class ProtobufToStringOutputTest extends DebugFormatTest { |
||||
RedactedFields message; |
||||
|
||||
@Before |
||||
public void setupTest() { |
||||
message = |
||||
RedactedFields.newBuilder() |
||||
.setOptionalUnredactedString("foo") |
||||
.setOptionalRedactedString("bar") |
||||
.setOptionalRedactedMessage( |
||||
TestNestedMessageRedaction.newBuilder().setOptionalUnredactedNestedString("foobar")) |
||||
.build(); |
||||
} |
||||
|
||||
@Test |
||||
public void toStringFormat_defaultFormat() { |
||||
assertThat(message.toString()) |
||||
.matches( |
||||
"optional_redacted_string: \"bar\"\n" |
||||
+ "optional_unredacted_string: \"foo\"\n" |
||||
+ "optional_redacted_message \\{\n" |
||||
+ " optional_unredacted_nested_string: \"foobar\"\n" |
||||
+ "\\}\n"); |
||||
} |
||||
|
||||
@Test |
||||
public void toStringFormat_testDebugFormat() { |
||||
ProtobufToStringOutput.callWithDebugFormat( |
||||
() -> |
||||
assertThat(message.toString()) |
||||
.matches( |
||||
String.format( |
||||
"%soptional_redacted_string: %s\n" |
||||
+ "optional_unredacted_string: \"foo\"\n" |
||||
+ "optional_redacted_message \\{\n" |
||||
+ " %s\n" |
||||
+ "\\}\n", |
||||
UNSTABLE_PREFIX_MULTILINE, REDACTED_REGEX, REDACTED_REGEX))); |
||||
} |
||||
|
||||
@Test |
||||
public void toStringFormat_testTextFormat() { |
||||
ProtobufToStringOutput.callWithTextFormat( |
||||
() -> { |
||||
assertThat(message.toString()) |
||||
.matches( |
||||
"optional_redacted_string: \"bar\"\n" |
||||
+ "optional_unredacted_string: \"foo\"\n" |
||||
+ "optional_redacted_message \\{\n" |
||||
+ " optional_unredacted_nested_string: \"foobar\"\n" |
||||
+ "\\}\n"); |
||||
}); |
||||
} |
||||
|
||||
@Test |
||||
public void toStringFormat_testProtoWrapperWithDebugFormat() { |
||||
ProtobufToStringOutput.callWithDebugFormat( |
||||
() -> { |
||||
ArrayList<RedactedFields> list = new ArrayList<>(); |
||||
list.add(message); |
||||
assertThat(list.toString()) |
||||
.matches( |
||||
String.format( |
||||
"\\[%soptional_redacted_string: %s\n" |
||||
+ "optional_unredacted_string: \"foo\"\n" |
||||
+ "optional_redacted_message \\{\n" |
||||
+ " %s\n" |
||||
+ "\\}\n" |
||||
+ "\\]", |
||||
UNSTABLE_PREFIX_MULTILINE, REDACTED_REGEX, REDACTED_REGEX)); |
||||
}); |
||||
} |
||||
|
||||
@Test |
||||
public void toStringFormat_testProtoWrapperWithTextFormat() { |
||||
ProtobufToStringOutput.callWithTextFormat( |
||||
() -> { |
||||
ArrayList<RedactedFields> list = new ArrayList<>(); |
||||
list.add(message); |
||||
assertThat(list.toString()) |
||||
.matches( |
||||
"\\[optional_redacted_string: \"bar\"\n" |
||||
+ "optional_unredacted_string: \"foo\"\n" |
||||
+ "optional_redacted_message \\{\n" |
||||
+ " optional_unredacted_nested_string: \"foobar\"\n" |
||||
+ "\\}\n" |
||||
+ "\\]"); |
||||
}); |
||||
} |
||||
} |
Loading…
Reference in new issue