From d6200389eb6127714dd7fa12f929decfc56d2de8 Mon Sep 17 00:00:00 2001 From: Geoffrey Chandler Date: Mon, 23 Mar 2015 14:58:56 -0700 Subject: [PATCH] Add support for ANSI colored resource banners Add AnsiPropertySource which allows named ANSI codes to be resolved and update ResourceBanner to include it. This commit also deprecates constants defined in AnsiElement and replaces them with AnsiStyle, AnsiColor and AnsiBackground enums. Closes gh-2704 --- .../main/asciidoc/spring-boot-features.adoc | 4 + .../springframework/boot/ResourceBanner.java | 8 ++ .../boot/SpringBootBanner.java | 6 +- .../boot/ansi/AnsiBackground.java | 73 ++++++++++++ .../springframework/boot/ansi/AnsiColor.java | 73 ++++++++++++ .../boot/ansi/AnsiElement.java | 56 +++++++++ .../springframework/boot/ansi/AnsiOutput.java | 14 ++- .../boot/ansi/AnsiPropertySource.java | 110 ++++++++++++++++++ .../springframework/boot/ansi/AnsiStyle.java | 48 ++++++++ .../boot/logging/logback/ColorConverter.java | 22 ++-- .../boot/ResourceBannerTests.java | 26 +++++ .../boot/ansi/AnsiPropertySourceTests.java | 86 ++++++++++++++ 12 files changed, 512 insertions(+), 14 deletions(-) create mode 100644 spring-boot/src/main/java/org/springframework/boot/ansi/AnsiBackground.java create mode 100644 spring-boot/src/main/java/org/springframework/boot/ansi/AnsiColor.java create mode 100644 spring-boot/src/main/java/org/springframework/boot/ansi/AnsiPropertySource.java create mode 100644 spring-boot/src/main/java/org/springframework/boot/ansi/AnsiStyle.java create mode 100644 spring-boot/src/test/java/org/springframework/boot/ansi/AnsiPropertySourceTests.java diff --git a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc index e56067e90de..a60362f4016 100644 --- a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc +++ b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc @@ -72,6 +72,10 @@ display (surrounded with brackets and prefixed with `v`). For example `(v1.0)`. |`${spring-boot.formatted-version}` |The Spring Boot version that you are using formatted for display (surrounded with brackets and prefixed with `v`). For example `(v{spring-boot-version})`. + +|`${Ansi.NAME}`, +|Where `NAME` is the name of an ANSI escape code. See +{sc-spring-boot}/ansi/AnsiPropertySource.{sc-ext}[`AnsiPropertySource`] for details. |=== TIP: The `SpringBootApplication.setBanner(...)` method can be used if you want to generate diff --git a/spring-boot/src/main/java/org/springframework/boot/ResourceBanner.java b/spring-boot/src/main/java/org/springframework/boot/ResourceBanner.java index 0bc021c887a..89a82a0b840 100644 --- a/spring-boot/src/main/java/org/springframework/boot/ResourceBanner.java +++ b/spring-boot/src/main/java/org/springframework/boot/ResourceBanner.java @@ -25,6 +25,7 @@ import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.boot.ansi.AnsiPropertySource; import org.springframework.core.env.Environment; import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.MutablePropertySources; @@ -77,6 +78,7 @@ public class ResourceBanner implements Banner { List resolvers = new ArrayList(); resolvers.add(environment); resolvers.add(getVersionResolver(sourceClass)); + resolvers.add(getAnsiResolver()); return resolvers; } @@ -114,4 +116,10 @@ public class ResourceBanner implements Banner { return (format ? " (v" + version + ")" : version); } + private PropertyResolver getAnsiResolver() { + MutablePropertySources sources = new MutablePropertySources(); + sources.addFirst(new AnsiPropertySource("ansi", true)); + return new PropertySourcesPropertyResolver(sources); + } + } diff --git a/spring-boot/src/main/java/org/springframework/boot/SpringBootBanner.java b/spring-boot/src/main/java/org/springframework/boot/SpringBootBanner.java index 4c738781135..2489859dfb6 100644 --- a/spring-boot/src/main/java/org/springframework/boot/SpringBootBanner.java +++ b/spring-boot/src/main/java/org/springframework/boot/SpringBootBanner.java @@ -21,9 +21,9 @@ import java.io.PrintStream; import org.springframework.boot.ansi.AnsiOutput; import org.springframework.core.env.Environment; -import static org.springframework.boot.ansi.AnsiElement.DEFAULT; -import static org.springframework.boot.ansi.AnsiElement.FAINT; -import static org.springframework.boot.ansi.AnsiElement.GREEN; +import static org.springframework.boot.ansi.AnsiColor.DEFAULT; +import static org.springframework.boot.ansi.AnsiColor.GREEN; +import static org.springframework.boot.ansi.AnsiStyle.FAINT; /** * Default Banner implementation which writes the 'Spring' banner. diff --git a/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiBackground.java b/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiBackground.java new file mode 100644 index 00000000000..cf174e0ccfd --- /dev/null +++ b/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiBackground.java @@ -0,0 +1,73 @@ +/* + * Copyright 2012-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.ansi; + +/** + * {@link AnsiElement Ansi} background colors. + * + * @author Phillip Webb + * @author Geoffrey Chandler + * @since 1.3.0 + */ +public enum AnsiBackground implements AnsiElement { + + DEFAULT("49"), + + BLACK("40"), + + RED("41"), + + GREEN("42"), + + YELLOW("43"), + + BLUE("44"), + + MAGENTA("45"), + + CYAN("46"), + + WHITE("47"), + + BRIGHT_BLACK("100"), + + BRIGHT_RED("101"), + + BRIGHT_GREEN("102"), + + BRIGHT_YELLOW("103"), + + BRIGHT_BLUE("104"), + + BRIGHT_MAGENTA("105"), + + BRIGHT_CYAN("106"), + + BRIGHT_WHITE("107"); + + private String code; + + private AnsiBackground(String code) { + this.code = code; + } + + @Override + public String toString() { + return this.code; + } + +} diff --git a/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiColor.java b/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiColor.java new file mode 100644 index 00000000000..c5a56ae3e87 --- /dev/null +++ b/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiColor.java @@ -0,0 +1,73 @@ +/* + * Copyright 2012-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.ansi; + +/** + * {@link AnsiElement Ansi} colors. + * + * @author Phillip Webb + * @author Geoffrey Chandler + * @since 1.3.0 + */ +public enum AnsiColor implements AnsiElement { + + DEFAULT("39"), + + BLACK("30"), + + RED("31"), + + GREEN("32"), + + YELLOW("33"), + + BLUE("34"), + + MAGENTA("35"), + + CYAN("36"), + + WHITE("37"), + + BRIGHT_BLACK("90"), + + BRIGHT_RED("91"), + + BRIGHT_GREEN("92"), + + BRIGHT_YELLOW("93"), + + BRIGHT_BLUE("94"), + + BRIGHT_MAGENTA("95"), + + BRIGHT_CYAN("96"), + + BRIGHT_WHITE("97"); + + private final String code; + + private AnsiColor(String code) { + this.code = code; + } + + @Override + public String toString() { + return this.code; + } + +} diff --git a/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiElement.java b/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiElement.java index decbf0e2f75..249400dd332 100644 --- a/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiElement.java +++ b/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiElement.java @@ -23,32 +23,88 @@ package org.springframework.boot.ansi; */ public interface AnsiElement { + /** + * @deprecated in 1.3.0 in favor of {@link AnsiStyle#NORMAL} + */ + @Deprecated public static final AnsiElement NORMAL = new DefaultAnsiElement("0"); + /** + * @deprecated in 1.3.0 in favor of {@link AnsiStyle#BOLD} + */ + @Deprecated public static final AnsiElement BOLD = new DefaultAnsiElement("1"); + /** + * @deprecated in 1.3.0 in favor of {@link AnsiStyle#FAINT} + */ + @Deprecated public static final AnsiElement FAINT = new DefaultAnsiElement("2"); + /** + * @deprecated in 1.3.0 in favor of {@link AnsiStyle#ITALIC} + */ + @Deprecated public static final AnsiElement ITALIC = new DefaultAnsiElement("3"); + /** + * @deprecated in 1.3.0 in favor of {@link AnsiStyle#UNDERLINE} + */ + @Deprecated public static final AnsiElement UNDERLINE = new DefaultAnsiElement("4"); + /** + * @deprecated in 1.3.0 in favor of {@link AnsiColor#BLACK} + */ + @Deprecated public static final AnsiElement BLACK = new DefaultAnsiElement("30"); + /** + * @deprecated in 1.3.0 in favor of {@link AnsiColor#RED} + */ + @Deprecated public static final AnsiElement RED = new DefaultAnsiElement("31"); + /** + * @deprecated in 1.3.0 in favor of {@link AnsiColor#GREEN} + */ + @Deprecated public static final AnsiElement GREEN = new DefaultAnsiElement("32"); + /** + * @deprecated in 1.3.0 in favor of {@link AnsiColor#YELLOW} + */ + @Deprecated public static final AnsiElement YELLOW = new DefaultAnsiElement("33"); + /** + * @deprecated in 1.3.0 in favor of {@link AnsiColor#BLUE} + */ + @Deprecated public static final AnsiElement BLUE = new DefaultAnsiElement("34"); + /** + * @deprecated in 1.3.0 in favor of {@link AnsiColor#MAGENTA} + */ + @Deprecated public static final AnsiElement MAGENTA = new DefaultAnsiElement("35"); + /** + * @deprecated in 1.3.0 in favor of {@link AnsiColor#CYAN} + */ + @Deprecated public static final AnsiElement CYAN = new DefaultAnsiElement("36"); + /** + * @deprecated in 1.3.0 in favor of {@link AnsiColor#WHITE} + */ + @Deprecated public static final AnsiElement WHITE = new DefaultAnsiElement("37"); + /** + * @deprecated in 1.3.0 in favor of {@link AnsiColor#DEFAULT} + */ + @Deprecated public static final AnsiElement DEFAULT = new DefaultAnsiElement("39"); /** diff --git a/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiOutput.java b/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiOutput.java index a38eb208a2f..e46313022b4 100644 --- a/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiOutput.java +++ b/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiOutput.java @@ -39,7 +39,7 @@ public abstract class AnsiOutput { private static final String ENCODE_END = "m"; - private static final String RESET = "0;" + AnsiElement.DEFAULT; + private static final String RESET = "0;" + AnsiColor.DEFAULT; /** * Sets if ANSI output is enabled. @@ -63,6 +63,18 @@ public abstract class AnsiOutput { return AnsiOutput.enabled; } + /** + * Encode a single {@link AnsiElement} if output is enabled. + * @param element the element to encode + * @return the encoded element or an empty string + */ + public static String encode(AnsiElement element) { + if (isEnabled()) { + return ENCODE_START + element + ENCODE_END; + } + return ""; + } + /** * Create a new ANSI string from the specified elements. Any {@link AnsiElement}s will * be encoded as required. diff --git a/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiPropertySource.java b/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiPropertySource.java new file mode 100644 index 00000000000..eec6ad0fd4b --- /dev/null +++ b/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiPropertySource.java @@ -0,0 +1,110 @@ +/* + * Copyright 2012-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.ansi; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumSet; +import java.util.List; +import java.util.Set; + +import org.springframework.core.env.PropertyResolver; +import org.springframework.core.env.PropertySource; +import org.springframework.util.StringUtils; + +/** + * {@link PropertyResolver} for {@link AnsiStyle}, {@link AnsiColor} and + * {@link AnsiBackground} elements. Supports properties of the form {@code AnsiStyle.BOLD} + * , {@code AnsiColor.RED} or {@code AnsiBackground.GREEN}. Also supports a prefix of + * {@code Ansi.} which is an aggregation of everything (with background colors prefixed + * {@code BG_}). + * + * @author Phillip Webb + * @since 1.3.0 + */ +public class AnsiPropertySource extends PropertySource { + + private static final Iterable> MAPPED_ENUMS; + static { + List> enums = new ArrayList>(); + enums.add(new MappedEnum("AnsiStyle.", AnsiStyle.class)); + enums.add(new MappedEnum("AnsiColor.", AnsiColor.class)); + enums.add(new MappedEnum("AnsiBackground.", AnsiBackground.class)); + enums.add(new MappedEnum("Ansi.", AnsiStyle.class)); + enums.add(new MappedEnum("Ansi.", AnsiColor.class)); + enums.add(new MappedEnum("Ansi.BG_", AnsiBackground.class)); + MAPPED_ENUMS = Collections.unmodifiableList(enums); + } + + private final boolean encode; + + /** + * Create a new {@link AnsiPropertySource} instance. + * @param name the name of the property source + * @param encode if the output should be encoded + */ + public AnsiPropertySource(String name, boolean encode) { + super(name); + this.encode = encode; + } + + @Override + public Object getProperty(String name) { + if (StringUtils.hasLength(name)) { + for (MappedEnum mappedEnum : MAPPED_ENUMS) { + if (name.startsWith(mappedEnum.getPrefix())) { + String enumName = name.substring(mappedEnum.getPrefix().length()); + for (Enum ansiEnum : mappedEnum.getEnums()) { + if (ansiEnum.name().equals(enumName)) { + if (this.encode) { + return AnsiOutput.encode((AnsiElement) ansiEnum); + } + return ansiEnum; + } + } + } + } + } + return null; + } + + /** + * Mapping between an enum and the pseudo property source. + */ + private static class MappedEnum> { + + private final String prefix; + + private final Set enums; + + public MappedEnum(String prefix, Class enumType) { + this.prefix = prefix; + this.enums = EnumSet.allOf(enumType); + + } + + public String getPrefix() { + return this.prefix; + } + + public Set getEnums() { + return this.enums; + } + + } + +} diff --git a/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiStyle.java b/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiStyle.java new file mode 100644 index 00000000000..567bedf9a3b --- /dev/null +++ b/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiStyle.java @@ -0,0 +1,48 @@ +/* + * Copyright 2012-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.ansi; + +/** + * {@link AnsiElement Ansi} styles. + * + * @author Phillip Webb + * @since 1.3.0 + */ +public enum AnsiStyle implements AnsiElement { + + NORMAL("0"), + + BOLD("1"), + + FAINT("2"), + + ITALIC("3"), + + UNDERLINE("4"); + + private final String code; + + private AnsiStyle(String code) { + this.code = code; + } + + @Override + public String toString() { + return this.code; + } + +} diff --git a/spring-boot/src/main/java/org/springframework/boot/logging/logback/ColorConverter.java b/spring-boot/src/main/java/org/springframework/boot/logging/logback/ColorConverter.java index 49817701daf..a1838c5b39a 100644 --- a/spring-boot/src/main/java/org/springframework/boot/logging/logback/ColorConverter.java +++ b/spring-boot/src/main/java/org/springframework/boot/logging/logback/ColorConverter.java @@ -20,8 +20,10 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; +import org.springframework.boot.ansi.AnsiColor; import org.springframework.boot.ansi.AnsiElement; import org.springframework.boot.ansi.AnsiOutput; +import org.springframework.boot.ansi.AnsiStyle; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.spi.ILoggingEvent; @@ -39,21 +41,21 @@ public class ColorConverter extends CompositeConverter { private static final Map ELEMENTS; static { Map elements = new HashMap(); - elements.put("faint", AnsiElement.FAINT); - elements.put("red", AnsiElement.RED); - elements.put("green", AnsiElement.GREEN); - elements.put("yellow", AnsiElement.YELLOW); - elements.put("blue", AnsiElement.BLUE); - elements.put("magenta", AnsiElement.MAGENTA); - elements.put("cyan", AnsiElement.CYAN); + elements.put("faint", AnsiStyle.FAINT); + elements.put("red", AnsiColor.RED); + elements.put("green", AnsiColor.GREEN); + elements.put("yellow", AnsiColor.YELLOW); + elements.put("blue", AnsiColor.BLUE); + elements.put("magenta", AnsiColor.MAGENTA); + elements.put("cyan", AnsiColor.CYAN); ELEMENTS = Collections.unmodifiableMap(elements); } private static final Map LEVELS; static { Map levels = new HashMap(); - levels.put(Level.ERROR_INTEGER, AnsiElement.RED); - levels.put(Level.WARN_INTEGER, AnsiElement.YELLOW); + levels.put(Level.ERROR_INTEGER, AnsiColor.RED); + levels.put(Level.WARN_INTEGER, AnsiColor.YELLOW); LEVELS = Collections.unmodifiableMap(levels); } @@ -63,7 +65,7 @@ public class ColorConverter extends CompositeConverter { if (element == null) { // Assume highlighting element = LEVELS.get(event.getLevel().toInteger()); - element = (element == null ? AnsiElement.GREEN : element); + element = (element == null ? AnsiColor.GREEN : element); } return toAnsiString(in, element); } diff --git a/spring-boot/src/test/java/org/springframework/boot/ResourceBannerTests.java b/spring-boot/src/test/java/org/springframework/boot/ResourceBannerTests.java index b1c0ff4af19..2b5b1e8ff94 100644 --- a/spring-boot/src/test/java/org/springframework/boot/ResourceBannerTests.java +++ b/spring-boot/src/test/java/org/springframework/boot/ResourceBannerTests.java @@ -21,7 +21,10 @@ import java.io.PrintStream; import java.util.Collections; import java.util.Map; +import org.junit.After; import org.junit.Test; +import org.springframework.boot.ansi.AnsiOutput; +import org.springframework.boot.ansi.AnsiOutput.Enabled; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MapPropertySource; import org.springframework.core.io.ByteArrayResource; @@ -38,6 +41,11 @@ import static org.junit.Assert.assertThat; */ public class ResourceBannerTests { + @After + public void reset() { + AnsiOutput.setEnabled(Enabled.DETECT); + } + @Test public void renderVersions() throws Exception { Resource resource = new ByteArrayResource( @@ -72,6 +80,24 @@ public class ResourceBannerTests { assertThat(banner, startsWith("banner 1")); } + @Test + public void renderWithColors() throws Exception { + Resource resource = new ByteArrayResource( + "${Ansi.RED}This is red.${Ansi.NORMAL}".getBytes()); + AnsiOutput.setEnabled(AnsiOutput.Enabled.ALWAYS); + String banner = printBanner(resource, null, null); + assertThat(banner, startsWith("\u001B[31mThis is red.\u001B[0m")); + } + + @Test + public void renderWithColorsButDisabled() throws Exception { + Resource resource = new ByteArrayResource( + "${Ansi.RED}This is red.${Ansi.NORMAL}".getBytes()); + AnsiOutput.setEnabled(AnsiOutput.Enabled.NEVER); + String banner = printBanner(resource, null, null); + assertThat(banner, startsWith("This is red.")); + } + private String printBanner(Resource resource, String bootVersion, String applicationVersion) { ResourceBanner banner = new MockResourceBanner(resource, bootVersion, diff --git a/spring-boot/src/test/java/org/springframework/boot/ansi/AnsiPropertySourceTests.java b/spring-boot/src/test/java/org/springframework/boot/ansi/AnsiPropertySourceTests.java new file mode 100644 index 00000000000..f84018425b2 --- /dev/null +++ b/spring-boot/src/test/java/org/springframework/boot/ansi/AnsiPropertySourceTests.java @@ -0,0 +1,86 @@ +/* + * Copyright 2012-2015 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.ansi; + +import org.junit.After; +import org.junit.Test; +import org.springframework.boot.ansi.AnsiOutput.Enabled; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertThat; + +/** + * Tests for {@link AnsiPropertySource}. + * + * @author Phillip Webb + */ +public class AnsiPropertySourceTests { + + private AnsiPropertySource source = new AnsiPropertySource("ansi", false); + + @After + public void reset() { + AnsiOutput.setEnabled(Enabled.DETECT); + } + + @Test + public void getAnsiStyle() throws Exception { + assertThat(this.source.getProperty("AnsiStyle.BOLD"), + equalTo((Object) AnsiStyle.BOLD)); + } + + @Test + public void getAnsiColor() throws Exception { + assertThat(this.source.getProperty("AnsiColor.RED"), + equalTo((Object) AnsiColor.RED)); + } + + @Test + public void getAnsiBackground() throws Exception { + assertThat(this.source.getProperty("AnsiBackground.GREEN"), + equalTo((Object) AnsiBackground.GREEN)); + } + + @Test + public void getAnsi() throws Exception { + assertThat(this.source.getProperty("Ansi.BOLD"), equalTo((Object) AnsiStyle.BOLD)); + assertThat(this.source.getProperty("Ansi.RED"), equalTo((Object) AnsiColor.RED)); + assertThat(this.source.getProperty("Ansi.BG_RED"), + equalTo((Object) AnsiBackground.RED)); + } + + @Test + public void getMissing() throws Exception { + assertThat(this.source.getProperty("AnsiStyle.NOPE"), nullValue()); + } + + @Test + public void encodeEnabled() throws Exception { + AnsiOutput.setEnabled(Enabled.ALWAYS); + AnsiPropertySource source = new AnsiPropertySource("ansi", true); + assertThat(source.getProperty("Ansi.RED"), equalTo((Object) "\033[31m")); + } + + @Test + public void encodeDisabled() throws Exception { + AnsiOutput.setEnabled(Enabled.NEVER); + AnsiPropertySource source = new AnsiPropertySource("ansi", true); + assertThat(source.getProperty("Ansi.RED"), equalTo((Object) "")); + } + +}