DataTableTypeRegistryTableConverter implements TableConverter { @Override @SuppressWarnings("unchecked") public <K, V> List<Map<K, V>> toMaps(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 emptyList(); } DataTableType keyConverter = registry.lookupCellTypeByType(keyType); DataTableType valueConverter = registry.lookupCellTypeByType(valueType); List<String> problems = new ArrayList<>(); if (keyConverter == null) { problems.add(problemNoTableCellTransformer(keyType)); } if (valueConverter == null) { problems.add(problemNoTableCellTransformer(valueType)); } if (!problems.isEmpty()) { throw mapsNoConverterDefined(keyType, valueType, problems); } DataTable header = dataTable.rows(0, 1); List<Map<K, V>> result = new ArrayList<>(); List<K> keys = unpack((List<List<K>>) keyConverter.transform(header.cells())); DataTable rows = dataTable.rows(1); if (rows.isEmpty()) { return emptyList(); } List<List<V>> transform = (List<List<V>>) valueConverter.transform(rows.cells()); for (List<V> values : transform) { result.add(createMap(keyType, keys, valueType, values)); } return unmodifiableList(result); } 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_maps_cant_convert_table_with_duplicate_keys() { DataTable table = parse("", "| 1 | 1 | 1 |", "| 4 | 5 | 6 |", "| 7 | 8 | 9 |" ); CucumberDataTableException exception = assertThrows( CucumberDataTableException.class, () -> converter.toMaps(table, Integer.class, Integer.class) ); assertThat(exception.getMessage(), is(format("" + "Can't convert DataTable to Map<%s, %s>.\n" + "Encountered duplicate key 1 with values 4 and 5", typeName(Integer.class), typeName(Integer.class)))); }
@Test void to_maps_cant_convert_table_with_duplicate_null_keys() { DataTable table = parse("", "| | |", "| 1 | 2 |" ); CucumberDataTableException exception = assertThrows( CucumberDataTableException.class, () -> converter.toMaps(table, Integer.class, Integer.class) ); assertThat(exception.getMessage(), is(format("" + "Can't convert DataTable to Map<%s, %s>.\n" + "Encountered duplicate key null with values 1 and 2", typeName(Integer.class), typeName(Integer.class)))); }
@Test void to_maps_of_unknown_key_type__throws_exception__register_table_cell_transformer() { DataTable table = parse("", "| lat | lon |", "| 29.993333 | -90.258056 |", "| 37.618889 | -122.375 |", "| 47.448889 | -122.309444 |", "| 40.639722 | -73.778889 |" ); CucumberDataTableException exception = assertThrows( CucumberDataTableException.class, () -> converter.toMaps(table, String.class, Coordinate.class) ); assertThat(exception.getMessage(), is("" + "Can't convert DataTable to List<Map<java.lang.String, io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$Coordinate>>.\n" + "Please review these problems:\n" + "\n" + " - There was no table cell transformer registered for io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$Coordinate.\n" + " Please consider registering a table cell transformer.\n" + "\n" + "Note: Usually solving one is enough" )); }
@Test void to_maps_of_unknown_value_type__throws_exception__register_table_cell_transformer() { DataTable table = parse("", "| ♙ | ♟ |", "| a2 | a7 |", "| b2 | b7 |", "| c2 | c7 |", "| d2 | d7 |", "| e2 | e7 |", "| f2 | f7 |", "| g2 | g7 |", "| h2 | h7 |" ); CucumberDataTableException exception = assertThrows( CucumberDataTableException.class, () -> converter.toMaps(table, Piece.class, String.class) ); assertThat(exception.getMessage(), is("" + "Can't convert DataTable to List<Map<io.cucumber.datatable.DataTableTypeRegistryTableConverterTest$Piece, java.lang.String>>.\n" + "Please review these problems:\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" + "Note: Usually solving one is enough" )); }
@Test void convert_to_maps_of_optional() { DataTable table = parse("", "| header1 | header2 |", "| 311 | 12299 |" ); Map<Optional<String>, Optional<BigInteger>> expectedMap = new HashMap<Optional<String>, Optional<BigInteger>>() {{ put(Optional.of("header1"), Optional.of(new BigInteger("311"))); put(Optional.of("header2"), Optional.of(new BigInteger("12299"))); }}; List<Map<Optional<String>, Optional<BigInteger>>> expected = singletonList(expectedMap); assertEquals(expected, converter.toMaps(table, OPTIONAL_STRING, OPTIONAL_BIG_INTEGER)); }