DataTableTypeRegistryTableConverter implements TableConverter { @Override public <T> T convert(DataTable dataTable, Type type) { return convert(dataTable, type, false); } 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 convert_to_empty_list_of_object__using_default_converter__throws_exception() { DataTable table = parse("", " | firstName | lastName | birthDate |" ); registry.setDefaultDataTableEntryTransformer(JACKSON_TABLE_ENTRY_BY_TYPE_CONVERTER); registry.setDefaultDataTableCellTransformer(TABLE_CELL_BY_TYPE_CONVERTER_SHOULD_NOT_BE_USED); CucumberDataTableException exception = assertThrows( CucumberDataTableException.class, () -> converter.convert(table, LIST_OF_AUTHOR) ); assertThat(exception.getMessage(), is("" + "Can't convert DataTable to List<io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$Author>.\n" + "Please review these problems:\n" + "\n" + " - There was a default table cell transformer that could be used but the table was too wide to use it.\n" + " Please reduce the table width to use this converter.\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 a default table entry transformer that could be used but the table was too short use it.\n" + " Please increase the table height to use this converter.\n" + "\n" + "Note: Usually solving one is enough" )); }
@Test void convert_to_list_of_unknown_type__throws_exception__register_transformer() { DataTable table = parse("", " | firstName | lastName | birthDate |", " | Annie M. G. | Schmidt | 1911-03-20 |", " | Roald | Dahl | 1916-09-13 |", " | Astrid | Lindgren | 1907-11-14 |" ); CucumberDataTableException exception = assertThrows( CucumberDataTableException.class, () -> converter.convert(table, LIST_OF_AUTHOR) ); assertThat(exception.getMessage(), is("" + "Can't convert DataTable to List<io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$Author>.\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 default table entry transformer registered to transform io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$Author.\n" + " Please consider registering a default table entry transformer.\n" + "\n" + "Note: Usually solving one is enough" )); }
@Test void convert_to_lists_of_unknown_type__throws_exception__register_transformer() { DataTable table = parse("", " | 1911-03-20 |", " | 1916-09-13 |", " | 1907-11-14 |" ); CucumberDataTableException exception = assertThrows( CucumberDataTableException.class, () -> converter.convert(table, LIST_OF_LIST_OF_DATE) ); assertThat(exception.getMessage(), is("" + "Can't convert DataTable to List<List<java.util.Date>>.\n" + "Please review these problems:\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" )); }
@Test void to_map_of_object_to_object__without_implied_entries__prefers__default_table_entry_converter() { DataTable table = parse("", "| KMSY | KSFO |", "| KSFO | KSEA |", "| KSEA | KJFK |", "| KJFK | AMS |" ); Map<AirPortCode, AirPortCode> expected = new HashMap<AirPortCode, AirPortCode>() {{ put(new AirPortCode("KMSY"), new AirPortCode("KSFO")); put(new AirPortCode("KSFO"), new AirPortCode("KSEA")); put(new AirPortCode("KSEA"), new AirPortCode("KJFK")); put(new AirPortCode("KJFK"), new AirPortCode("AMS")); }}; registry.setDefaultDataTableCellTransformer(JACKSON_TABLE_CELL_BY_TYPE_CONVERTER); assertEquals(expected, converter.convert(table, MAP_OF_AIR_PORT_CODE_TO_AIR_PORT_CODE)); }
@Test void convert_to_map_of_primitive_to_list_of_primitive() { DataTable table = parse("", "| KMSY | 29.993333 | -90.258056 |", "| KSFO | 37.618889 | -122.375 |", "| KSEA | 47.448889 | -122.309444 |", "| KJFK | 40.639722 | -73.778889 |" ); Map<String, List<Double>> expected = new HashMap<String, List<Double>>() {{ put("KMSY", asList(29.993333, -90.258056)); put("KSFO", asList(37.618889, -122.375)); put("KSEA", asList(47.448889, -122.309444)); put("KJFK", asList(40.639722, -73.778889)); }}; assertEquals(expected, converter.convert(table, MAP_OF_STRING_TO_LIST_OF_DOUBLE)); }
@Test void convert_to_map_of_primitive_to_list_of_object() throws ParseException { DataTable table = parse("", " | Annie M. G. | 1995-03-21 | 1911-03-20 |", " | Roald | 1990-09-13 | 1916-09-13 |", " | Astrid | 1907-10-14 | 1907-11-14 |" ); Map<String, List<Date>> expected = new HashMap<String, List<Date>>() {{ put("Annie M. G.", asList(SIMPLE_DATE_FORMAT.parse("1995-03-21"), SIMPLE_DATE_FORMAT.parse("1911-03-20"))); put("Roald", asList(SIMPLE_DATE_FORMAT.parse("1990-09-13"), SIMPLE_DATE_FORMAT.parse("1916-09-13"))); put("Astrid", asList(SIMPLE_DATE_FORMAT.parse("1907-10-14"), SIMPLE_DATE_FORMAT.parse("1907-11-14"))); }}; registry.defineDataTableType(DATE_TABLE_CELL_TRANSFORMER); assertEquals(expected, converter.convert(table, MAP_OF_STRING_TO_LIST_OF_DATE)); }
@Test void convert_to_map_of_primitive_to_list_of_object__with_default_converter() throws ParseException { DataTable table = parse("", " | Annie M. G. | 1995-03-21 | 1911-03-20 |", " | Roald | 1990-09-13 | 1916-09-13 |", " | Astrid | 1907-10-14 | 1907-11-14 |" ); Map<String, List<Date>> expected = new HashMap<String, List<Date>>() {{ put("Annie M. G.", asList(SIMPLE_DATE_FORMAT.parse("1995-03-21"), SIMPLE_DATE_FORMAT.parse("1911-03-20"))); put("Roald", asList(SIMPLE_DATE_FORMAT.parse("1990-09-13"), SIMPLE_DATE_FORMAT.parse("1916-09-13"))); put("Astrid", asList(SIMPLE_DATE_FORMAT.parse("1907-10-14"), SIMPLE_DATE_FORMAT.parse("1907-11-14"))); }}; registry.setDefaultDataTableCellTransformer(JACKSON_TABLE_CELL_BY_TYPE_CONVERTER); assertEquals(expected, converter.convert(table, MAP_OF_STRING_TO_LIST_OF_DATE)); }
@Test void convert_to_map_of_primitive_to_list_of_primitive__default_converter_present() { registry.setDefaultDataTableEntryTransformer(TABLE_ENTRY_BY_TYPE_CONVERTER_SHOULD_NOT_BE_USED); registry.setDefaultDataTableCellTransformer(TABLE_CELL_BY_TYPE_CONVERTER_SHOULD_NOT_BE_USED); DataTable table = parse("", "| KMSY | 29.993333 | -90.258056 |", "| KSFO | 37.618889 | -122.375 |", "| KSEA | 47.448889 | -122.309444 |", "| KJFK | 40.639722 | -73.778889 |" ); Map<String, List<Double>> expected = new HashMap<String, List<Double>>() {{ put("KMSY", asList(29.993333, -90.258056)); put("KSFO", asList(37.618889, -122.375)); put("KSEA", asList(47.448889, -122.309444)); put("KJFK", asList(40.639722, -73.778889)); }}; assertEquals(expected, converter.convert(table, MAP_OF_STRING_TO_LIST_OF_DOUBLE)); }
@Test void convert_to_map_of_primitive_to_map_of_primitive_to_object() { DataTable table = parse("", " | | 1 | 2 | 3 |", " | A | ♘ | | ♝ |", " | B | | | |", " | C | | ♝ | |" ); registry.defineDataTableType(new DataTableType(Piece.class, PIECE_TABLE_CELL_TRANSFORMER)); Map<String, Map<Integer, Piece>> expected = new HashMap<String, Map<Integer, Piece>>() {{ put("A", new HashMap<Integer, Piece>() {{ put(1, Piece.WHITE_KNIGHT); put(2, null); put(3, Piece.BLACK_BISHOP); }}); put("B", new HashMap<Integer, Piece>() {{ put(1, null); put(2, null); put(3, null); }}); put("C", new HashMap<Integer, Piece>() {{ put(1, null); put(2, Piece.BLACK_BISHOP); put(3, null); }}); }}; assertEquals(expected, converter.convert(table, MAP_OF_STRING_TO_MAP_OF_INTEGER_TO_PIECE)); }
@Test void convert_to_map_of_primitive_to_map_of_primitive_to_primitive() { 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 |" ); Map<String, Map<String, Double>> expected = new HashMap<String, Map<String, Double>>() {{ put("KMSY", new HashMap<String, Double>() {{ put("lat", 29.993333); put("lon", -90.258056); }}); put("KSFO", new HashMap<String, Double>() {{ put("lat", 37.618889); put("lon", -122.375); }}); put("KSEA", new HashMap<String, Double>() {{ put("lat", 47.448889); put("lon", -122.309444); }}); put("KJFK", new HashMap<String, Double>() {{ put("lat", 40.639722); put("lon", -73.778889); }}); }}; assertEquals(expected, converter.convert(table, MAP_OF_STRING_TO_MAP_OF_STRING_DOUBLE)); }
@Test void convert_to_map_of_string_to_map() { 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 |" ); Map<String, Map<String, String>> expected = new HashMap<String, Map<String, String>>() {{ put("KMSY", new HashMap<String, String>() {{ put("lat", "29.993333"); put("lon", "-90.258056"); }}); put("KSFO", new HashMap<String, String>() {{ put("lat", "37.618889"); put("lon", "-122.375"); }}); put("KSEA", new HashMap<String, String>() {{ put("lat", "47.448889"); put("lon", "-122.309444"); }}); put("KJFK", new HashMap<String, String>() {{ put("lat", "40.639722"); put("lon", "-73.778889"); }}); }}; assertEquals(expected, converter.convert(table, MAP_OF_STRING_TO_MAP)); }
@Test void convert_to_map_of_string_to_string__throws_exception__blank_space() { DataTable table = parse("", "| | -90.258056 |", "| 37.618889 | -122.375 |", "| 47.448889 | -122.309444 |", "| 40.639722 | -73.778889 |" ); CucumberDataTableException exception = assertThrows( CucumberDataTableException.class, () -> converter.convert(table, MAP_OF_STRING_TO_LIST_OF_DOUBLE) ); assertThat(exception.getMessage(), is(format("" + "Can't convert DataTable to Map<%s, %s>.\n" + "There are more values then keys. " + "The first header cell was left blank. " + "You can add a value there", typeName(String.class), LIST_OF_DOUBLE))); }
@Test void convert_to_map_of_string_to_string__throws_exception__more_then_one_value_per_key() { DataTable table = parse("", "| KMSY | 29.993333 | -90.258056 |", "| KSFO | 37.618889 | -122.375 |", "| KSEA | 47.448889 | -122.309444 |", "| KJFK | 40.639722 | -73.778889 |" ); CucumberDataTableException exception = assertThrows( CucumberDataTableException.class, () -> converter.convert(table, MAP_OF_STRING_TO_STRING) ); assertThat(exception.getMessage(), is(format("" + "Can't convert DataTable to Map<%s, %s>.\n" + "There is more then one value per key. " + "Did you mean to transform to Map<%s, List<%s>> instead?", typeName(String.class), typeName(String.class), typeName(String.class), typeName(String.class)))); }
@Test void convert_to_object() { registry.setDefaultDataTableEntryTransformer(TABLE_ENTRY_BY_TYPE_CONVERTER_SHOULD_NOT_BE_USED); registry.setDefaultDataTableCellTransformer(TABLE_CELL_BY_TYPE_CONVERTER_SHOULD_NOT_BE_USED); DataTable table = parse("", " | | 1 | 2 | 3 |", " | A | ♘ | | ♝ |", " | B | | | |", " | C | | ♝ | |" ); registry.defineDataTableType(new DataTableType(ChessBoard.class, CHESS_BOARD_TABLE_TRANSFORMER)); ChessBoard expected = new ChessBoard(asList("♘", "♝", "♝")); assertEquals(expected, converter.convert(table, ChessBoard.class)); }
@Test void convert_to_optional_of_object__must_have_optional_converter() { DataTable table = parse("", " | | 1 | 2 | 3 |", " | A | ♘ | | ♝ |", " | B | | | |", " | C | | ♝ | |" ); registry.defineDataTableType(new DataTableType(ChessBoard.class, CHESS_BOARD_TABLE_TRANSFORMER)); UndefinedDataTableTypeException exception = assertThrows( UndefinedDataTableTypeException.class, () -> converter.convert(table, OPTIONAL_CHESS_BOARD_TYPE) ); assertThat(exception.getMessage(), is("" + "Can't convert DataTable to io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$ChessBoard.\n" + "Please review these problems:\n" + "\n" + " - There was no table entry or table row transformer registered for io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$ChessBoard.\n" + " Please consider registering a table entry or row transformer.\n" + "\n" + " - There was no default table entry transformer registered to transform io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$ChessBoard.\n" + " Please consider registering a default table entry transformer.\n" + "\n" + "Note: Usually solving one is enough")); }
@Test void convert_to_empty_optional_object() { registry.setDefaultDataTableEntryTransformer(TABLE_ENTRY_BY_TYPE_CONVERTER_SHOULD_NOT_BE_USED); registry.setDefaultDataTableCellTransformer(TABLE_CELL_BY_TYPE_CONVERTER_SHOULD_NOT_BE_USED); DataTable table = parse(""); registry.defineDataTableType(new DataTableType(ChessBoard.class, CHESS_BOARD_TABLE_TRANSFORMER)); assertEquals(Optional.empty(), converter.convert(table, OPTIONAL_CHESS_BOARD_TYPE)); }
@Test void convert_to_object__more_then_one_item__throws_exception() { DataTable table = parse("", "| ♘ |", "| ♝ |" ); registry.defineDataTableType(new DataTableType(Piece.class, PIECE_TABLE_CELL_TRANSFORMER)); CucumberDataTableException exception = assertThrows( CucumberDataTableException.class, () -> converter.convert(table, Piece.class) ); assertThat(exception.getMessage(), is(format("" + "Can't convert DataTable to %s. " + "The table contained more then one item: [♘, ♝]", typeName(Piece.class)))); }
@Test void convert_to_object__too_wide__throws_exception() { DataTable table = parse("", "| ♘ | ♝ |" ); registry.defineDataTableType(new DataTableType(Piece.class, PIECE_TABLE_CELL_TRANSFORMER)); CucumberDataTableException exception = assertThrows( CucumberDataTableException.class, () -> converter.convert(table, Piece.class) ); assertThat(exception.getMessage(), is("" + "Can't convert DataTable to io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$Piece.\n" + "Please review these problems:\n" + "\n" + " - There was a table cell transformer for io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$Piece but the table was too wide to use it.\n" + " Please reduce the table width to use this converter.\n" + "\n" + " - There was no table entry or table row transformer registered for io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$Piece.\n" + " Please consider registering a table entry or row transformer.\n" + "\n" + "Note: Usually solving one is enough")); }
@Test void convert_to_primitive__empty_table_to_null() { DataTable table = emptyDataTable(); assertNull(converter.convert(table, Integer.class)); }
@Test void convert_to_primitive__single_cell() { DataTable table = parse("| 3 |"); assertEquals(Integer.valueOf(3), converter.convert(table, Integer.class)); }
@Test void convert_to_single_object__single_cell() { DataTable table = parse("| ♝ |"); registry.defineDataTableType(new DataTableType(Piece.class, PIECE_TABLE_CELL_TRANSFORMER)); assertEquals(Piece.BLACK_BISHOP, converter.convert(table, Piece.class)); }
@Test void convert_to_single_object__single_cell__with_default_transformer_present() { registry.setDefaultDataTableEntryTransformer(TABLE_ENTRY_BY_TYPE_CONVERTER_SHOULD_NOT_BE_USED); registry.setDefaultDataTableCellTransformer(TABLE_CELL_BY_TYPE_CONVERTER_SHOULD_NOT_BE_USED); DataTable table = parse("| ♝ |"); registry.defineDataTableType(new DataTableType(Piece.class, PIECE_TABLE_CELL_TRANSFORMER)); assertEquals(Piece.BLACK_BISHOP, converter.convert(table, Piece.class)); }
@Test void convert_to_single_object__single_cell__using_default_transformer() { DataTable table = parse("| BLACK_BISHOP |"); registry.setDefaultDataTableEntryTransformer(TABLE_ENTRY_BY_TYPE_CONVERTER_SHOULD_NOT_BE_USED); registry.setDefaultDataTableCellTransformer(JACKSON_TABLE_CELL_BY_TYPE_CONVERTER); assertEquals(Piece.BLACK_BISHOP, converter.convert(table, Piece.class)); }
@Test void convert_to_table__table_transformer_takes_precedence_over_identity_transform() { DataTable table = parse("", " | | 1 | 2 | 3 |", " | A | ♘ | | ♝ |", " | B | | | |", " | C | | ♝ | |" ); DataTable expected = emptyDataTable(); registry.defineDataTableType(new DataTableType(DataTable.class, (DataTable raw) -> expected)); assertSame(expected, converter.convert(table, DataTable.class)); }
@Test void convert_to_table__transposed() { DataTable table = parse("", " | | 1 | 2 | 3 |", " | A | ♘ | | ♝ |", " | B | | | |", " | C | | ♝ | |" ); assertEquals(table.transpose(), converter.convert(table, DataTable.class, true)); }
@Test void convert_to_unknown_type__throws_exception() { DataTable table = parse("", "| ♘ |" ); CucumberDataTableException exception = assertThrows( CucumberDataTableException.class, () -> converter.convert(table, Piece.class)); assertThat(exception.getMessage(), is("" + "Can't convert DataTable to io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$Piece.\n" + "Please review these problems:\n" + "\n" + " - There was no table entry or table row transformer registered for io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$Piece.\n" + " Please consider registering a table entry or row transformer.\n" + "\n" + " - There was no table cell transformer registered for io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$Piece.\n" + " Please consider registering a table cell transformer.\n" + "\n" + " - There was no default table cell transformer registered to transform io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$Piece.\n" + " Please consider registering a default table cell transformer.\n" + "\n" + "Note: Usually solving one is enough")); }
@Test void convert_to_unknown_type__throws_exception__with_table_entry_converter_present__throws_exception() { DataTable table = parse("", "| ♘ |" ); CucumberDataTableException exception = assertThrows( CucumberDataTableException.class, () -> converter.convert(table, Piece.class)); assertThat(exception.getMessage(), is("" + "Can't convert DataTable to io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$Piece.\n" + "Please review these problems:\n" + "\n" + " - There was no table entry or table row transformer registered for io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$Piece.\n" + " Please consider registering a table entry or row transformer.\n" + "\n" + " - There was no table cell transformer registered for io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$Piece.\n" + " Please consider registering a table cell transformer.\n" + "\n" + " - There was no default table cell transformer registered to transform io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$Piece.\n" + " Please consider registering a default table cell transformer.\n" + "\n" + "Note: Usually solving one is enough")); }
@Test void convert_to_empty_list__only_header() { DataTable table = parse("", " | firstName | lastName | birthDate |" ); registry.defineDataTableType(new DataTableType(Author.class, AUTHOR_TABLE_ENTRY_TRANSFORMER)); assertEquals(emptyList(), converter.convert(table, LIST_OF_AUTHOR)); }
@Test void to_map_of_primitive_to_list_of_unknown__throws_exception() { DataTable table = parse("", " | Annie M. G. | 1995-03-21 | 1911-03-20 |", " | Roald | 1990-09-13 | 1916-09-13 |", " | Astrid | 1907-10-14 | 1907-11-14 |" ); CucumberDataTableException exception = assertThrows( CucumberDataTableException.class, () -> converter.convert(table, MAP_OF_STRING_TO_LIST_OF_DATE) ); assertThat(exception.getMessage(), is("" + "Can't convert DataTable to Map<java.lang.String, java.util.List<java.util.Date>>.\n" + "Please review these problems:\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" )); }
@Test void convert_to_empty_table__empty_table() { DataTable table = emptyDataTable(); assertSame(table, converter.convert(table, DataTable.class)); }
@Test void convert_to_list_of_map() { DataTable table = parse("", "| firstName | lastName | birthDate |", "| Annie M. G. | Schmidt | 1911-03-20 |", "| Roald | Dahl | 1916-09-13 |", "| Astrid | Lindgren | 1907-11-14 |" ); List<HashMap<String, String>> expected = asList( new HashMap<String, String>() {{ put("firstName", "Annie M. G."); put("lastName", "Schmidt"); put("birthDate", "1911-03-20"); }}, new HashMap<String, String>() {{ put("firstName", "Roald"); put("lastName", "Dahl"); put("birthDate", "1916-09-13"); }}, new HashMap<String, String>() {{ put("firstName", "Astrid"); put("lastName", "Lindgren"); put("birthDate", "1907-11-14"); }} ); assertEquals(expected, converter.convert(table, LIST_OF_MAP)); }