Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
0b26bfe
chore(core): add unit tests to AnyTableLoader
davidgamez Apr 6, 2023
9d99240
chore(core): code cleanup
davidgamez Apr 6, 2023
22eaa4d
chore(core): code formatting
davidgamez Apr 6, 2023
2fa57b0
chore(core): fix missing required unit test
davidgamez Apr 6, 2023
a13d544
chore: replace junit assertions with google truth library
davidgamez Apr 10, 2023
2f52dd4
chore: refactor TestUtils assertion method
davidgamez Apr 10, 2023
f85742f
chore: replace string methods in favor of toInputStream util
davidgamez Apr 10, 2023
49c132e
removing input stream helper method
davidgamez Apr 10, 2023
1c6e0f1
remove autovalue builder reference
davidgamez Apr 10, 2023
6714d8b
chore: enhance list instantiations with immutable list
davidgamez Apr 10, 2023
2c0c751
refactor test removing the times called verification in favor of equa…
davidgamez Apr 10, 2023
77a4b50
rename testgtfs classes
davidgamez Apr 11, 2023
df25717
chore: remove times assertion from AnyTableLoaderTest.parsableTableRo…
davidgamez Apr 11, 2023
b82e67f
chore: code cleanup
davidgamez Apr 11, 2023
84cb79b
chore: removing local toInputStream in favor of TestUtils method
davidgamez Apr 13, 2023
2208d06
remove commented line
davidgamez Apr 13, 2023
8c63578
Add MockitoRule and combine assertions
davidgamez Apr 17, 2023
bda4860
formatting code
davidgamez Apr 17, 2023
dec85a6
Update AnyTableLoaderTest.java
davidgamez Apr 18, 2023
cbb3248
fix gradle build file
davidgamez Apr 18, 2023
05b5690
Merge branch 'master' into chore/table-loader-unit-tests
davidgamez Apr 18, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ dependencies {
testImplementation group: 'junit', name: 'junit', version: '4.13'
testImplementation "com.google.truth:truth:1.0.1"
testImplementation 'com.google.truth.extensions:truth-java8-extension:1.0.1'
testImplementation 'org.mockito:mockito-core:4.5.1'
}

