/** Test the custom pattern */
 @Test
 public void testCustomPattern() {
   final List<PatternFormatter> formatters = parser.parse(customPattern);
   assertNotNull(formatters);
   final Map<String, String> mdc = new HashMap<>();
   mdc.put("loginId", "Fred");
   final Throwable t = new Throwable();
   final StackTraceElement[] elements = t.getStackTrace();
   final Log4jLogEvent event =
       Log4jLogEvent.newBuilder() //
           .setLoggerName("org.apache.logging.log4j.PatternParserTest") //
           .setMarker(MarkerManager.getMarker("TEST")) //
           .setLoggerFqcn(Logger.class.getName()) //
           .setLevel(Level.INFO) //
           .setMessage(new SimpleMessage("Hello, world")) //
           .setContextMap(mdc) //
           .setThreadName("Thread1") //
           .setSource(elements[0])
           .setTimeMillis(System.currentTimeMillis())
           .build();
   final StringBuilder buf = new StringBuilder();
   for (final PatternFormatter formatter : formatters) {
     formatter.format(event, buf);
   }
   final String str = buf.toString();
   final String expected =
       "INFO  [PatternParserTest        :100 ] - Hello, world" + Strings.LINE_SEPARATOR;
   assertTrue("Expected to end with: " + expected + ". Actual: " + str, str.endsWith(expected));
 }
 private void testNestedPatternHighlight(final Level level, final String expectedStart) {
   final List<PatternFormatter> formatters = parser.parse(nestedPatternHighlight);
   assertNotNull(formatters);
   final Throwable t = new Throwable();
   t.getStackTrace();
   final LogEvent event =
       Log4jLogEvent.newBuilder() //
           .setLoggerName("org.apache.logging.log4j.PatternParserTest") //
           .setMarker(MarkerManager.getMarker("TEST")) //
           .setLoggerFqcn(Logger.class.getName()) //
           .setLevel(level) //
           .setMessage(new SimpleMessage("Hello, world")) //
           .setThreadName("Thread1") //
           .setSource(/*stackTraceElement[0]*/ null) //
           .setTimeMillis(System.currentTimeMillis()) //
           .build();
   final StringBuilder buf = new StringBuilder();
   for (final PatternFormatter formatter : formatters) {
     formatter.format(event, buf);
   }
   final String str = buf.toString();
   final String expectedEnd =
       String.format("] %-5s: Hello, world%s\u001B[m", level, Strings.LINE_SEPARATOR);
   assertTrue(
       "Expected to start with: " + expectedStart + ". Actual: " + str,
       str.startsWith(expectedStart));
   assertTrue(
       "Expected to end with: \"" + expectedEnd + "\". Actual: \"" + str,
       str.endsWith(expectedEnd));
 }
  @Test
  public void testBadPattern() {
    final Calendar cal = Calendar.getInstance();
    cal.set(2001, Calendar.FEBRUARY, 3, 4, 5, 6);
    cal.set(Calendar.MILLISECOND, 789);
    final long timestamp = cal.getTimeInMillis();

    final List<PatternFormatter> formatters = parser.parse(badPattern);
    assertNotNull(formatters);
    final Throwable t = new Throwable();
    final StackTraceElement[] elements = t.getStackTrace();
    final LogEvent event =
        Log4jLogEvent.newBuilder() //
            .setLoggerName("a.b.c") //
            .setLoggerFqcn(Logger.class.getName()) //
            .setLevel(Level.INFO) //
            .setMessage(new SimpleMessage("Hello, world")) //
            .setThreadName("Thread1") //
            .setSource(elements[0]) //
            .setTimeMillis(timestamp) //
            .build();
    final StringBuilder buf = new StringBuilder();
    for (final PatternFormatter formatter : formatters) {
      formatter.format(event, buf);
    }
    final String str = buf.toString();

    // eats all characters until the closing '}' character
    final String expected = "[2001-02-03 04:05:06,789] - Hello, world";
    assertTrue(
        "Expected to start with: " + expected + ". Actual: " + str, str.startsWith(expected));
  }
 public void format(LogEvent event, StringBuilder toAppendTo) {
   StringBuilder buf = new StringBuilder();
   for (PatternFormatter formatter : this.formatters) {
     formatter.format(event, buf);
   }
   toAppendTo.append(this.pattern.matcher(buf.toString()).replaceAll(this.substitution));
 }
 @Test
 public void testPatternTruncateFromEnd() {
   final List<PatternFormatter> formatters = parser.parse(patternTruncateFromEnd);
   assertNotNull(formatters);
   final LogEvent event =
       Log4jLogEvent.newBuilder() //
           .setLoggerName("org.apache.logging.log4j.PatternParserTest") //
           .setLoggerFqcn(Logger.class.getName()) //
           .setLevel(Level.INFO) //
           .setMessage(new SimpleMessage("Hello, world")) //
           .setThreadName("Thread1") //
           .setTimeMillis(System.currentTimeMillis()) //
           .build();
   final StringBuilder buf = new StringBuilder();
   for (final PatternFormatter formatter : formatters) {
     formatter.format(event, buf);
   }
   final String str = buf.toString();
   final String expected = "INFO  org.a Hello, world" + Strings.LINE_SEPARATOR;
   assertTrue("Expected to end with: " + expected + ". Actual: " + str, str.endsWith(expected));
 }