package humanize;
import static humanize.ICUHumanize.compactDecimal;
import static humanize.ICUHumanize.dateFormatInstance;
import static humanize.ICUHumanize.decimalFormatInstance;
import static humanize.ICUHumanize.duration;
import static humanize.ICUHumanize.formatCurrency;
import static humanize.ICUHumanize.formatDate;
import static humanize.ICUHumanize.formatDateTime;
import static humanize.ICUHumanize.formatDecimal;
import static humanize.ICUHumanize.formatPercent;
import static humanize.ICUHumanize.formatPluralCurrency;
import static humanize.ICUHumanize.messageFormatInstance;
import static humanize.ICUHumanize.naturalDay;
import static humanize.ICUHumanize.naturalTime;
import static humanize.ICUHumanize.ordinalize;
import static humanize.ICUHumanize.parseNumber;
import static humanize.ICUHumanize.pluralize;
import static humanize.ICUHumanize.replaceSupplementary;
import static humanize.ICUHumanize.smartDateFormat;
import static humanize.ICUHumanize.spellNumber;
import static humanize.ICUHumanize.transliterate;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotEquals;
import static org.testng.Assert.assertTrue;
import humanize.icu.spi.MessageFormat;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.Random;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.ibm.icu.text.CompactDecimalFormat.CompactStyle;
public class TestICUHumanize
{
private static final Locale ES = new Locale("es", "ES");
private Random rand;
private Locale defaultLocale;
@Test(threadPoolSize = 10, invocationCount = 10)
public void compactDecimalLocaleTest()
{
Locale DE = Locale.GERMAN;
assertEquals(compactDecimal(-10, ES), "-10");
assertEquals(compactDecimal(-10000001, ES), "-10 M");
assertEquals(compactDecimal(-10, DE), "-10");
assertEquals(compactDecimal(-10000001, DE), "-10 Mio.");
assertEquals(compactDecimal(10, ES), "10");
assertEquals(compactDecimal(100000, ES), "100 K");
assertEquals(compactDecimal(100000000, ES), "100 M");
assertEquals(compactDecimal(2394000, ES), "2,4 M");
assertEquals(compactDecimal(10, DE), "10");
assertEquals(compactDecimal(100000, DE), "100 Tsd.");
assertEquals(compactDecimal(100000000, DE), "100 Mio.");
assertEquals(compactDecimal(2394000, DE), "2,4 Mio.");
assertEquals(compactDecimal(10, CompactStyle.LONG, ES), "10");
assertEquals(compactDecimal(100000, CompactStyle.LONG, ES), "100 mil");
assertEquals(compactDecimal(1000000, CompactStyle.LONG, ES), "1 millón");
assertEquals(compactDecimal(100000000, CompactStyle.LONG, ES), "100 millones");
assertEquals(compactDecimal(2394000, CompactStyle.LONG, ES), "2,4 millones");
assertEquals(compactDecimal(10, CompactStyle.LONG, DE), "10");
assertEquals(compactDecimal(100000, CompactStyle.LONG, DE), "100 Tausend");
assertEquals(compactDecimal(1000000, CompactStyle.LONG, DE), "1 Million");
assertEquals(compactDecimal(100000000, CompactStyle.LONG, DE), "100 Millionen");
assertEquals(compactDecimal(2394000, CompactStyle.LONG, DE), "2,4 Millionen");
}
@Test
public void compactDecimalTest()
{
assertEquals(compactDecimal(-10), "-10");
assertEquals(compactDecimal(-10000001), "-10M");
assertEquals(compactDecimal(10), "10");
assertEquals(compactDecimal(100000), "100K");
assertEquals(compactDecimal(100000000), "100M");
assertEquals(compactDecimal(2394000), "2.4M");
assertEquals(compactDecimal(10, CompactStyle.LONG), "10");
assertEquals(compactDecimal(100000, CompactStyle.LONG), "100 thousand");
assertEquals(compactDecimal(100000000, CompactStyle.LONG), "100 million");
assertEquals(compactDecimal(2394000, CompactStyle.LONG), "2.4 million");
}
@Test(threadPoolSize = 10, invocationCount = 10)
public void durationTest()
{
assertEquals(duration(1), "1 sec.");
assertEquals(duration(3730), "1:02:10");
}
@Test(threadPoolSize = 10, invocationCount = 10)
public void formatCurrencyTest()
{
int df = rand.nextInt(9);
assertEquals(formatCurrency(34), "£34");
assertEquals(formatCurrency(1000 + df), "£1,00" + df);
assertEquals(formatCurrency(10000.55 + df), "£10,00" + df + ".55");
assertEquals(formatCurrency(100, ES), "100 €");
assertEquals(formatCurrency(1000.55, ES), "1.000,55 €");
}
@Test(threadPoolSize = 10, invocationCount = 10)
public void formatDateTest()
{
int day = rand.nextInt(20) + 1;
Date date = newTestDate(day, 11, 2015);
assertEquals(formatDate(DateFormat.MEDIUM, date), String.format("%d Dec 2015", day));
assertEquals(formatDate(date), String.format("%02d/12/2015", day));
assertEquals(formatDate(DateFormat.MEDIUM, date, ES), String.format("%d dic. 2015", day));
assertEquals(formatDate(date, ES), String.format("%d/12/15", day));
assertEquals(formatDate(date, "dd/MM/yy"), String.format("%02d/12/15", day));
assertEquals(formatDate(date, "dd/MM/yy", ES), String.format("%02d/12/15", day));
}
@Test(threadPoolSize = 10, invocationCount = 10)
public void formatDateTimeTest()
{
int day = rand.nextInt(20) + 1;
Date date = newTestDate(day, 11, 2015, 22, 10, 0);
assertEquals(formatDateTime(DateFormat.MEDIUM, DateFormat.MEDIUM, date),
String.format("%d Dec 2015, 22:10:00", day));
assertEquals(formatDateTime(date), String.format("%02d/12/2015, 22:10", day));
assertEquals(formatDateTime(DateFormat.MEDIUM, DateFormat.MEDIUM, date, ES),
String.format("%d dic. 2015 22:10:00", day));
assertEquals(formatDateTime(date, ES), String.format("%d/12/15 22:10", day));
}
@Test(threadPoolSize = 10, invocationCount = 10)
public void formatDecimalTest()
{
int df = rand.nextInt(9);
assertEquals(formatDecimal(1000 + df), "1,00" + df);
assertEquals(formatDecimal(10000.55 + df), "10,00" + df + ".55");
assertEquals(formatDecimal(1000 + df, ES), "1.00" + df);
}
@Test(threadPoolSize = 10, invocationCount = 10)
public void formatPercentTest()
{
assertEquals(formatPercent(0), "0%");
assertEquals(formatPercent(-1), "-100%");
assertEquals(formatPercent(0.5), "50%");
assertEquals(formatPercent(1.5), "150%");
assertEquals(formatPercent(0.564), "56%");
assertEquals(formatPercent(1000.564), "100,056%");
assertEquals(formatPercent(0, ES), "0 %");
assertEquals(formatPercent(-1, ES), "-100 %");
assertEquals(formatPercent(0.5, ES), "50 %");
assertEquals(formatPercent(1.5, ES), "150 %");
assertEquals(formatPercent(0.564, ES), "56 %");
assertEquals(formatPercent(1000.564, ES), "100.056 %");
}
@Test(threadPoolSize = 10, invocationCount = 10)
public void formatPluralCurrencyTest()
{
int df = rand.nextInt(9);
assertEquals(formatPluralCurrency(34), "34 British pounds");
assertEquals(formatPluralCurrency(1000 + df), "1,00" + df + " British pounds");
assertEquals(formatPluralCurrency(10000.55 + df), "10,00" + df + ".55 British pounds");
assertEquals(formatPluralCurrency(1, ES), "1 euro");
assertEquals(formatPluralCurrency(100, ES), "100 euros");
assertEquals(formatPluralCurrency(1000.55, ES), "1.000,55 euros");
}
@Test(threadPoolSize = 10, invocationCount = 10)
public void formattersTest()
{
for (int i = 0; i < 3; i++)
{
assertEquals(decimalFormatInstance("@@##").format(i + 1.14159), String.format("%d.142", (i + 1)));
assertEquals(decimalFormatInstance("@@##", ES).format(i + 1.14159), String.format("%d,142", (i + 1)));
}
int day = rand.nextInt(20) + 1;
Date date = newTestDate(day, 11, 2015);
assertEquals(dateFormatInstance("dd/MM/yyyy").format(date), String.format("%02d/%d/%d", day, 12, 2015));
assertEquals(dateFormatInstance("dd/MM/yyyy", ES).format(date), String.format("%02d/%d/%d", day, 12, 2015));
}
@Test(threadPoolSize = 10, invocationCount = 10)
public void naturalDayTest()
{
Calendar cal = Calendar.getInstance();
assertEquals(naturalDay(cal.getTime()), "today");
cal.add(Calendar.DATE, 1);
assertEquals(naturalDay(cal.getTime()), "tomorrow");
cal.add(Calendar.DAY_OF_MONTH, -2);
assertEquals(naturalDay(cal.getTime()), "yesterday");
cal.add(Calendar.DAY_OF_WEEK, -1);
assertEquals(naturalDay(cal.getTime()), formatDate(cal.getTime()));
cal.setTime(new Date());
assertEquals(naturalDay(cal.getTime(), ES), "hoy");
cal.add(Calendar.DATE, 1);
assertEquals(naturalDay(cal.getTime(), ES), "mañana");
cal.add(Calendar.DATE, -2);
assertEquals(naturalDay(cal.getTime(), ES), "ayer");
}
@Test(threadPoolSize = 10, invocationCount = 10)
public void naturalTimeTest()
{
assertTrue(naturalTime(new Date(0), new Date(10)).endsWith(" from now"));
assertEquals(naturalTime(new Date(0), new Date(1000 * 60 * 12)), "12 minutes from now");
assertEquals(naturalTime(new Date(0), new Date(1000 * 60 * 60 * 3)), "3 hours from now");
assertEquals(naturalTime(new Date(0), new Date(1000 * 60 * 60 * 24 * 1)), "1 day from now");
assertEquals(naturalTime(new Date(0), new Date(1000 * 60 * 60 * 24 * 3)), "3 days from now");
assertEquals(naturalTime(new Date(0), new Date(1000 * 60 * 60 * 24 * 7 * 3)), "3 weeks from now");
assertEquals(naturalTime(new Date(0), new Date(2629743830L * 3L)), "2 months from now");
assertEquals(naturalTime(new Date(0), new Date(2629743830L * 13L * 3L)), "3 years from now");
assertEquals(naturalTime(new Date(0), new Date(315769289947L * 3L)), "30 years from now");
assertEquals(naturalTime(new Date(0), new Date(3155792597470L * 3L)), "300 years from now");
assertEquals(naturalTime(new Date(6000), new Date(0)), "6 seconds ago");
assertEquals(naturalTime(new Date(1000 * 60 * 12), new Date(0)), "12 minutes ago");
assertEquals(naturalTime(new Date(1000 * 60 * 60 * 3), new Date(0)), "3 hours ago");
assertEquals(naturalTime(new Date(1000 * 60 * 60 * 24 * 1), new Date(0)), "1 day ago");
assertEquals(naturalTime(new Date(1000 * 60 * 60 * 24 * 3), new Date(0)), "3 days ago");
assertEquals(naturalTime(new Date(1000 * 60 * 60 * 24 * 7 * 3), new Date(0)), "3 weeks ago");
assertEquals(naturalTime(new Date(2629743830L * 3L), new Date(0)), "2 months ago");
assertEquals(naturalTime(new Date(2629743830L * 13L * 3L), new Date(0)), "3 years ago");
assertEquals(naturalTime(new Date(315769289947L * 3L), new Date(0)), "30 years ago");
assertEquals(naturalTime(new Date(3155792597470L * 3L), new Date(0)), "300 years ago");
// within locale
assertTrue(naturalTime(new Date(0), new Date(10), ES).startsWith("dentro de"));
assertEquals(naturalTime(new Date(0), new Date(1000 * 60 * 60 * 3), ES), "dentro de 3 horas");
assertEquals(naturalTime(new Date(0), new Date(1000 * 60 * 60 * 24 * 1), ES), "dentro de un día");
assertEquals(naturalTime(new Date(315769289947L * 3L), new Date(0), ES), "hace 30 años");
assertEquals(naturalTime(new Date(3155792597470L * 3L), new Date(0), ES), "hace 300 años");
}
@Test(threadPoolSize = 10, invocationCount = 10)
public void ordinalizeTest()
{
assertEquals(ordinalize(0), "0th");
assertEquals(ordinalize(1), "1st");
assertEquals(ordinalize(2), "2nd");
assertEquals(ordinalize(3), "3rd");
assertEquals(ordinalize(4), "4th");
assertEquals(ordinalize(5), "5th");
assertEquals(ordinalize(33), "33rd");
assertEquals(ordinalize(11), "11th");
assertEquals(ordinalize(12), "12th");
assertEquals(ordinalize(13), "13th");
assertEquals(ordinalize(10), "10th");
assertEquals(ordinalize(22), "22nd");
assertEquals(ordinalize(101), "101st");
assertEquals(ordinalize(-10), "−10th");
assertEquals(ordinalize(1.25), "1st");
assertEquals(ordinalize(new Float(1.33)), "1st");
assertEquals(ordinalize(new Long(10000000)), "10,000,000th");
assertEquals(ordinalize(1, ES), "1º");
assertEquals(ordinalize(20, ES), "20º");
}
@Test(threadPoolSize = 10, invocationCount = 10)
public void parseNumberTest() throws ParseException
{
assertEquals(parseNumber("one hundred twenty-three").intValue(), 123);
assertEquals(parseNumber("doscientos un mil doscientos cincuenta y seis", ES).intValue(), 201256);
}
@Test(threadPoolSize = 10, invocationCount = 10)
public void pluralizeWithFormatInstance()
{
int df = rand.nextInt(9);
MessageFormat f = messageFormatInstance("There {0, plural, one{is one file}other{are {0} files}} on {1}.");
assertEquals(f.render(1000 + df, "disk"), "There are 1,00" + df + " files on disk.");
assertEquals(f.render(0, "disk"), "There are 0 files on disk.");
assertEquals(f.render(-1, "disk"), "There are -1 files on disk.");
assertEquals(f.render(1, "disk"), "There is one file on disk.");
assertEquals(f.render(1, "disk", 1000, "bla bla"), "There is one file on disk.");
f = messageFormatInstance("Hay {0, plural, one{un fichero}other{{0} ficheros}} en {1}.", ES);
assertEquals(f.render(1000 + df, "disco"), "Hay 1.00" + df + " ficheros en disco.");
assertEquals(f.render(1, "disco"), "Hay un fichero en disco.");
}
@Test(threadPoolSize = 10, invocationCount = 10)
public void pluralRulesTest()
{
String pt1 = "Hi {0, plural, one{man}other{men}}!";
assertEquals(pluralize(pt1, 1), "Hi man!");
assertEquals(pluralize(pt1, 20), "Hi men!");
String pt2 = "Hi {1} {2} {0, plural, one{man}other{men}}!";
assertEquals(pluralize(pt2, 1, "a", "b"), "Hi a b man!");
assertEquals(pluralize(pt2, 20, "c", "d"), "Hi c d men!");
String pt3 = "{0, plural, one{el niño}other{los niños}}!";
assertEquals(pluralize(ES, pt3, 1), "el niño!");
assertEquals(pluralize(ES, pt3, 20), "los niños!");
String pt4 = "{0, plural, one{el niño}other{los niños}} en {1}!";
assertEquals(pluralize(ES, pt4, 1, "su casa"), "el niño en su casa!");
assertEquals(pluralize(ES, pt4, 20, "el parque"), "los niños en el parque!");
}
@Test
public void replaceSupplementaryTest()
{
assertEquals(
replaceSupplementary("The first three letters of the Gothic alphabet are: \uD800\uDF30 \uD800\uDF31 \uD800\uDF32 and not"),
"The first three letters of the Gothic alphabet are: GOTHIC LETTER AHSA GOTHIC LETTER BAIRKAN GOTHIC LETTER GIBA and not");
assertEquals(replaceSupplementary("A normal string"), "A normal string");
// Emoji face
assertEquals(replaceSupplementary(new StringBuilder().appendCodePoint(0x1F60A).toString()),
"SMILING FACE WITH SMILING EYES");
}
@Test(threadPoolSize = 10, invocationCount = 10)
public void smartDateFormatTest()
{
int day = rand.nextInt(20) + 1;
Date date = newTestDate(day, 11, 2015);
assertEquals(smartDateFormat(date, "MMMd"), day + " Dec");
assertEquals(smartDateFormat(date, "MMMd", ES), day + " dic.");
}
@Test(threadPoolSize = 10, invocationCount = 10)
public void spellNumberTest()
{
assertEquals(spellNumber(123), "one hundred twenty-three");
assertEquals(spellNumber(2840), "two thousand eight hundred forty");
assertEquals(spellNumber(1803), "one thousand eight hundred three");
assertEquals(spellNumber(1412605), "one million four hundred twelve thousand six hundred five");
assertEquals(spellNumber(2760300), "two million seven hundred sixty thousand three hundred");
assertEquals(spellNumber(999000), "nine hundred ninety-nine thousand");
assertEquals(spellNumber(23380000000L), "twenty-three billion three hundred eighty million");
assertEquals(spellNumber(23, ES), "veintitrés");
assertEquals(spellNumber(201256, ES), "doscientos un mil doscientos cincuenta y seis");
}
@Test
public void transliterateTest()
{
assertEquals(transliterate("김, 국삼"), "gim, gugsam");
assertEquals(transliterate("キャンパス"), "kyanpasu");
assertEquals(transliterate("Θεοδωράτου, Ελένη"), "Theodōrátou, Elénē");
assertNotEquals(transliterate("김, 국삼"), "michael, gugsam");
}
@BeforeClass
protected void setUp()
{
defaultLocale = Locale.getDefault();
Locale.setDefault(Locale.UK);
rand = new Random();
}
@AfterClass
protected void tearDown()
{
Locale.setDefault(defaultLocale);
}
private Date newTestDate(int day, int month, int year)
{
return newTestDate(day, month, year, 0, 0, 0);
}
private Date newTestDate(int day, int month, int year, int h, int m, int s)
{
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DATE, day);
cal.set(Calendar.MONTH, month);
cal.set(Calendar.YEAR, year);
cal.set(Calendar.HOUR_OF_DAY, h);
cal.set(Calendar.MINUTE, m);
cal.set(Calendar.SECOND, s);
return cal.getTime();
}
}