jar {
Expand Down
27 changes: 27 additions & 0 deletions core/src/test/java/org/mobilitydata/gtfsvalidator/TestUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.mobilitydata.gtfsvalidator;

import static java.util.stream.Collectors.toList;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import org.mobilitydata.gtfsvalidator.notice.NoticeContainer;
import org.mobilitydata.gtfsvalidator.notice.ValidationNotice;

public class TestUtils {

protected TestUtils() {
// Hiding default constructor to avoid instantiation
}

// In TestUtils...
public static List<Class<? extends ValidationNotice>> validationNoticeTypes(
NoticeContainer notices) {
return notices.getValidationNotices().stream().map(obj -> obj.getClass()).collect(toList());
}

public static InputStream toInputStream(String s) {
return new ByteArrayInputStream(s.getBytes(StandardCharsets.UTF_8));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package org.mobilitydata.gtfsvalidator.parsing;

import static com.google.common.truth.Truth.assertThat;
import static org.mobilitydata.gtfsvalidator.TestUtils.toInputStream;

import com.google.common.primitives.Bytes;
import java.io.ByteArrayInputStream;
Expand All @@ -32,10 +33,6 @@
@RunWith(JUnit4.class)
public class CsvFileTest {

private static InputStream toInputStream(String s) {
return new ByteArrayInputStream(s.getBytes(StandardCharsets.UTF_8));
}

@Test
public void emptyFile() throws IOException {
InputStream inputStream = toInputStream("");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,11 @@
package org.mobilitydata.gtfsvalidator.parsing;

import static com.google.common.truth.Truth.assertThat;
import static org.mobilitydata.gtfsvalidator.TestUtils.toInputStream;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.function.Function;
Expand All @@ -31,20 +30,7 @@
import org.junit.runners.JUnit4;
import org.mobilitydata.gtfsvalidator.annotation.FieldLevelEnum;
import org.mobilitydata.gtfsvalidator.input.CountryCode;
import org.mobilitydata.gtfsvalidator.notice.EmptyRowNotice;
import org.mobilitydata.gtfsvalidator.notice.InvalidEmailNotice;
import org.mobilitydata.gtfsvalidator.notice.InvalidFloatNotice;
import org.mobilitydata.gtfsvalidator.notice.InvalidPhoneNumberNotice;
import org.mobilitydata.gtfsvalidator.notice.InvalidRowLengthNotice;
import org.mobilitydata.gtfsvalidator.notice.InvalidUrlNotice;
import org.mobilitydata.gtfsvalidator.notice.LeadingOrTrailingWhitespacesNotice;
import org.mobilitydata.gtfsvalidator.notice.MissingRecommendedFieldNotice;
import org.mobilitydata.gtfsvalidator.notice.MissingRequiredFieldNotice;
import org.mobilitydata.gtfsvalidator.notice.NewLineInValueNotice;
import org.mobilitydata.gtfsvalidator.notice.NonAsciiOrNonPrintableCharNotice;
import org.mobilitydata.gtfsvalidator.notice.NoticeContainer;
import org.mobilitydata.gtfsvalidator.notice.NumberOutOfRangeNotice;
import org.mobilitydata.gtfsvalidator.notice.ValidationNotice;
import org.mobilitydata.gtfsvalidator.notice.*;
import org.mobilitydata.gtfsvalidator.type.GtfsColor;
import org.mobilitydata.gtfsvalidator.type.GtfsDate;
import org.mobilitydata.gtfsvalidator.type.GtfsTime;
Expand All @@ -57,10 +43,6 @@ public class RowParserTest {
private static CountryCode TEST_COUNTRY_CODE = CountryCode.forStringOrUnknown("AU");
private static String TEST_FILENAME = "stops.txt";

private static InputStream toInputStream(String s) {
return new ByteArrayInputStream(s.getBytes(StandardCharsets.UTF_8));
}

private static GtfsFieldValidator FIELD_VALIDATOR = new DefaultFieldValidator(TEST_COUNTRY_CODE);

private static RowParser createParser(String cellValue) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
package org.mobilitydata.gtfsvalidator.table;

import static com.google.common.truth.Truth.assertThat;
import static org.mobilitydata.gtfsvalidator.TestUtils.toInputStream;
import static org.mobilitydata.gtfsvalidator.TestUtils.validationNoticeTypes;
import static org.mockito.Mockito.*;

import com.google.common.collect.ImmutableList;
import java.io.InputStream;
import java.util.List;
import java.util.Set;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.mobilitydata.gtfsvalidator.annotation.FieldLevelEnum;
import org.mobilitydata.gtfsvalidator.notice.*;
import org.mobilitydata.gtfsvalidator.parsing.CsvHeader;
import org.mobilitydata.gtfsvalidator.testgtfs.GtfsTestEntity;
import org.mobilitydata.gtfsvalidator.testgtfs.GtfsTestFileValidator;
import org.mobilitydata.gtfsvalidator.testgtfs.GtfsTestTableDescriptor;
import org.mobilitydata.gtfsvalidator.validator.GtfsFieldValidator;
import org.mobilitydata.gtfsvalidator.validator.TableHeaderValidator;
import org.mobilitydata.gtfsvalidator.validator.ValidatorProvider;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.mockito.quality.Strictness;

public class AnyTableLoaderTest {

@Rule public MockitoRule rule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);
@Mock private GtfsTableContainer mockContainer;
@Mock private ValidatorProvider validatorProvider;
private NoticeContainer loaderNotices;

@Before
public void setup() {
loaderNotices = new NoticeContainer();
}

@Test
public void invalidInputStream() {
var testTableDescriptor = mock(GtfsTableDescriptor.class);
when(testTableDescriptor.gtfsFilename()).thenReturn("_not_a_valid_file_");
when(testTableDescriptor.createContainerForInvalidStatus(
GtfsTableContainer.TableStatus.INVALID_HEADERS))
.thenReturn(mockContainer);

var loadedContainer =
AnyTableLoader.load(testTableDescriptor, validatorProvider, null, loaderNotices);

assertThat(validationNoticeTypes(loaderNotices)).containsExactly(CsvParsingFailedNotice.class);
assertThat(loadedContainer).isEqualTo(mockContainer);
}

@Test
public void emptyInputStream() {
var testTableDescriptor = mock(GtfsTableDescriptor.class);
when(testTableDescriptor.gtfsFilename()).thenReturn("filename");
when(testTableDescriptor.createContainerForInvalidStatus(
GtfsTableContainer.TableStatus.EMPTY_FILE))
.thenReturn(mockContainer);
InputStream csvInputStream = toInputStream("");

var loadedContainer =
AnyTableLoader.load(testTableDescriptor, validatorProvider, csvInputStream, loaderNotices);

assertThat(loaderNotices.getValidationNotices())
.containsExactly(new EmptyFileNotice("filename"));
assertThat(loadedContainer).isEqualTo(mockContainer);
}

@Test
public void invalidHeaders() {
var testTableDescriptor = mock(GtfsTableDescriptor.class);
when(testTableDescriptor.gtfsFilename()).thenReturn("filename");
when(testTableDescriptor.getColumns()).thenReturn(ImmutableList.of());
when(testTableDescriptor.createContainerForInvalidStatus(
GtfsTableContainer.TableStatus.INVALID_HEADERS))
.thenReturn(mockContainer);
InputStream csvInputStream = toInputStream("A file with no headers");
ValidationNotice headerValidationNotice = mock(ValidationNotice.class);
when(headerValidationNotice.isError()).thenReturn(true);
TableHeaderValidator tableHeaderValidator =
new TableHeaderValidator() {
@Override
public void validate(
String filename,
CsvHeader actualHeader,
Set<String> supportedHeaders,
Set<String> requiredHeaders,
NoticeContainer noticeContainer) {
noticeContainer.addValidationNotice(headerValidationNotice);
}
};
when(validatorProvider.getTableHeaderValidator()).thenReturn(tableHeaderValidator);

var loadedContainer =
AnyTableLoader.load(testTableDescriptor, validatorProvider, csvInputStream, loaderNotices);

assertThat(loaderNotices.getValidationNotices()).containsExactly(headerValidationNotice);
assertThat(loadedContainer).isEqualTo(mockContainer);
}

@Test
public void invalidRowLengthNotice() {
var testTableDescriptor = spy(new GtfsTestTableDescriptor());
when(testTableDescriptor.createContainerForInvalidStatus(
GtfsTableContainer.TableStatus.UNPARSABLE_ROWS))
.thenReturn(mockContainer);
when(validatorProvider.getTableHeaderValidator()).thenReturn(mock(TableHeaderValidator.class));
InputStream inputStream = toInputStream("id,code\n" + "s1\n");

var loadedContainer =
AnyTableLoader.load(testTableDescriptor, validatorProvider, inputStream, loaderNotices);

assertThat(loaderNotices.getValidationNotices())
.containsExactly(new InvalidRowLengthNotice("filename.txt", 2, 1, 2));
assertThat(loadedContainer).isEqualTo(mockContainer);
}

@Test
public void parsableTableRows() {
var testTableDescriptor = new GtfsTestTableDescriptor();
when(validatorProvider.getTableHeaderValidator()).thenReturn(mock(TableHeaderValidator.class));
when(validatorProvider.getFieldValidator()).thenReturn(mock(GtfsFieldValidator.class));
GtfsTestFileValidator validator = mock(GtfsTestFileValidator.class);
when(validatorProvider.createSingleFileValidators(any())).thenReturn(List.of(validator));
InputStream inputStream = toInputStream("id,stop_lat,_no_name_\n" + "s1, 23.00, no_value\n");

var loadedContainer =
AnyTableLoader.load(testTableDescriptor, validatorProvider, inputStream, loaderNotices);

assertThat(loadedContainer.getTableStatus())
.isEqualTo(GtfsTableContainer.TableStatus.PARSABLE_HEADERS_AND_ROWS);
verify(validator, times(1)).validate(any());
}

@Test
public void missingRequiredField() {
var testTableDescriptor = spy(new GtfsTestTableDescriptor());
when(testTableDescriptor.getColumns())
.thenReturn(
ImmutableList.of(
GtfsColumnDescriptor.builder()
.setColumnName(GtfsTestEntity.ID_FIELD_NAME)
.setHeaderRequired(true)
.setFieldLevel(FieldLevelEnum.REQUIRED)
.setIsMixedCase(false)
.setIsCached(false)
.build(),
GtfsColumnDescriptor.builder()
.setColumnName(GtfsTestEntity.CODE_FIELD_NAME)
.setHeaderRequired(false)
.setFieldLevel(FieldLevelEnum.REQUIRED)
.setIsMixedCase(false)
.setIsCached(false)
.build()));
when(testTableDescriptor.createContainerForInvalidStatus(
GtfsTableContainer.TableStatus.UNPARSABLE_ROWS))
.thenReturn(mockContainer);
when(validatorProvider.getTableHeaderValidator()).thenReturn(mock(TableHeaderValidator.class));
when(validatorProvider.getFieldValidator()).thenReturn(mock(GtfsFieldValidator.class));
InputStream inputStream = toInputStream("id,code\n" + "s1,\n");

var loadedContainer =
AnyTableLoader.load(testTableDescriptor, validatorProvider, inputStream, loaderNotices);

assertThat(loaderNotices.getValidationNotices())
.contains(new MissingRequiredFieldNotice("filename.txt", 2, "code"));
assertThat(loadedContainer).isEqualTo(mockContainer);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,18 @@

import com.google.common.collect.ImmutableList;
import org.junit.Test;
import org.mobilitydata.gtfsvalidator.parsing.CsvHeader;
import org.mobilitydata.gtfsvalidator.table.GtfsTableContainer.TableStatus;
import org.mobilitydata.gtfsvalidator.testgtfs.GtfsStopTableContainer;
import org.mobilitydata.gtfsvalidator.testgtfs.GtfsTestTableContainer;

public class GtfsFeedContainerTest {

@Test
public void getTableForFilename() {
GtfsStopTableContainer stopTable =
new GtfsStopTableContainer(TableStatus.EMPTY_FILE, CsvHeader.EMPTY);
GtfsFeedContainer feedContainer = new GtfsFeedContainer(ImmutableList.of(stopTable));
GtfsTestTableContainer table = new GtfsTestTableContainer(TableStatus.EMPTY_FILE);
GtfsFeedContainer feedContainer = new GtfsFeedContainer(ImmutableList.of(table));

assertThat(feedContainer.getTableForFilename("stops.txt")).hasValue(stopTable);
assertThat(feedContainer.getTableForFilename("STOPS.TXT")).hasValue(stopTable);
assertThat(feedContainer.getTableForFilename("filename.txt")).hasValue(table);
assertThat(feedContainer.getTableForFilename("FILENAME.TXT")).hasValue(table);
assertThat(feedContainer.getTableForFilename("STOPS")).isEmpty();
}
}

This file was deleted.

This file was deleted.

Loading