diff --git a/core/src/main/java/org/mobilitydata/gtfsvalidator/parsing/RowParser.java b/core/src/main/java/org/mobilitydata/gtfsvalidator/parsing/RowParser.java index d1303aebea..e29f7b53c5 100644 --- a/core/src/main/java/org/mobilitydata/gtfsvalidator/parsing/RowParser.java +++ b/core/src/main/java/org/mobilitydata/gtfsvalidator/parsing/RowParser.java @@ -40,6 +40,7 @@ import org.mobilitydata.gtfsvalidator.notice.TooManyRowsNotice; import org.mobilitydata.gtfsvalidator.notice.UnexpectedEnumValueNotice; import org.mobilitydata.gtfsvalidator.notice.ValidationNotice; +import org.mobilitydata.gtfsvalidator.table.GtfsColumnDescriptor; import org.mobilitydata.gtfsvalidator.table.GtfsEnum; import org.mobilitydata.gtfsvalidator.type.GtfsColor; import org.mobilitydata.gtfsvalidator.type.GtfsDate; @@ -125,16 +126,15 @@ public boolean checkRowLength() { } @Nullable - public String asString(int columnIndex, FieldLevelEnum level) { + public String asString(int columnIndex, GtfsColumnDescriptor columnDescriptor) { String s = row.asString(columnIndex); - if (level == FieldLevelEnum.REQUIRED && s == null) { + if (columnDescriptor.fieldLevel() == FieldLevelEnum.REQUIRED && s == null) { noticeContainer.addValidationNotice( - new MissingRequiredFieldNotice( - fileName, getRowNumber(), header.getColumnName(columnIndex))); - } else if (level == FieldLevelEnum.RECOMMENDED && s == null) { + new MissingRequiredFieldNotice(fileName, getRowNumber(), columnDescriptor.columnName())); + } else if (columnDescriptor.fieldLevel() == FieldLevelEnum.RECOMMENDED && s == null) { noticeContainer.addValidationNotice( new MissingRecommendedFieldNotice( - fileName, getRowNumber(), header.getColumnName(columnIndex))); + fileName, getRowNumber(), columnDescriptor.columnName())); } if (s != null) { s = @@ -147,23 +147,23 @@ public String asString(int columnIndex, FieldLevelEnum level) { } @Nullable - public String asText(int columnIndex, FieldLevelEnum level) { - return asString(columnIndex, level); + public String asText(int columnIndex, GtfsColumnDescriptor columnDescriptor) { + return asString(columnIndex, columnDescriptor); } @Nullable - public String asId(int columnIndex, FieldLevelEnum level) { - return asValidatedString(columnIndex, level, fieldValidator::validateId); + public String asId(int columnIndex, GtfsColumnDescriptor columnDescriptor) { + return asValidatedString(columnIndex, columnDescriptor, fieldValidator::validateId); } @Nullable - public String asUrl(int columnIndex, FieldLevelEnum level) { - return asValidatedString(columnIndex, level, fieldValidator::validateUrl); + public String asUrl(int columnIndex, GtfsColumnDescriptor columnDescriptor) { + return asValidatedString(columnIndex, columnDescriptor, fieldValidator::validateUrl); } @Nullable - public String asEmail(int columnIndex, FieldLevelEnum level) { - return asValidatedString(columnIndex, level, fieldValidator::validateEmail); + public String asEmail(int columnIndex, GtfsColumnDescriptor columnDescriptor) { + return asValidatedString(columnIndex, columnDescriptor, fieldValidator::validateEmail); } /** @@ -172,14 +172,14 @@ public String asEmail(int columnIndex, FieldLevelEnum level) { * unknown, only phone number starting by "+" are validated. * * @param columnIndex the column index - * @param level whether the value is required, recommended or optional according to GTFS + * @param columnDescriptor Gtfs Column Descriptor * @return the string value of the phone number to be validated if a valid number according to the * {@code CountryCode}, returns {@code null} otherwise. Note that if {@code CountryCode} is * unknown, only phone number starting by "+" are validated. */ @Nullable - public String asPhoneNumber(int columnIndex, FieldLevelEnum level) { - return asValidatedString(columnIndex, level, fieldValidator::validatePhoneNumber); + public String asPhoneNumber(int columnIndex, GtfsColumnDescriptor columnDescriptor) { + return asValidatedString(columnIndex, columnDescriptor, fieldValidator::validatePhoneNumber); } @Nullable @@ -190,8 +190,9 @@ public String asPhoneNumber(int columnIndex, FieldLevelEnum level) { * @param level whether the value is required, recommended or optional according to GTFS * @return If parsing was successful returns {@code Locale}, otherwise, {@code null} is returned. */ - public Locale asLanguageCode(int columnIndex, FieldLevelEnum level) { - return parseAsType(columnIndex, level, RowParser::parseLocale, InvalidLanguageCodeNotice::new); + public Locale asLanguageCode(int columnIndex, GtfsColumnDescriptor columnDescriptor) { + return parseAsType( + columnIndex, columnDescriptor, RowParser::parseLocale, InvalidLanguageCodeNotice::new); } /** @@ -209,28 +210,30 @@ private static Locale parseLocale(String languageTag) { } @Nullable - public ZoneId asTimezone(int columnIndex, FieldLevelEnum level) { - return parseAsType(columnIndex, level, ZoneId::of, InvalidTimezoneNotice::new); + public ZoneId asTimezone(int columnIndex, GtfsColumnDescriptor columnDescriptor) { + return parseAsType(columnIndex, columnDescriptor, ZoneId::of, InvalidTimezoneNotice::new); } @Nullable - public Currency asCurrencyCode(int columnIndex, FieldLevelEnum level) { - return parseAsType(columnIndex, level, Currency::getInstance, InvalidCurrencyNotice::new); + public Currency asCurrencyCode(int columnIndex, GtfsColumnDescriptor columnDescriptor) { + return parseAsType( + columnIndex, columnDescriptor, Currency::getInstance, InvalidCurrencyNotice::new); } @Nullable - public Double asFloat(int columnIndex, FieldLevelEnum level) { - return parseAsType(columnIndex, level, Double::parseDouble, InvalidFloatNotice::new); + public Double asFloat(int columnIndex, GtfsColumnDescriptor columnDescriptor) { + return parseAsType(columnIndex, columnDescriptor, Double::parseDouble, InvalidFloatNotice::new); } @Nullable - public Double asFloat(int columnIndex, FieldLevelEnum level, NumberBounds bounds) { - return checkBounds(asFloat(columnIndex, level), 0.0, columnIndex, "float", bounds); + public Double asFloat( + int columnIndex, GtfsColumnDescriptor columnDescriptor, NumberBounds bounds) { + return checkBounds(asFloat(columnIndex, columnDescriptor), 0.0, columnIndex, "float", bounds); } @Nullable - public Double asLatitude(int columnIndex, FieldLevelEnum level) { - Double value = asFloat(columnIndex, level); + public Double asLatitude(int columnIndex, GtfsColumnDescriptor columnDescriptor) { + Double value = asFloat(columnIndex, columnDescriptor); if (value != null && !(-90 <= value && value <= 90)) { noticeContainer.addValidationNotice( new NumberOutOfRangeNotice( @@ -245,8 +248,8 @@ public Double asLatitude(int columnIndex, FieldLevelEnum level) { } @Nullable - public Double asLongitude(int columnIndex, FieldLevelEnum level) { - Double value = asFloat(columnIndex, level); + public Double asLongitude(int columnIndex, GtfsColumnDescriptor columnDescriptor) { + Double value = asFloat(columnIndex, columnDescriptor); if (value != null && !(-180 <= value && value <= 180)) { noticeContainer.addValidationNotice( new NumberOutOfRangeNotice( @@ -261,24 +264,30 @@ public Double asLongitude(int columnIndex, FieldLevelEnum level) { } @Nullable - public Integer asInteger(int columnIndex, FieldLevelEnum level) { - return parseAsType(columnIndex, level, Integer::parseInt, InvalidIntegerNotice::new); + public Integer asInteger(int columnIndex, GtfsColumnDescriptor columnDescriptor) { + return parseAsType(columnIndex, columnDescriptor, Integer::parseInt, InvalidIntegerNotice::new); } @Nullable - public Integer asInteger(int columnIndex, FieldLevelEnum level, NumberBounds bounds) { - return checkBounds(asInteger(columnIndex, level), 0, columnIndex, "integer", bounds); + public Integer asInteger( + int columnIndex, GtfsColumnDescriptor columnDescriptor, NumberBounds bounds) { + return checkBounds(asInteger(columnIndex, columnDescriptor), 0, columnIndex, "integer", bounds); } @Nullable - public BigDecimal asDecimal(int columnIndex, FieldLevelEnum level) { - return parseAsType(columnIndex, level, BigDecimal::new, InvalidFloatNotice::new); + public BigDecimal asDecimal(int columnIndex, GtfsColumnDescriptor columnDescriptor) { + return parseAsType(columnIndex, columnDescriptor, BigDecimal::new, InvalidFloatNotice::new); } @Nullable - public BigDecimal asDecimal(int columnIndex, FieldLevelEnum level, NumberBounds bounds) { + public BigDecimal asDecimal( + int columnIndex, GtfsColumnDescriptor columnDescriptor, NumberBounds bounds) { return checkBounds( - asDecimal(columnIndex, level), new BigDecimal(0), columnIndex, "decimal", bounds); + asDecimal(columnIndex, columnDescriptor), + new BigDecimal(0), + columnIndex, + "decimal", + bounds); } /** @@ -337,14 +346,18 @@ private > T checkBounds( } @Nullable - public GtfsColor asColor(int columnIndex, FieldLevelEnum level) { - return parseAsType(columnIndex, level, GtfsColor::fromString, InvalidColorNotice::new); + public GtfsColor asColor(int columnIndex, GtfsColumnDescriptor columnDescriptor) { + return parseAsType( + columnIndex, columnDescriptor, GtfsColor::fromString, InvalidColorNotice::new); } @Nullable public Integer asEnum( - int columnIndex, FieldLevelEnum level, EnumCreator enumCreator, E unrecognized) { - Integer i = asInteger(columnIndex, level); + int columnIndex, + GtfsColumnDescriptor columnDescriptor, + EnumCreator enumCreator, + E unrecognized) { + Integer i = asInteger(columnIndex, columnDescriptor); if (i == null) { return null; } @@ -358,13 +371,13 @@ public Integer asEnum( } @Nullable - public GtfsTime asTime(int columnIndex, FieldLevelEnum level) { - return parseAsType(columnIndex, level, GtfsTime::fromString, InvalidTimeNotice::new); + public GtfsTime asTime(int columnIndex, GtfsColumnDescriptor columnDescriptor) { + return parseAsType(columnIndex, columnDescriptor, GtfsTime::fromString, InvalidTimeNotice::new); } @Nullable - public GtfsDate asDate(int columnIndex, FieldLevelEnum level) { - return parseAsType(columnIndex, level, GtfsDate::fromString, InvalidDateNotice::new); + public GtfsDate asDate(int columnIndex, GtfsColumnDescriptor columnDescriptor) { + return parseAsType(columnIndex, columnDescriptor, GtfsDate::fromString, InvalidDateNotice::new); } public enum NumberBounds { @@ -384,7 +397,7 @@ public interface EnumCreator { * parsing failed. * * @param columnIndex index of the column to parse - * @param level whether the value is required, recommended or optional according to GTFS + * @param columnDescriptor Gtfs Column Descriptor * @param parsingFunction function that converts string to an object to return * @param noticingFunction function to create a notice about parse errors * @param the type to return @@ -393,10 +406,10 @@ public interface EnumCreator { @Nullable private T parseAsType( int columnIndex, - FieldLevelEnum level, + GtfsColumnDescriptor columnDescriptor, Function parsingFunction, NoticingFunction noticingFunction) { - String s = asString(columnIndex, level); + String s = asString(columnIndex, columnDescriptor); if (s == null) { return null; } @@ -418,14 +431,16 @@ private T parseAsType( * error is emitted, the value is considered invalid. * * @param columnIndex index of the column to parse - * @param level whether the value is required, recommended or optional according to GTFS + * @param columnDescriptor GTFS column descriptor * @param validatingFunction the predicate to validate a given string * @return the cell value at the given column or null if the value is missing */ @Nullable private String asValidatedString( - int columnIndex, FieldLevelEnum level, FieldValidatingFunction validatingFunction) { - String s = asString(columnIndex, level); + int columnIndex, + GtfsColumnDescriptor columnDescriptor, + FieldValidatingFunction validatingFunction) { + String s = asString(columnIndex, columnDescriptor); if (s == null) { return null; } diff --git a/core/src/test/java/org/mobilitydata/gtfsvalidator/parsing/RowParserTest.java b/core/src/test/java/org/mobilitydata/gtfsvalidator/parsing/RowParserTest.java index db39032ae1..c3c0db2cf7 100644 --- a/core/src/test/java/org/mobilitydata/gtfsvalidator/parsing/RowParserTest.java +++ b/core/src/test/java/org/mobilitydata/gtfsvalidator/parsing/RowParserTest.java @@ -1,19 +1,15 @@ -/* - * Copyright 2020 Google LLC, MobilityData IO +/** + * Copyright 2020 Google LLC, MobilityData IO 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 * - * 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 * - * 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 + *

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.mobilitydata.gtfsvalidator.parsing; import static com.google.common.truth.Truth.assertThat; @@ -25,6 +21,7 @@ import java.time.LocalDate; import java.time.ZoneId; import java.util.Arrays; +import java.util.Optional; import java.util.function.Function; import org.junit.Test; import org.junit.runner.RunWith; @@ -32,6 +29,7 @@ import org.mobilitydata.gtfsvalidator.annotation.FieldLevelEnum; import org.mobilitydata.gtfsvalidator.input.CountryCode; import org.mobilitydata.gtfsvalidator.notice.*; +import org.mobilitydata.gtfsvalidator.table.GtfsColumnDescriptor; import org.mobilitydata.gtfsvalidator.type.GtfsColor; import org.mobilitydata.gtfsvalidator.type.GtfsDate; import org.mobilitydata.gtfsvalidator.type.GtfsTime; @@ -46,6 +44,39 @@ public class RowParserTest { private static GtfsFieldValidator FIELD_VALIDATOR = new DefaultFieldValidator(TEST_COUNTRY_CODE); + private static GtfsColumnDescriptor GTFS_COLUMN_DESCRIPTOR = + new GtfsColumnDescriptor() { + @Override + public String columnName() { + return "column name"; + } + + @Override + public boolean headerRequired() { + return false; + } + + @Override + public FieldLevelEnum fieldLevel() { + return FieldLevelEnum.REQUIRED; + } + + @Override + public Optional numberBounds() { + return Optional.empty(); + } + + @Override + public boolean isCached() { + return false; + } + + @Override + public boolean isMixedCase() { + return false; + } + }; + private static RowParser createParser(String cellValue) { NoticeContainer noticeContainer = new NoticeContainer(); RowParser parser = @@ -75,14 +106,14 @@ private static void assertInvalid( @Test public void asUrl_valid() { - assertValid("http://google.com", p -> p.asUrl(0, FieldLevelEnum.REQUIRED), "http://google.com"); + assertValid("http://google.com", p -> p.asUrl(0, GTFS_COLUMN_DESCRIPTOR), "http://google.com"); } @Test public void asUrl_invalid() { assertInvalid( "invalid", - p -> p.asUrl(0, FieldLevelEnum.REQUIRED), + p -> p.asUrl(0, GTFS_COLUMN_DESCRIPTOR), "invalid", new InvalidUrlNotice("stops.txt", 8, "column name", "invalid")); } @@ -91,7 +122,7 @@ public void asUrl_invalid() { public void asString_recommended_valid() { RowParser parser = createParser("ABCDE"); - assertThat(parser.asString(0, FieldLevelEnum.RECOMMENDED)).isEqualTo("ABCDE"); + assertThat(parser.asString(0, GTFS_COLUMN_DESCRIPTOR)).isEqualTo("ABCDE"); assertThat(parser.getNoticeContainer().getValidationNotices()).isEmpty(); } @@ -99,15 +130,23 @@ public void asString_recommended_valid() { public void asString_required_valid() { RowParser parser = createParser("ABCDE"); - assertThat(parser.asString(0, FieldLevelEnum.REQUIRED)).isEqualTo("ABCDE"); + assertThat(parser.asString(0, GTFS_COLUMN_DESCRIPTOR)).isEqualTo("ABCDE"); assertThat(parser.getNoticeContainer().getValidationNotices()).isEmpty(); } @Test public void asString_recommended_missing() { RowParser parser = createParser(null); - - assertThat(parser.asString(0, FieldLevelEnum.RECOMMENDED)).isEqualTo(null); + GtfsColumnDescriptor tempColumnDescriptor = + GtfsColumnDescriptor.builder() + .setColumnName("column name") + .setHeaderRequired(false) + .setFieldLevel(FieldLevelEnum.RECOMMENDED) + .setIsMixedCase(false) + .setIsCached(false) + .build(); + + assertThat(parser.asString(0, tempColumnDescriptor)).isEqualTo(null); MissingRecommendedFieldNotice notice = new MissingRecommendedFieldNotice(TEST_FILENAME, 8, "column name"); assertThat(parser.getNoticeContainer().getValidationNotices()).containsExactly(notice); @@ -118,7 +157,7 @@ public void asString_recommended_missing() { public void asString_required_missing() { RowParser parser = createParser(null); - assertThat(parser.asString(0, FieldLevelEnum.REQUIRED)).isEqualTo(null); + assertThat(parser.asString(0, GTFS_COLUMN_DESCRIPTOR)).isEqualTo(null); MissingRequiredFieldNotice notice = new MissingRequiredFieldNotice(TEST_FILENAME, 8, "column name"); assertThat(parser.getNoticeContainer().getValidationNotices()).containsExactly(notice); @@ -129,185 +168,183 @@ public void asString_required_missing() { public void asInteger() { RowParser parser = createParser("12345"); - assertThat(parser.asInteger(0, FieldLevelEnum.REQUIRED)).isEqualTo(12345); + assertThat(parser.asInteger(0, GTFS_COLUMN_DESCRIPTOR)).isEqualTo(12345); assertThat(parser.getNoticeContainer().getValidationNotices()).isEmpty(); - assertThat(parser.asInteger(0, FieldLevelEnum.REQUIRED, RowParser.NumberBounds.NON_NEGATIVE)) + assertThat(parser.asInteger(0, GTFS_COLUMN_DESCRIPTOR, RowParser.NumberBounds.NON_NEGATIVE)) .isEqualTo(12345); assertThat(parser.getNoticeContainer().getValidationNotices()).isEmpty(); - assertThat(parser.asInteger(0, FieldLevelEnum.REQUIRED, RowParser.NumberBounds.NON_ZERO)) + assertThat(parser.asInteger(0, GTFS_COLUMN_DESCRIPTOR, RowParser.NumberBounds.NON_ZERO)) .isEqualTo(12345); assertThat(parser.getNoticeContainer().getValidationNotices()).isEmpty(); - assertThat(parser.asInteger(0, FieldLevelEnum.REQUIRED, RowParser.NumberBounds.POSITIVE)) + assertThat(parser.asInteger(0, GTFS_COLUMN_DESCRIPTOR, RowParser.NumberBounds.POSITIVE)) .isEqualTo(12345); assertThat(parser.getNoticeContainer().getValidationNotices()).isEmpty(); - assertThat(createParser("abc").asInteger(0, FieldLevelEnum.REQUIRED)).isNull(); + assertThat(createParser("abc").asInteger(0, GTFS_COLUMN_DESCRIPTOR)).isNull(); } @Test public void asDecimal() { RowParser parser = createParser("123.45"); - assertThat(parser.asDecimal(0, FieldLevelEnum.REQUIRED)).isEqualTo(new BigDecimal("123.45")); + assertThat(parser.asDecimal(0, GTFS_COLUMN_DESCRIPTOR)).isEqualTo(new BigDecimal("123.45")); assertThat(parser.getNoticeContainer().getValidationNotices()).isEmpty(); - assertThat(parser.asDecimal(0, FieldLevelEnum.REQUIRED, RowParser.NumberBounds.NON_NEGATIVE)) + assertThat(parser.asDecimal(0, GTFS_COLUMN_DESCRIPTOR, RowParser.NumberBounds.NON_NEGATIVE)) .isEqualTo(new BigDecimal("123.45")); assertThat(parser.getNoticeContainer().getValidationNotices()).isEmpty(); - assertThat(parser.asDecimal(0, FieldLevelEnum.REQUIRED, RowParser.NumberBounds.NON_ZERO)) + assertThat(parser.asDecimal(0, GTFS_COLUMN_DESCRIPTOR, RowParser.NumberBounds.NON_ZERO)) .isEqualTo(new BigDecimal("123.45")); assertThat(parser.getNoticeContainer().getValidationNotices()).isEmpty(); - assertThat(parser.asDecimal(0, FieldLevelEnum.REQUIRED, RowParser.NumberBounds.POSITIVE)) + assertThat(parser.asDecimal(0, GTFS_COLUMN_DESCRIPTOR, RowParser.NumberBounds.POSITIVE)) .isEqualTo(new BigDecimal("123.45")); assertThat(parser.getNoticeContainer().getValidationNotices()).isEmpty(); - assertThat(createParser("abc").asDecimal(0, FieldLevelEnum.REQUIRED)).isNull(); + assertThat(createParser("abc").asDecimal(0, GTFS_COLUMN_DESCRIPTOR)).isNull(); } @Test public void asFloat() { RowParser parser = createParser("123.45"); - assertThat(parser.asFloat(0, FieldLevelEnum.REQUIRED)).isEqualTo(123.45); + assertThat(parser.asFloat(0, GTFS_COLUMN_DESCRIPTOR)).isEqualTo(123.45); assertThat(parser.getNoticeContainer().getValidationNotices()).isEmpty(); - assertThat(parser.asFloat(0, FieldLevelEnum.REQUIRED, RowParser.NumberBounds.NON_NEGATIVE)) + assertThat(parser.asFloat(0, GTFS_COLUMN_DESCRIPTOR, RowParser.NumberBounds.NON_NEGATIVE)) .isEqualTo(123.45); assertThat(parser.getNoticeContainer().getValidationNotices()).isEmpty(); - assertThat(parser.asFloat(0, FieldLevelEnum.REQUIRED, RowParser.NumberBounds.NON_ZERO)) + assertThat(parser.asFloat(0, GTFS_COLUMN_DESCRIPTOR, RowParser.NumberBounds.NON_ZERO)) .isEqualTo(123.45); assertThat(parser.getNoticeContainer().getValidationNotices()).isEmpty(); - assertThat(parser.asFloat(0, FieldLevelEnum.REQUIRED, RowParser.NumberBounds.POSITIVE)) + assertThat(parser.asFloat(0, GTFS_COLUMN_DESCRIPTOR, RowParser.NumberBounds.POSITIVE)) .isEqualTo(123.45); assertThat(parser.getNoticeContainer().getValidationNotices()).isEmpty(); - assertThat(createParser("abc").asFloat(0, FieldLevelEnum.REQUIRED)).isNull(); + assertThat(createParser("abc").asFloat(0, GTFS_COLUMN_DESCRIPTOR)).isNull(); } @Test public void asEmail_valid() { assertValid( - "no-reply@google.com", p -> p.asEmail(0, FieldLevelEnum.REQUIRED), "no-reply@google.com"); + "no-reply@google.com", p -> p.asEmail(0, GTFS_COLUMN_DESCRIPTOR), "no-reply@google.com"); } @Test public void asEmail_invalid() { assertInvalid( "invalid", - p -> p.asEmail(0, FieldLevelEnum.REQUIRED), + p -> p.asEmail(0, GTFS_COLUMN_DESCRIPTOR), "invalid", new InvalidEmailNotice("stops.txt", 8, "column name", "invalid")); } @Test public void asColor() { - assertThat(createParser("FFFFFF").asColor(0, FieldLevelEnum.REQUIRED)) + assertThat(createParser("FFFFFF").asColor(0, GTFS_COLUMN_DESCRIPTOR)) .isEqualTo(GtfsColor.fromInt(0xffffff)); - assertThat(createParser("abcdef").asColor(0, FieldLevelEnum.REQUIRED)) + assertThat(createParser("abcdef").asColor(0, GTFS_COLUMN_DESCRIPTOR)) .isEqualTo(GtfsColor.fromInt(0xabcdef)); - assertThat(createParser("123456").asColor(0, FieldLevelEnum.REQUIRED)) + assertThat(createParser("123456").asColor(0, GTFS_COLUMN_DESCRIPTOR)) .isEqualTo(GtfsColor.fromInt(0x123456)); - assertThat(createParser("invalid").asColor(0, FieldLevelEnum.REQUIRED)).isNull(); + assertThat(createParser("invalid").asColor(0, GTFS_COLUMN_DESCRIPTOR)).isNull(); } @Test public void asCurrencyCode() { - assertThat(createParser("USD").asCurrencyCode(0, FieldLevelEnum.REQUIRED).getCurrencyCode()) + assertThat(createParser("USD").asCurrencyCode(0, GTFS_COLUMN_DESCRIPTOR).getCurrencyCode()) .isEqualTo("USD"); - assertThat(createParser("AUD").asCurrencyCode(0, FieldLevelEnum.REQUIRED).getCurrencyCode()) + assertThat(createParser("AUD").asCurrencyCode(0, GTFS_COLUMN_DESCRIPTOR).getCurrencyCode()) .isEqualTo("AUD"); - assertThat(createParser("CAD").asCurrencyCode(0, FieldLevelEnum.REQUIRED).getCurrencyCode()) + assertThat(createParser("CAD").asCurrencyCode(0, GTFS_COLUMN_DESCRIPTOR).getCurrencyCode()) .isEqualTo("CAD"); - assertThat(createParser("invalid").asCurrencyCode(0, FieldLevelEnum.REQUIRED)).isNull(); + assertThat(createParser("invalid").asCurrencyCode(0, GTFS_COLUMN_DESCRIPTOR)).isNull(); } @Test public void asLanguageCode_invalid() { // Underscore is invalid delimiter. - assertThat(createParser("en_EN").asLanguageCode(0, FieldLevelEnum.REQUIRED)).isNull(); + assertThat(createParser("en_EN").asLanguageCode(0, GTFS_COLUMN_DESCRIPTOR)).isNull(); } @Test public void asLanguageCode() { // Russian of Russia. - assertThat(createParser("ru-RU").asLanguageCode(0, FieldLevelEnum.REQUIRED).toLanguageTag()) + assertThat(createParser("ru-RU").asLanguageCode(0, GTFS_COLUMN_DESCRIPTOR).toLanguageTag()) .isEqualTo("ru-RU"); // Zürich German. assertThat( - createParser("gsw-u-sd-chzh") - .asLanguageCode(0, FieldLevelEnum.REQUIRED) - .toLanguageTag()) + createParser("gsw-u-sd-chzh").asLanguageCode(0, GTFS_COLUMN_DESCRIPTOR).toLanguageTag()) .isEqualTo("gsw-u-sd-chzh"); // Latin American Spanish. - assertThat(createParser("es-419").asLanguageCode(0, FieldLevelEnum.REQUIRED).toLanguageTag()) + assertThat(createParser("es-419").asLanguageCode(0, GTFS_COLUMN_DESCRIPTOR).toLanguageTag()) .isEqualTo("es-419"); } @Test public void asPhoneNumber_valid() { assertValid( - "(650) 253-0000", p -> p.asPhoneNumber(0, FieldLevelEnum.REQUIRED), "(650) 253-0000"); + "(650) 253-0000", p -> p.asPhoneNumber(0, GTFS_COLUMN_DESCRIPTOR), "(650) 253-0000"); } @Test public void asPhoneNumber_invalid() { assertInvalid( "invalid", - p -> p.asPhoneNumber(0, FieldLevelEnum.REQUIRED), + p -> p.asPhoneNumber(0, GTFS_COLUMN_DESCRIPTOR), "invalid", new InvalidPhoneNumberNotice("stops.txt", 8, "column name", "invalid")); } @Test public void asDate() { - assertThat(createParser("20200901").asDate(0, FieldLevelEnum.REQUIRED)) + assertThat(createParser("20200901").asDate(0, GTFS_COLUMN_DESCRIPTOR)) .isEqualTo(GtfsDate.fromLocalDate(LocalDate.of(2020, 9, 1))); - assertThat(createParser("invalid").asDate(0, FieldLevelEnum.REQUIRED)).isNull(); + assertThat(createParser("invalid").asDate(0, GTFS_COLUMN_DESCRIPTOR)).isNull(); } @Test public void asTime() { - assertThat(createParser("12:20:30").asTime(0, FieldLevelEnum.REQUIRED)) + assertThat(createParser("12:20:30").asTime(0, GTFS_COLUMN_DESCRIPTOR)) .isEqualTo(GtfsTime.fromHourMinuteSecond(12, 20, 30)); - assertThat(createParser("24:20:30").asTime(0, FieldLevelEnum.REQUIRED)) + assertThat(createParser("24:20:30").asTime(0, GTFS_COLUMN_DESCRIPTOR)) .isEqualTo(GtfsTime.fromHourMinuteSecond(24, 20, 30)); - assertThat(createParser("invalid").asTime(0, FieldLevelEnum.REQUIRED)).isNull(); + assertThat(createParser("invalid").asTime(0, GTFS_COLUMN_DESCRIPTOR)).isNull(); } @Test public void asTimezone_valid() { - assertThat(createParser("America/Toronto").asTimezone(0, FieldLevelEnum.REQUIRED)) + assertThat(createParser("America/Toronto").asTimezone(0, GTFS_COLUMN_DESCRIPTOR)) .isEqualTo(ZoneId.of("America/Toronto")); } @Test public void asTimezone_invalid() { // ZoneId.of("invalid") throws ZoneRulesException. - assertThat(createParser("invalid").asTimezone(0, FieldLevelEnum.REQUIRED)).isNull(); + assertThat(createParser("invalid").asTimezone(0, GTFS_COLUMN_DESCRIPTOR)).isNull(); // ZoneId.of("Latinoamerica/ Argentina") throws DateTimeException. - assertThat(createParser("Latinoamerica/ Argentina").asTimezone(0, FieldLevelEnum.REQUIRED)) + assertThat(createParser("Latinoamerica/ Argentina").asTimezone(0, GTFS_COLUMN_DESCRIPTOR)) .isNull(); } @Test public void asId() { - assertThat(createParser("32tgklu34y3k").asId(0, FieldLevelEnum.REQUIRED)) + assertThat(createParser("32tgklu34y3k").asId(0, GTFS_COLUMN_DESCRIPTOR)) .isEqualTo("32tgklu34y3k"); RowParser parser = createParser("קום"); // .קום :the .COM equivalent in Hebrew - parser.asId(0, FieldLevelEnum.REQUIRED); + parser.asId(0, GTFS_COLUMN_DESCRIPTOR); assertThat(parser.getNoticeContainer().getValidationNotices()) .containsExactly( new NonAsciiOrNonPrintableCharNotice(TEST_FILENAME, 8, "column name", "קום")); @@ -317,20 +354,20 @@ public void asId() { @Test public void asLatitude_valid() { - assertValid("32.5", p -> p.asLatitude(0, FieldLevelEnum.REQUIRED), 32.5); + assertValid("32.5", p -> p.asLatitude(0, GTFS_COLUMN_DESCRIPTOR), 32.5); } @Test public void asLatitude_outOfRange() { assertInvalid( "-91", - p -> p.asLatitude(0, FieldLevelEnum.REQUIRED), + p -> p.asLatitude(0, GTFS_COLUMN_DESCRIPTOR), -91.0, new NumberOutOfRangeNotice( "stops.txt", 8, "column name", "latitude within [-90, 90]", -91.0)); assertInvalid( "91", - p -> p.asLatitude(0, FieldLevelEnum.REQUIRED), + p -> p.asLatitude(0, GTFS_COLUMN_DESCRIPTOR), 91.0, new NumberOutOfRangeNotice( "stops.txt", 8, "column name", "latitude within [-90, 90]", 91.0)); @@ -340,29 +377,29 @@ public void asLatitude_outOfRange() { public void asLatitude_nonParsable() { assertInvalid( "invalid", - p -> p.asLatitude(0, FieldLevelEnum.REQUIRED), + p -> p.asLatitude(0, GTFS_COLUMN_DESCRIPTOR), null, new InvalidFloatNotice("stops.txt", 8, "column name", "invalid")); } @Test public void asLongitude_valid() { - assertValid("-32.5", p -> p.asLongitude(0, FieldLevelEnum.REQUIRED), -32.5); - assertValid("-91", p -> p.asLongitude(0, FieldLevelEnum.REQUIRED), -91); - assertValid("91", p -> p.asLongitude(0, FieldLevelEnum.REQUIRED), 91); + assertValid("-32.5", p -> p.asLongitude(0, GTFS_COLUMN_DESCRIPTOR), -32.5); + assertValid("-91", p -> p.asLongitude(0, GTFS_COLUMN_DESCRIPTOR), -91); + assertValid("91", p -> p.asLongitude(0, GTFS_COLUMN_DESCRIPTOR), 91); } @Test public void asLongitude_outOfRange() { assertInvalid( "-181", - p -> p.asLongitude(0, FieldLevelEnum.REQUIRED), + p -> p.asLongitude(0, GTFS_COLUMN_DESCRIPTOR), -181.0, new NumberOutOfRangeNotice( "stops.txt", 8, "column name", "longitude within [-180, 180]", -181.0)); assertInvalid( "181", - p -> p.asLongitude(0, FieldLevelEnum.REQUIRED), + p -> p.asLongitude(0, GTFS_COLUMN_DESCRIPTOR), 181.0, new NumberOutOfRangeNotice( "stops.txt", 8, "column name", "longitude within [-180, 180]", 181.0)); @@ -372,7 +409,7 @@ public void asLongitude_outOfRange() { public void asLongitude_nonParsable() { assertInvalid( "invalid", - p -> p.asLongitude(0, FieldLevelEnum.REQUIRED), + p -> p.asLongitude(0, GTFS_COLUMN_DESCRIPTOR), null, new InvalidFloatNotice("stops.txt", 8, "column name", "invalid")); } @@ -381,7 +418,7 @@ public void asLongitude_nonParsable() { public void whitespaceInValue() { // Protected whitespaces are stripped. RowParser parser = createParser(" 1\t"); - assertThat(parser.asInteger(0, FieldLevelEnum.REQUIRED)).isEqualTo(1); + assertThat(parser.asInteger(0, GTFS_COLUMN_DESCRIPTOR)).isEqualTo(1); LeadingOrTrailingWhitespacesNotice notice = new LeadingOrTrailingWhitespacesNotice(TEST_FILENAME, 8, "column name", " 1\t"); assertThat(parser.getNoticeContainer().hasValidationErrors()).isFalse(); @@ -391,7 +428,7 @@ public void whitespaceInValue() { @Test public void newLineInValue() { RowParser parser = createParser("a\nb"); - assertThat(parser.asText(0, FieldLevelEnum.REQUIRED)).isEqualTo("a\nb"); + assertThat(parser.asText(0, GTFS_COLUMN_DESCRIPTOR)).isEqualTo("a\nb"); assertThat(parser.getNoticeContainer().hasValidationErrors()).isTrue(); assertThat(parser.getNoticeContainer().getValidationNotices()) .containsExactly(new NewLineInValueNotice(TEST_FILENAME, 8, "column name", "a\nb")); @@ -400,7 +437,7 @@ public void newLineInValue() { @Test public void carriageReturnInValue() { RowParser parser = createParser("a\rb"); - assertThat(parser.asText(0, FieldLevelEnum.REQUIRED)).isEqualTo("a\rb"); + assertThat(parser.asText(0, GTFS_COLUMN_DESCRIPTOR)).isEqualTo("a\rb"); assertThat(parser.getNoticeContainer().hasValidationErrors()).isTrue(); assertThat(parser.getNoticeContainer().getValidationNotices()) .containsExactly(new NewLineInValueNotice(TEST_FILENAME, 8, "column name", "a\rb")); diff --git a/core/src/test/java/org/mobilitydata/gtfsvalidator/testgtfs/GtfsTestTableDescriptor.java b/core/src/test/java/org/mobilitydata/gtfsvalidator/testgtfs/GtfsTestTableDescriptor.java index 68847acdcb..eb42741abc 100644 --- a/core/src/test/java/org/mobilitydata/gtfsvalidator/testgtfs/GtfsTestTableDescriptor.java +++ b/core/src/test/java/org/mobilitydata/gtfsvalidator/testgtfs/GtfsTestTableDescriptor.java @@ -70,8 +70,7 @@ public void load( FieldCache fieldCache, GtfsTestEntity.Builder builder) { builder.setId( - addToCacheIfPresent( - rowParser.asId(columnIndex, columnDescriptor.fieldLevel()), fieldCache)); + addToCacheIfPresent(rowParser.asId(columnIndex, columnDescriptor), fieldCache)); } }); builder.put( @@ -85,8 +84,7 @@ public void load( FieldCache fieldCache, GtfsTestEntity.Builder builder) { builder.setCode( - addToCacheIfPresent( - rowParser.asText(columnIndex, columnDescriptor.fieldLevel()), fieldCache)); + addToCacheIfPresent(rowParser.asText(columnIndex, columnDescriptor), fieldCache)); } }); return builder.build(); diff --git a/processor/src/main/java/org/mobilitydata/gtfsvalidator/processor/TableDescriptorGenerator.java b/processor/src/main/java/org/mobilitydata/gtfsvalidator/processor/TableDescriptorGenerator.java index 8e36a7b02b..825ff03e2c 100644 --- a/processor/src/main/java/org/mobilitydata/gtfsvalidator/processor/TableDescriptorGenerator.java +++ b/processor/src/main/java/org/mobilitydata/gtfsvalidator/processor/TableDescriptorGenerator.java @@ -252,12 +252,12 @@ private MethodSpec generateGetFieldLoadersMethod() { CodeBlock fieldValue = field.type() == FieldTypeEnum.ENUM ? CodeBlock.of( - "rowParser.asEnum(columnIndex, columnDescriptor.fieldLevel(), $T::forNumber," + "rowParser.asEnum(columnIndex, columnDescriptor, $T::forNumber," + " $T.UNRECOGNIZED)", ClassName.get(field.javaType()), ClassName.get(field.javaType())) : CodeBlock.of( - "rowParser.$L(columnIndex, columnDescriptor.fieldLevel()$L)", + "rowParser.$L(columnIndex, columnDescriptor$L)", gtfsTypeToParserMethod(field.type()), field.numberBounds().isPresent() ? ", RowParser.NumberBounds." + field.numberBounds().get()