blob: ad3450268c5532f13339239e765e5038f37fc701 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.logging.log4j.core.time.internal.format;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import org.apache.logging.log4j.core.time.internal.format.DateParser;
import org.apache.logging.log4j.core.time.internal.format.FastDateParser;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
/**
* Compare FastDateParser with SimpleDateFormat
*
* Copied from Apache Commons Lang 3 on 2016-11-16.
*/
@RunWith(Parameterized.class)
public class FastDateParserSDFTest {
@Parameters(name= "{index}: {0} {1} {2}")
public static Collection<Object[]> data() {
return Arrays.asList(new Object [][]{
// General Time zone tests
{"z yyyy", "GMT 2010", Locale.UK, true}, // no offset specified, but this is allowed as a TimeZone name
{"z yyyy", "GMT-123 2010", Locale.UK, false},
{"z yyyy", "GMT-1234 2010", Locale.UK, false},
{"z yyyy", "GMT-12:34 2010", Locale.UK, true},
{"z yyyy", "GMT-1:23 2010", Locale.UK, true},
// RFC 822 tests
{"z yyyy", "-1234 2010", Locale.UK, true},
{"z yyyy", "-12:34 2010", Locale.UK, false},
{"z yyyy", "-123 2010", Locale.UK, false},
// year tests
{ "MM/dd/yyyy", "01/11/12", Locale.UK, true},
{ "MM/dd/yy", "01/11/12", Locale.UK, true},
// LANG-1089
{ "HH", "00", Locale.UK, true}, // Hour in day (0-23)
{ "KK", "00", Locale.UK, true}, // Hour in am/pm (0-11)
{ "hh", "00", Locale.UK, true}, // Hour in am/pm (1-12), i.e. midday/midnight is 12, not 0
{ "kk", "00", Locale.UK, true}, // Hour in day (1-24), i.e. midnight is 24, not 0
{ "HH", "01", Locale.UK, true}, // Hour in day (0-23)
{ "KK", "01", Locale.UK, true}, // Hour in am/pm (0-11)
{ "hh", "01", Locale.UK, true}, // Hour in am/pm (1-12), i.e. midday/midnight is 12, not 0
{ "kk", "01", Locale.UK, true}, // Hour in day (1-24), i.e. midnight is 24, not 0
{ "HH", "11", Locale.UK, true}, // Hour in day (0-23)
{ "KK", "11", Locale.UK, true}, // Hour in am/pm (0-11)
{ "hh", "11", Locale.UK, true}, // Hour in am/pm (1-12), i.e. midday/midnight is 12, not 0
{ "kk", "11", Locale.UK, true}, // Hour in day (1-24), i.e. midnight is 24, not 0
{ "HH", "12", Locale.UK, true}, // Hour in day (0-23)
{ "KK", "12", Locale.UK, true}, // Hour in am/pm (0-11)
{ "hh", "12", Locale.UK, true}, // Hour in am/pm (1-12), i.e. midday/midnight is 12, not 0
{ "kk", "12", Locale.UK, true}, // Hour in day (1-24), i.e. midnight is 24, not 0
{ "HH", "13", Locale.UK, true}, // Hour in day (0-23)
{ "KK", "13", Locale.UK, true}, // Hour in am/pm (0-11)
{ "hh", "13", Locale.UK, true}, // Hour in am/pm (1-12), i.e. midday/midnight is 12, not 0
{ "kk", "13", Locale.UK, true}, // Hour in day (1-24), i.e. midnight is 24, not 0
{ "HH", "23", Locale.UK, true}, // Hour in day (0-23)
{ "KK", "23", Locale.UK, true}, // Hour in am/pm (0-11)
{ "hh", "23", Locale.UK, true}, // Hour in am/pm (1-12), i.e. midday/midnight is 12, not 0
{ "kk", "23", Locale.UK, true}, // Hour in day (1-24), i.e. midnight is 24, not 0
{ "HH", "24", Locale.UK, true}, // Hour in day (0-23)
{ "KK", "24", Locale.UK, true}, // Hour in am/pm (0-11)
{ "hh", "24", Locale.UK, true}, // Hour in am/pm (1-12), i.e. midday/midnight is 12, not 0
{ "kk", "24", Locale.UK, true}, // Hour in day (1-24), i.e. midnight is 24, not 0
{ "HH", "25", Locale.UK, true}, // Hour in day (0-23)
{ "KK", "25", Locale.UK, true}, // Hour in am/pm (0-11)
{ "hh", "25", Locale.UK, true}, // Hour in am/pm (1-12), i.e. midday/midnight is 12, not 0
{ "kk", "25", Locale.UK, true}, // Hour in day (1-24), i.e. midnight is 24, not 0
{ "HH", "48", Locale.UK, true}, // Hour in day (0-23)
{ "KK", "48", Locale.UK, true}, // Hour in am/pm (0-11)
{ "hh", "48", Locale.UK, true}, // Hour in am/pm (1-12), i.e. midday/midnight is 12, not 0
{ "kk", "48", Locale.UK, true}, // Hour in day (1-24), i.e. midnight is 24, not 0
});
}
private final String format;
private final String input;
private final Locale locale;
private final boolean valid;
private final TimeZone timeZone = TimeZone.getDefault();
public FastDateParserSDFTest(final String format, final String input, final Locale locale, final boolean valid) {
this.format = format;
this.input = input;
this.locale = locale;
this.valid = valid;
}
@Test
public void testOriginal() throws Exception {
checkParse(input);
}
@Test
public void testOriginalPP() throws Exception {
checkParsePosition(input);
}
@Test
public void testUpperCase() throws Exception {
checkParse(input.toUpperCase(locale));
}
@Test
public void testUpperCasePP() throws Exception {
checkParsePosition(input.toUpperCase(locale));
}
@Test
public void testLowerCase() throws Exception {
checkParse(input.toLowerCase(locale));
}
@Test
public void testLowerCasePP() throws Exception {
checkParsePosition(input.toLowerCase(locale));
}
private void checkParse(final String formattedDate) {
final SimpleDateFormat sdf = new SimpleDateFormat(format, locale);
sdf.setTimeZone(timeZone);
final DateParser fdf = new FastDateParser(format, timeZone, locale);
Date expectedTime=null;
Class<?> sdfE = null;
try {
expectedTime = sdf.parse(formattedDate);
if (!valid) {
// Error in test data
throw new RuntimeException("Test data error: expected SDF parse to fail, but got " + expectedTime);
}
} catch (final ParseException e) {
if (valid) {
// Error in test data
throw new RuntimeException("Test data error: expected SDF parse to succeed, but got " + e);
}
sdfE = e.getClass();
}
Date actualTime = null;
Class<?> fdfE = null;
try {
actualTime = fdf.parse(formattedDate);
if (!valid) {
// failure in test
fail("Expected FDP parse to fail, but got " + actualTime);
}
} catch (final ParseException e) {
if (valid) {
// failure in test
fail("Expected FDP parse to succeed, but got " + e);
}
fdfE = e.getClass();
}
if (valid) {
assertEquals(locale.toString()+" "+formattedDate +"\n",expectedTime, actualTime);
} else {
assertEquals(locale.toString()+" "+formattedDate + " expected same Exception ", sdfE, fdfE);
}
}
private void checkParsePosition(final String formattedDate) {
final SimpleDateFormat sdf = new SimpleDateFormat(format, locale);
sdf.setTimeZone(timeZone);
final DateParser fdf = new FastDateParser(format, timeZone, locale);
final ParsePosition sdfP = new ParsePosition(0);
final Date expectedTime = sdf.parse(formattedDate, sdfP);
final int sdferrorIndex = sdfP.getErrorIndex();
if (valid) {
assertEquals("Expected SDF error index -1 ", -1, sdferrorIndex);
final int endIndex = sdfP.getIndex();
final int length = formattedDate.length();
if (endIndex != length) {
// Error in test data
throw new RuntimeException("Test data error: expected SDF parse to consume entire string; endindex " + endIndex + " != " + length);
}
} else {
final int errorIndex = sdfP.getErrorIndex();
if (errorIndex == -1) {
throw new RuntimeException("Test data error: expected SDF parse to fail, but got " + expectedTime);
}
}
final ParsePosition fdfP = new ParsePosition(0);
final Date actualTime = fdf.parse(formattedDate, fdfP);
final int fdferrorIndex = fdfP.getErrorIndex();
if (valid) {
assertEquals("Expected FDF error index -1 ", -1, fdferrorIndex);
final int endIndex = fdfP.getIndex();
final int length = formattedDate.length();
assertEquals("Expected FDF to parse full string " + fdfP, length, endIndex);
assertEquals(locale.toString()+" "+formattedDate +"\n", expectedTime, actualTime);
} else {
assertNotEquals("Test data error: expected FDF parse to fail, but got " + actualTime, -1, fdferrorIndex);
assertTrue("FDF error index ("+ fdferrorIndex + ") should approxiamate SDF index (" + sdferrorIndex + ")",
sdferrorIndex - fdferrorIndex <= 4);
}
}
}