### Question:
AnsiLoggerWithFooter implements ConsoleLogger { @Override public void log(Level logLevel, String message) { if (!messageConsumers.containsKey(logLevel)) { return; } Consumer<String> messageConsumer = messageConsumers.get(logLevel); singleThreadedExecutor.execute( () -> { boolean didErase = eraseFooter(); if (didErase) { if (enableTwoCursorUpJump) { messageConsumer.accept(String.format(CURSOR_UP_SEQUENCE_TEMPLATE, 2)); messageConsumer.accept(message); } else { messageConsumer.accept(CURSOR_UP_SEQUENCE + message); } } else { messageConsumer.accept(message); } printInBold(footerLines); }); } AnsiLoggerWithFooter(
      ImmutableMap<Level, Consumer<String>> messageConsumers,
      SingleThreadedExecutor singleThreadedExecutor,
      boolean enableTwoCursorUpJump); @Override void log(Level logLevel, String message); @Override void setFooter(List<String> newFooterLines);  }### Answer:
@Test public void testLog_noFooter() { AnsiLoggerWithFooter testAnsiLoggerWithFooter = createTestLogger(false); testAnsiLoggerWithFooter.log(Level.LIFECYCLE, "lifecycle"); testAnsiLoggerWithFooter.log(Level.PROGRESS, "progress"); testAnsiLoggerWithFooter.log(Level.INFO, "info"); testAnsiLoggerWithFooter.log(Level.DEBUG, "debug"); testAnsiLoggerWithFooter.log(Level.WARN, "warn"); testAnsiLoggerWithFooter.log(Level.ERROR, "error"); singleThreadedExecutor.shutDownAndAwaitTermination(SHUTDOWN_TIMEOUT); Assert.assertEquals( Arrays.asList("lifecycle", "progress", "info", "debug", "warn", "error"), messages); Assert.assertEquals( Arrays.asList( Level.LIFECYCLE, Level.PROGRESS, Level.INFO, Level.DEBUG, Level.WARN, Level.ERROR), levels); }
@Test public void testLog_ignoreIfNoMessageConsumer() { AnsiLoggerWithFooter testAnsiLoggerWithFooter = new AnsiLoggerWithFooter( ImmutableMap.of(Level.LIFECYCLE, createMessageConsumer(Level.LIFECYCLE)), singleThreadedExecutor, false); testAnsiLoggerWithFooter.log(Level.LIFECYCLE, "lifecycle"); testAnsiLoggerWithFooter.log(Level.PROGRESS, "progress"); testAnsiLoggerWithFooter.log(Level.INFO, "info"); testAnsiLoggerWithFooter.log(Level.DEBUG, "debug"); testAnsiLoggerWithFooter.log(Level.WARN, "warn"); testAnsiLoggerWithFooter.log(Level.ERROR, "error"); singleThreadedExecutor.shutDownAndAwaitTermination(SHUTDOWN_TIMEOUT); Assert.assertEquals(Collections.singletonList("lifecycle"), messages); Assert.assertEquals(Collections.singletonList(Level.LIFECYCLE), levels); }