DataTableTypeRegistryTableConverter implements TableConverter { @Override public <K, V> Map<K, V> toMap(DataTable dataTable, Type keyType, Type valueType) { requireNonNull(dataTable, "dataTable may not be null"); requireNonNull(keyType, "keyType may not be null"); requireNonNull(valueType, "valueType may not be null"); if (dataTable.isEmpty()) { return emptyMap(); } DataTable keyColumn = dataTable.columns(0, 1); DataTable valueColumns = dataTable.columns(1); String firstHeaderCell = keyColumn.cell(0, 0); boolean firstHeaderCellIsBlank = firstHeaderCell == null || firstHeaderCell.isEmpty(); List<K> keys = convertEntryKeys(keyType, keyColumn, valueType, firstHeaderCellIsBlank); if (valueColumns.isEmpty()) { return createMap(keyType, keys, valueType, nCopies(keys.size(), null)); } boolean keysImplyTableRowTransformer = keys.size() == dataTable.height() - 1; List<V> values = convertEntryValues(valueColumns, keyType, valueType, keysImplyTableRowTransformer); if (keys.size() != values.size()) { throw keyValueMismatchException(firstHeaderCellIsBlank, keys.size(), keyType, values.size(), valueType); } return createMap(keyType, keys, valueType, values); } DataTableTypeRegistryTableConverter(DataTableTypeRegistry registry); @Override T convert(DataTable dataTable, Type type); @Override @SuppressWarnings("unchecked") T convert(DataTable dataTable, Type type, boolean transposed); @Override List<T> toList(DataTable dataTable, Type itemType); @Override @SuppressWarnings("unchecked") List<List<T>> toLists(DataTable dataTable, Type itemType); @Override Map<K, V> toMap(DataTable dataTable, Type keyType, Type valueType); @Override @SuppressWarnings("unchecked") List<Map<K, V>> toMaps(DataTable dataTable, Type keyType, Type valueType);  }
@Test void to_map__duplicate_keys__throws_exception() { DataTable table = parse("", "| | lat | lon |", "| KMSY | 29.993333 | -90.258056 |", "| KSEA | 47.448889 | -122.309444 |", "| KSFO | 37.618889 | -122.375 |", "| KSEA | 47.448889 | -122.309444 |", "| KJFK | 40.639722 | -73.778889 |" ); registry.defineDataTableType(new DataTableType(AirPortCode.class, AIR_PORT_CODE_TABLE_CELL_TRANSFORMER)); registry.defineDataTableType(new DataTableType(Coordinate.class, COORDINATE_TABLE_ENTRY_TRANSFORMER)); CucumberDataTableException exception = assertThrows( CucumberDataTableException.class, () -> converter.toMap(table, AirPortCode.class, Coordinate.class) ); assertThat(exception.getMessage(), startsWith(format("" + "Can't convert DataTable to Map<%s, %s>.\n" + "Encountered duplicate key", typeName(AirPortCode.class), typeName(Coordinate.class)))); }
@Test void to_map_of_entry_to_primitive__blank_first_cell__throws_exception__key_type_was_entry() { DataTable table = parse("", "| code | |", "| KMSY | Louis Armstrong New Orleans International Airport |", "| KSFO | San Francisco International Airport |", "| KSEA | Seattle–Tacoma International Airport |", "| KJFK | John F. Kennedy International Airport |" ); registry.defineDataTableType(new DataTableType(AirPortCode.class, AIR_PORT_CODE_TABLE_ENTRY_TRANSFORMER)); CucumberDataTableException exception = assertThrows( CucumberDataTableException.class, () -> converter.toMap(table, AirPortCode.class, String.class) ); assertThat(exception.getMessage(), is("" + "Can't convert DataTable to Map<io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$AirPortCode, java.lang.String>.\n" + "The first cell was either blank or you have registered a TableEntryTransformer for the key type.\n" + "\n" + "This requires that there is a TableEntryTransformer for the value type but I couldn't find any.\n" + "\n" + "You can either:\n" + "\n" + " 1) Use a DataTableType that uses a TableEntryTransformer for class java.lang.String\n" + "\n" + " 2) Add a key to the first cell and use a DataTableType that uses a TableEntryTransformer for class io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$AirPortCode" )); }
@Test void to_map_of_entry_to_row__throws_exception__more_values_then_keys() { DataTable table = parse("", "| code | 29.993333 | -90.258056 |", "| KSFO | 37.618889 | -122.375 |", "| KSEA | 47.448889 | -122.309444 |", "| KJFK | 40.639722 | -73.778889 |" ); registry.defineDataTableType(new DataTableType(AirPortCode.class, AIR_PORT_CODE_TABLE_ENTRY_TRANSFORMER)); registry.defineDataTableType(new DataTableType(Coordinate.class, COORDINATE_TABLE_ROW_TRANSFORMER)); CucumberDataTableException exception = assertThrows( CucumberDataTableException.class, () -> converter.toMap(table, AirPortCode.class, Coordinate.class) ); assertThat(exception.getMessage(), is(format("" + "Can't convert DataTable to Map<%s, %s>.\n" + "There are more values then keys. " + "Did you use a TableEntryTransformer for the key " + "while using a TableRow or TableCellTransformer for the value?", typeName(AirPortCode.class), typeName(Coordinate.class)))); }
@Test void to_map_of_object_to_unknown_type__throws_exception__register_table_entry_transformer() { DataTable table = parse("", "| code | lat | lon |", "| KMSY | 29.993333 | -90.258056 |", "| KSFO | 37.618889 | -122.375 |", "| KSEA | 47.448889 | -122.309444 |", "| KJFK | 40.639722 | -73.778889 |" ); registry.defineDataTableType(new DataTableType(AirPortCode.class, AIR_PORT_CODE_TABLE_ENTRY_TRANSFORMER)); CucumberDataTableException exception = assertThrows( CucumberDataTableException.class, () -> converter.toMap(table, AirPortCode.class, Coordinate.class) ); assertThat(exception.getMessage(), startsWith(format("" + "Can't convert DataTable to Map<%s, %s>.\n" + "The first cell was either blank or you have registered a TableEntryTransformer for the key type.", typeName(AirPortCode.class), typeName(Coordinate.class)))); }
@Test void to_map_of_primitive_to_entry__throws_exception__more_keys_then_values() { DataTable table = parse("", "| code | lat | lon |", "| KMSY | 29.993333 | -90.258056 |", "| KSFO | 37.618889 | -122.375 |", "| KSEA | 47.448889 | -122.309444 |", "| KJFK | 40.639722 | -73.778889 |" ); registry.defineDataTableType(new DataTableType(Coordinate.class, COORDINATE_TABLE_ENTRY_TRANSFORMER)); CucumberDataTableException exception = assertThrows( CucumberDataTableException.class, () -> converter.toMap(table, String.class, Coordinate.class) ); assertThat(exception.getMessage(), is(format("" + "Can't convert DataTable to Map<%s, %s>.\n" + "There are more keys than values. " + "Did you use a TableEntryTransformer for the value " + "while using a TableRow or TableCellTransformer for the keys?", typeName(String.class), typeName(Coordinate.class)))); }
@Test void to_map_of_primitive_to_primitive__blank_first_cell__throws_exception__first_cell_was_blank() { DataTable table = parse("", " | | birthDate |", " | Annie M. G. Schmidt | 1911-03-20 |", " | Roald Dahl | 1916-09-13 |", " | Astrid Lindgren | 1907-11-14 |" ); CucumberDataTableException exception = assertThrows( CucumberDataTableException.class, () -> converter.toMap(table, String.class, String.class) ); assertThat(exception.getMessage(), startsWith(format("" + "Can't convert DataTable to Map<%s, %s>.\n" + "The first cell was either blank or you have registered a TableEntryTransformer for the key type.", typeName(String.class), typeName(String.class)))); }
@Test void to_map_of_unknown_key_type__throws_exception() { DataTable table = parse("", " | name | birthDate |", " | Annie M. G. Schmidt | 1911-03-20 |", " | Roald Dahl | 1916-09-13 |", " | Astrid Lindgren | 1907-11-14 |" ); CucumberDataTableException exception = assertThrows( CucumberDataTableException.class, () -> converter.toMap(table, Author.class, String.class) ); assertThat(exception.getMessage(), is("" + "Can't convert DataTable to Map<io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$Author, java.lang.String>.\n" + "Please review these problems:\n" + "\n" + " - There was no table entry or table row transformer registered for io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$Author.\n" + " Please consider registering a table entry or row transformer.\n" + "\n" + " - There was no table cell transformer registered for io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$Author.\n" + " Please consider registering a table cell transformer.\n" + "\n" + " - There was no default table entry transformer registered to transform io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$Author.\n" + " Please consider registering a default table entry transformer.\n" + "\n" + " - There was no default table cell transformer registered to transform io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$Author.\n" + " Please consider registering a default table cell transformer.\n" + "\n" + "Note: Usually solving one is enough" )); }
@Test void to_map_of_unknown_type_to_object__throws_exception__register_table_cell_transformer() { DataTable table = parse("", "| | lat | lon |", "| KMSY | 29.993333 | -90.258056 |", "| KSFO | 37.618889 | -122.375 |", "| KSEA | 47.448889 | -122.309444 |", "| KJFK | 40.639722 | -73.778889 |" ); registry.defineDataTableType(new DataTableType(Coordinate.class, COORDINATE_TABLE_ENTRY_TRANSFORMER)); CucumberDataTableException exception = assertThrows( CucumberDataTableException.class, () -> converter.toMap(table, AirPortCode.class, Coordinate.class) ); assertThat(exception.getMessage(), is("" + "Can't convert DataTable to Map<io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$AirPortCode, io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$Coordinate>.\n" + "Please review these problems:\n" + "\n" + " - There was no table cell transformer registered for io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$AirPortCode.\n" + " Please consider registering a table cell transformer.\n" + "\n" + " - There was no default table cell transformer registered to transform io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$AirPortCode.\n" + " Please consider registering a default table cell transformer.\n" + "\n" + "Note: Usually solving one is enough" )); }
@Test void to_map_of_unknown_value_type__throws_exception() { DataTable table = parse("", " | Annie M. G. Schmidt | 1911-03-20 |", " | Roald Dahl | 1916-09-13 |", " | Astrid Lindgren | 1907-11-14 |" ); CucumberDataTableException exception = assertThrows( CucumberDataTableException.class, () -> converter.toMap(table, String.class, Date.class) ); assertThat(exception.getMessage(), is("" + "Can't convert DataTable to Map<java.lang.String, java.util.Date>.\n" + "Please review these problems:\n" + "\n" + " - There was no table entry transformer registered for java.util.Date.\n" + " Please consider registering a table entry transformer.\n" + "\n" + " - There was no table cell transformer registered for java.util.Date.\n" + " Please consider registering a table cell transformer.\n" + "\n" + " - There was no default table cell transformer registered to transform java.util.Date.\n" + " Please consider registering a default table cell transformer.\n" + "\n" + "Note: Usually solving one is enough" )); }