diff --git a/docs/modules/commons/pages/table-transformers.adoc b/docs/modules/commons/pages/table-transformers.adoc index 319c9bda44..2a96bcded2 100644 --- a/docs/modules/commons/pages/table-transformers.adoc +++ b/docs/modules/commons/pages/table-transformers.adoc @@ -471,3 +471,48 @@ Examples: ---- {transformer=CARTESIAN_PRODUCT, tables=\{transformer=REPEATING\, times=100\};\{transformer=FROM_CSV\, csvPath=/data/csv.csv\}} ---- + +== INDEXING + +`INDEXING` transformer adds a column with the rows indices in the specified order. Indices are zero-based + +[cols="1,3", options="header"] +|=== +|Parameter|Description + +|`order`|The mandatory indedxing order: `ASCENDING` or `DESCENDING`. +|=== + +.ASCENDING order example +[source,gherkin] +---- +{transformer=INDEXING, order=ASCENDING} +|key | +|value | +|value2| +---- + +.ASCENDING order resulting table +[source,gherkin] +---- +|key |index| +|value |0 | +|value2|1 | +---- + +.DESCENDING order example +[source,gherkin] +---- +{transformer=INDEXING, order=DESCENDING} +|key | +|value | +|value2| +---- + +.DESCENDING order resulting table +[source,gherkin] +---- +|key |index| +|value |1 | +|value2|0 | +---- diff --git a/vividus-tests/src/main/resources/story/integration/TableTransformers.story b/vividus-tests/src/main/resources/story/integration/TableTransformers.story index 9fbdd13385..165be60b7c 100644 --- a/vividus-tests/src/main/resources/story/integration/TableTransformers.story +++ b/vividus-tests/src/main/resources/story/integration/TableTransformers.story @@ -303,3 +303,21 @@ When I initialize scenario variable `sitemapTransformerTable` with values: {transformer=FROM_SITEMAP, siteMapRelativeUrl=/index.html, column=sitemapUrl, ignoreErrors=true} Then `${sitemapTransformerTable}` is equal to table: |sitemapUrl | + +Scenario: Verify INDEXING transformer ASCENDING order +Then `` is = `` +Examples: +{transformer=INDEXING, order=ASCENDING} +|expected| +|0 | +|1 | +|2 | + +Scenario: Verify INDEXING transformer DESCENDING order +Then `` is = `` +Examples: +{transformer=INDEXING, order=DESCENDING} +|expected| +|2 | +|1 | +|0 | diff --git a/vividus/src/main/java/org/vividus/transformer/IndexingTableTransformer.java b/vividus/src/main/java/org/vividus/transformer/IndexingTableTransformer.java new file mode 100644 index 0000000000..2ba8da1494 --- /dev/null +++ b/vividus/src/main/java/org/vividus/transformer/IndexingTableTransformer.java @@ -0,0 +1,73 @@ +/* + * Copyright 2019-2022 the original author or authors. + * + * 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 + * + * https://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 + * limitations under the License. + */ + +package org.vividus.transformer; + +import java.util.List; +import java.util.function.IntUnaryOperator; + +import org.apache.commons.lang3.Validate; +import org.jbehave.core.model.ExamplesTable.TableProperties; +import org.jbehave.core.model.ExamplesTable.TableRows; +import org.jbehave.core.model.TableParsers; +import org.jbehave.core.model.TableTransformers.TableTransformer; +import org.vividus.util.ExamplesTableProcessor; + +public class IndexingTableTransformer implements TableTransformer +{ + private static final String INDEX = "index"; + + @Override + public String transform(String tableAsString, TableParsers tableParsers, TableProperties properties) + { + TableRows tableRows = tableParsers.parseRows(tableAsString, properties); + List headers = tableRows.getHeaders(); + Validate.isTrue(!headers.contains(INDEX), + "Unable to add column with row indices to the table, because it has `index` column."); + Order order = properties.getMandatoryNonBlankProperty("order", Order.class); + List> rows = tableRows.getRows(); + IntUnaryOperator indexer = order.getIndexer(rows); + for (int i = 0; i < rows.size(); i++) + { + rows.get(i).add(Integer.toString(indexer.applyAsInt(i))); + } + headers.add(INDEX); + return ExamplesTableProcessor.buildExamplesTable(headers, rows, properties); + } + + private enum Order + { + ASCENDING + { + @Override + IntUnaryOperator getIndexer(List rows) + { + return i -> i; + } + }, + DESCENDING + { + @Override + IntUnaryOperator getIndexer(List rows) + { + int size = rows.size(); + return i -> size - i - 1; + } + }; + + abstract IntUnaryOperator getIndexer(List rows); + } +} diff --git a/vividus/src/main/resources/org/vividus/spring-vividus.xml b/vividus/src/main/resources/org/vividus/spring-vividus.xml index 2fbf5f7d9f..0b1c11d34a 100644 --- a/vividus/src/main/resources/org/vividus/spring-vividus.xml +++ b/vividus/src/main/resources/org/vividus/spring-vividus.xml @@ -86,6 +86,7 @@ + diff --git a/vividus/src/test/java/org/vividus/transformer/IndexingTableTransformerTests.java b/vividus/src/test/java/org/vividus/transformer/IndexingTableTransformerTests.java new file mode 100644 index 0000000000..ed53c0c6f9 --- /dev/null +++ b/vividus/src/test/java/org/vividus/transformer/IndexingTableTransformerTests.java @@ -0,0 +1,60 @@ +/* + * Copyright 2019-2022 the original author or authors. + * + * 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 + * + * https://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 + * limitations under the License. + */ + +package org.vividus.transformer; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.jbehave.core.configuration.Keywords; +import org.jbehave.core.model.ExamplesTable.TableProperties; +import org.jbehave.core.model.TableParsers; +import org.jbehave.core.steps.ParameterConverters; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +class IndexingTableTransformerTests +{ + @ParameterizedTest + @CsvSource({ + "order=ASCENDING, '|k|index|\n|value|0|\n|value2|1|'", + "order=DESCENDING, '|k|index|\n|value|1|\n|value2|0|'" + }) + void shouldAddIndexColumnAccordingWithOrder(String properties, String expectedTable) + { + var transformer = new IndexingTableTransformer(); + var converters = new ParameterConverters(); + var tableProperties = new TableProperties(properties, new Keywords(), converters); + + assertEquals(expectedTable, transformer.transform("|k|\n|value|\n|value2|", + new TableParsers(new ParameterConverters()), tableProperties)); + } + + @Test + void shouldThrowAnExceptionIfIndexColumnIsInTheTable() + { + var transformer = new IndexingTableTransformer(); + var converters = new ParameterConverters(); + var tableProperties = new TableProperties("", new Keywords(), converters); + var tableParsers = new TableParsers(new ParameterConverters()); + + var iae = assertThrows(IllegalArgumentException.class, () -> transformer.transform("|index|\n|v|", + tableParsers, tableProperties)); + assertEquals("Unable to add column with row indices to the table, because it has `index` column.", + iae.getMessage()); + } +}