/* Copyright 2013 Jonatan Jönsson * * 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 se.softhouse.common.strings; import static com.google.common.collect.Lists.transform; import static com.google.common.collect.Maps.newLinkedHashMap; import static java.util.Arrays.asList; import static org.fest.assertions.Assertions.assertThat; import static org.junit.Assert.fail; import static se.softhouse.common.strings.Describers.asFunction; import static se.softhouse.common.strings.Describers.booleanAsEnabledDisabled; import static se.softhouse.common.strings.Describers.booleanAsOnOff; import static se.softhouse.common.strings.Describers.characterDescriber; import static se.softhouse.common.strings.Describers.fileDescriber; import static se.softhouse.common.strings.Describers.mapDescriber; import static se.softhouse.common.strings.Describers.numberDescriber; import static se.softhouse.common.strings.Describers.toStringDescriber; import static se.softhouse.common.strings.Describers.withConstantString; import static se.softhouse.common.strings.StringsUtil.NEWLINE; import static se.softhouse.common.testlib.Locales.TURKISH; import java.io.File; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Map; import org.junit.Test; import se.softhouse.common.strings.Describers.BooleanDescribers; import se.softhouse.common.testlib.Locales; import se.softhouse.common.testlib.ResourceLoader; import com.google.common.collect.Lists; import com.google.common.testing.NullPointerTester; import com.google.common.testing.NullPointerTester.Visibility; /** * Tests for {@link Describers} */ public class DescribersTest { private static final Locale locale = Locale.getDefault(); @Test public void testDescriberWithConstant() { Describer<Integer> constant = Describers.withConstantString("42"); assertThat(constant.describe(1, locale)).isEqualTo("42"); assertThat(constant.describe(2, locale)).isEqualTo("42"); assertThat(constant.describe(42, locale)).isEqualTo("42"); } @Test public void testThatDescribingNullYieldsNullString() { assertThat(toStringDescriber().describe(null, locale)).isEqualTo("null"); assertThat(characterDescriber().describe(null, locale)).isEqualTo("null"); assertThat(fileDescriber().describe(null, locale)).isEqualTo("null"); assertThat(mapDescriber(toStringDescriber()).describe(null, locale)).isEqualTo("null"); } @Test public void testThatToStringDescriberCallsToString() { assertThat(Describers.toStringDescriber().describe(42, locale)).isEqualTo("42"); } @Test public void testCharacterDescriber() { assertThat(characterDescriber().describe((char) 0, locale)).isEqualTo("the Null character"); assertThat(characterDescriber().describe('a', locale)).isEqualTo("a"); } @Test public void testFileDescriber() { File file = new File(""); assertThat(fileDescriber().describe(file, locale)).isEqualTo(file.getAbsolutePath()); } @Test public void testThatListDescriberDescribesEachValueWithTheValueDescriber() { Describer<List<?>> describer = Describers.listDescriber(withConstantString("42")); assertThat(describer.describe(Arrays.asList(1, 2, 3), locale)).isEqualTo("42, 42, 42"); assertThat(describer.describe(Collections.<Integer>emptyList(), locale)).isEqualTo("Empty list"); } @Test public void testThatListDescriberSeparatesValuesWithValueSeparator() { Describer<List<?>> dotter = Describers.listDescriber(withConstantString("."), ""); assertThat(dotter.describe(Arrays.asList(1, 2, 3), locale)).isEqualTo("..."); } @Test public void testDescriberAsAFunction() { List<Boolean> booleans = asList(true, false); List<String> describedBooleans = transform(booleans, asFunction(booleanAsEnabledDisabled())); assertThat(describedBooleans).isEqualTo(asList("enabled", "disabled")); } @Test public void testDescriberAsAFunctionWithSpecificLocale() throws InterruptedException { Locales.setDefault(Locales.SWEDISH); List<Integer> numbers = Arrays.asList(1000, 2000); List<String> describedNumbers = Lists.transform(numbers, asFunction(numberDescriber(), Locale.US)); assertThat(describedNumbers).isEqualTo(asList("1,000", "2,000")); Locales.resetDefaultLocale(); } @Test public void testFunctionAsADescriber() { String describedBoolean = Describers.usingFunction(asFunction(booleanAsEnabledDisabled())).describe(false, locale); assertThat(describedBoolean).isEqualTo("disabled"); } @Test public void testBooleanAsOnOff() { List<Boolean> booleans = asList(true, false); List<String> describedBooleans = transform(booleans, asFunction(booleanAsOnOff())); assertThat(describedBooleans).isEqualTo(asList("on", "off")); } @Test public void testThatNumberDescriberHandlesLocaleWell() { String shortInLocale = numberDescriber().describe(Short.MAX_VALUE, TURKISH); assertThat(shortInLocale).isEqualTo("32.767"); String integerInLocale = numberDescriber().describe(Integer.MAX_VALUE, TURKISH); assertThat(integerInLocale).isEqualTo("2.147.483.647"); String longInLocale = numberDescriber().describe(Long.MAX_VALUE, TURKISH); assertThat(longInLocale).isEqualTo("9.223.372.036.854.775.807"); String bigIntegerInLocale = numberDescriber().describe(BigInteger.valueOf(1000), TURKISH); assertThat(bigIntegerInLocale).isEqualTo("1.000"); String bigDecimalInLocale = numberDescriber().describe(BigDecimal.valueOf(1000), TURKISH); assertThat(bigDecimalInLocale).isEqualTo("1.000"); } @Test public void testMapDescriber() { Map<String, Integer> defaults = newLinkedHashMap(); defaults.put("population", 42); defaults.put("hello", 1); Map<String, String> descriptions = newLinkedHashMap(); descriptions.put("population", "The number of citizens in the world"); descriptions.put("hello", "The number of times to say hello"); Describer<Map<String, Integer>> propertyDescriber = mapDescriber(descriptions); String describedMap = propertyDescriber.describe(defaults, locale); assertThat(describedMap).isEqualTo(ResourceLoader.get("/common/described-map.txt")); Map<Number, String> numberDescriptions = newLinkedHashMap(); numberDescriptions.put(2000, "MM"); Describer<Map<Number, String>> numberDescriber = mapDescriber(numberDescriptions, Describers.numberDescriber()); assertThat(numberDescriber.describe(numberDescriptions, TURKISH)).contains("2.000=MM"); } @Test public void testMapDescriberForValuesAndKeysWithCustomSeparator() { Map<String, Integer> values = newLinkedHashMap(); values.put("anything", 73); values.put("everything", 42); // Test with custom valueDescriber, custom keyDescriber and custom separator Describer<Map<String, Integer>> customValueKeySeparator = mapDescriber( Describers.<String>withConstantString("foo"), Describers.<Integer>withConstantString("bar"), ":"); String describedMap = customValueKeySeparator.describe(values, locale); assertThat(describedMap).isEqualTo("foo:bar" + NEWLINE + "foo:bar"); assertThat(customValueKeySeparator.describe(Collections.<String, Integer>emptyMap(), locale)).isEqualTo("Empty map"); // Test with custom valueDescriber and custom separator Describer<Map<String, String>> customValueAndSeparator = mapDescriber(Describers.<String>withConstantString("foo"), ":"); Map<String, String> valuesCustomValueAndSeparator = newLinkedHashMap(); valuesCustomValueAndSeparator.put("hello", "world"); assertThat(customValueAndSeparator.describe(valuesCustomValueAndSeparator, locale)).contains("hello:foo"); // Test with custom valueDescriber Describer<Map<String, String>> customValue = mapDescriber(Describers.<String>withConstantString("foo")); assertThat(customValue.describe(valuesCustomValueAndSeparator, locale)).contains("hello=foo"); // Test with custom valueDescriber, custom keyDescriber Describer<Map<String, Integer>> customValueAndKey = mapDescriber( Describers.<String>withConstantString("foo"), Describers.<Integer>withConstantString("bar")); assertThat(customValueAndKey.describe(values, locale)).contains("foo=bar" + NEWLINE + "foo=bar"); } @Test public void testThatMissingKeyThrows() { Map<String, Integer> map = newLinkedHashMap(); map.put("population", 42); Map<String, String> noDescriptions = newLinkedHashMap(); // No description of population Describer<Map<String, Integer>> describer = mapDescriber(noDescriptions); try { describer.describe(map, locale); fail("population should have to be described"); } catch(NullPointerException expected) { assertThat(expected).hasMessage("Undescribed key: population"); } } @Test public void testToStringStrings() { assertThat(BooleanDescribers.valueOf("ON_OFF").toString()).isEqualTo("ON_OFF"); assertThat(numberDescriber().toString()).isEqualTo("NumberDescriber"); } @Test public void testThatNullContractsAreFollowed() throws Exception { new NullPointerTester().testStaticMethods(Describers.class, Visibility.PACKAGE); } }