├── version.txt ├── settings.gradle ├── .gitignore ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── spockito-junit4-idea-testrun.png ├── spockito-junit5-idea-testrun.png ├── .travis.yml ├── spockito-junit5 ├── README.md └── src │ ├── main │ └── java │ │ └── org │ │ └── tools4j │ │ └── spockito │ │ └── jupiter │ │ ├── AggregateTableRow.java │ │ ├── SpockitoExtension.java │ │ ├── JoinOn.java │ │ ├── TableValueConverter.java │ │ ├── TableRowAggregator.java │ │ ├── TableArgumentsProvider.java │ │ ├── TableSource.java │ │ ├── TableSourceDataProvider.java │ │ └── TableRowConverters.java │ └── test │ └── java │ └── org │ └── tools4j │ └── spockito │ └── jupiter │ ├── Operation.java │ ├── TableSourceTest.java │ └── SpockitoExtensionTest.java ├── LICENSE.md ├── etc └── LICENSE.template ├── spockito-table └── src │ ├── main │ └── java │ │ └── org │ │ └── tools4j │ │ └── spockito │ │ └── table │ │ ├── TableConverter.java │ │ ├── TableRowConverter.java │ │ ├── TableJoiner.java │ │ ├── SpockitoException.java │ │ ├── Row.java │ │ ├── SpockitoData.java │ │ ├── TableRow.java │ │ ├── DataProvider.java │ │ ├── Data.java │ │ ├── Column.java │ │ ├── Primitives.java │ │ ├── TableData.java │ │ ├── ValueConverter.java │ │ ├── Table.java │ │ ├── SpockitoTableConverter.java │ │ ├── InjectionContext.java │ │ ├── Strings.java │ │ ├── TableDataProvider.java │ │ ├── SpockitoTableJoiner.java │ │ ├── GenericTypes.java │ │ ├── SpockitoTableRow.java │ │ ├── SpockitoTableRowConverter.java │ │ └── SpockitoTable.java │ └── test │ └── java │ └── org │ └── tools4j │ └── spockito │ └── table │ ├── UnescapeTest.java │ └── TableTest.java ├── .github └── workflows │ └── gradle.yml ├── spockito-junit4 ├── src │ ├── test │ │ └── java │ │ │ └── org │ │ │ └── tools4j │ │ │ └── spockito │ │ │ ├── Operation.java │ │ │ ├── UnrollClassDataToFieldsTest.java │ │ │ ├── UnrollClassDataToMethodTest.java │ │ │ ├── UnrollClassDataToConstructorTest.java │ │ │ ├── UnrollMethodDataTest.java │ │ │ ├── SpockitoBeforeAfterTest.java │ │ │ ├── CustomConverterTest.java │ │ │ ├── FaqTest.java │ │ │ └── AdvancedDataTypesTest.java │ └── main │ │ └── java │ │ └── org │ │ └── tools4j │ │ └── spockito │ │ ├── AbstractSpockitoTestRunner.java │ │ ├── MethodLevelFilter.java │ │ ├── UnrolledTestMethod.java │ │ ├── SingleTestMultiRowRunner.java │ │ └── TableRowConverters.java └── README.md ├── gradlew.bat ├── README.md └── gradlew /version.txt: -------------------------------------------------------------------------------- 1 | 2.1-SNAPSHOT 2 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ( 2 | 'spockito-table', 3 | 'spockito-junit4', 4 | 'spockito-junit5') 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .classpath 2 | .gradle 3 | .project 4 | .settings 5 | .idea 6 | bin 7 | build 8 | gradle.properties 9 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tools4j/spockito/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /spockito-junit4-idea-testrun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tools4j/spockito/HEAD/spockito-junit4-idea-testrun.png -------------------------------------------------------------------------------- /spockito-junit5-idea-testrun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tools4j/spockito/HEAD/spockito-junit5-idea-testrun.png -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: java 3 | jdk: 4 | - openjdk8 5 | - openjdk11 6 | 7 | after_success: 8 | - gradle jacocoTestReport coveralls 9 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /spockito-junit5/README.md: -------------------------------------------------------------------------------- 1 | # spockito-junit5 2 | Java JUnit 5.x runner for parameterized tests where the test cases are defined in a table-like manner. 3 | 4 | See [main documentation](https://github.com/tools4j/spockito/blob/master/README.md) for more information. 5 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017-2022 tools4j.org (Marco Terzer) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /etc/LICENSE.template: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017-${year} tools4j.org (Marco Terzer) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /spockito-table/src/main/java/org/tools4j/spockito/table/TableConverter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2017-2022 tools4j.org (Marco Terzer) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package org.tools4j.spockito.table; 25 | 26 | @FunctionalInterface 27 | public interface TableConverter { 28 | Object convert(Table table); 29 | } 30 | -------------------------------------------------------------------------------- /spockito-table/src/main/java/org/tools4j/spockito/table/TableRowConverter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2017-2022 tools4j.org (Marco Terzer) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package org.tools4j.spockito.table; 25 | 26 | @FunctionalInterface 27 | public interface TableRowConverter { 28 | Object convert(TableRow tableRow); 29 | } 30 | -------------------------------------------------------------------------------- /spockito-table/src/main/java/org/tools4j/spockito/table/TableJoiner.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2017-2022 tools4j.org (Marco Terzer) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package org.tools4j.spockito.table; 25 | 26 | public interface TableJoiner { 27 | 28 | JoinBuilder onAllCommonColumns(); 29 | JoinBuilder on(int child, int parent); 30 | JoinBuilder on(String child, String parent); 31 | JoinBuilder on(String common); 32 | 33 | interface JoinBuilder { 34 | JoinBuilder and(int child, int parent); 35 | JoinBuilder and(String child, String parent); 36 | JoinBuilder and(String common); 37 | Table apply(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /spockito-table/src/main/java/org/tools4j/spockito/table/SpockitoException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2017-2022 tools4j.org (Marco Terzer) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package org.tools4j.spockito.table; 25 | 26 | /** 27 | * Exception thrown when spockito fails to inject data for instance due to failed value conversion. 28 | */ 29 | public class SpockitoException extends RuntimeException { 30 | 31 | private static final long serialVersionUID = 1L; 32 | 33 | public SpockitoException(final String message) { 34 | super(message); 35 | } 36 | 37 | public SpockitoException(final String message, final Throwable cause) { 38 | super(message, cause); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /.github/workflows/gradle.yml: -------------------------------------------------------------------------------- 1 | name: Continuous Integration 2 | on: 3 | repository_dispatch: 4 | types: run-commit-tests 5 | push: 6 | branches: 7 | - master 8 | pull_request: 9 | types: [opened, synchronize] 10 | branches: 11 | - master 12 | 13 | env: 14 | GRADLE_OPTS: "-Dorg.gradle.daemon=false" 15 | 16 | jobs: 17 | java-build: 18 | name: Java ${{ matrix.java }} (${{ matrix.os }}) 19 | runs-on: ${{ matrix.os }} 20 | strategy: 21 | fail-fast: false 22 | matrix: 23 | java: [ '8', '11', '17' ] 24 | os: ['ubuntu-latest', 'windows-latest'] 25 | steps: 26 | - name: Checkout code 27 | uses: actions/checkout@v2 28 | - name: Cache Gradle dependencies 29 | uses: actions/cache@v1 30 | with: 31 | path: ~/.gradle/caches 32 | key: ${{ runner.os }}-gradle-caches-${{ hashFiles('**/*.gradle') }} 33 | restore-keys: | 34 | ${{ runner.os }}-gradle-caches- 35 | - name: Cache Gradle wrappers 36 | uses: actions/cache@v1 37 | with: 38 | path: ~/.gradle/wrapper 39 | key: ${{ runner.os }}-gradle-wrapper 40 | - name: Setup java 41 | uses: actions/setup-java@v1 42 | with: 43 | java-version: ${{ matrix.java }} 44 | - name: Build with Gradle 45 | run: ./gradlew 46 | - name: Copy crash logs 47 | id: copy_crash_logs 48 | if: failure() 49 | run: | 50 | echo "::set-output name=dir::build/crash_logs" 51 | ./gradlew copyCrashLogs 52 | - name: Upload crash logs 53 | if: always() && steps.copy_crash_logs.outputs.dir == 'build/crash_logs' 54 | uses: actions/upload-artifact@v1 55 | with: 56 | name: crash-logs-${{ matrix.os }}-java-${{ matrix.java }} 57 | path: ${{ steps.copy_crash_logs.outputs.dir }} 58 | -------------------------------------------------------------------------------- /spockito-table/src/main/java/org/tools4j/spockito/table/Row.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2017-2022 tools4j.org (Marco Terzer) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package org.tools4j.spockito.table; 25 | 26 | import java.lang.annotation.Documented; 27 | import java.lang.annotation.Retention; 28 | import java.lang.annotation.RetentionPolicy; 29 | import java.lang.annotation.Target; 30 | 31 | import static java.lang.annotation.ElementType.ANNOTATION_TYPE; 32 | import static java.lang.annotation.ElementType.FIELD; 33 | import static java.lang.annotation.ElementType.PARAMETER; 34 | 35 | /** 36 | * Annotation for fields or parameters referencing a whole {@link TableRow} of a {@link Table}. If the target type is 37 | * int, the row index will be assigned instead. 38 | */ 39 | @Retention(RetentionPolicy.RUNTIME) 40 | @Target(value = {ANNOTATION_TYPE, FIELD, PARAMETER}) 41 | @Documented 42 | public @interface Row { 43 | } -------------------------------------------------------------------------------- /spockito-junit5/src/main/java/org/tools4j/spockito/jupiter/AggregateTableRow.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2017-2022 tools4j.org (Marco Terzer) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package org.tools4j.spockito.jupiter; 25 | 26 | import org.junit.jupiter.params.aggregator.AggregateWith; 27 | import org.tools4j.spockito.table.TableRow; 28 | 29 | import java.lang.annotation.Documented; 30 | import java.lang.annotation.Retention; 31 | import java.lang.annotation.Target; 32 | 33 | import static java.lang.annotation.ElementType.ANNOTATION_TYPE; 34 | import static java.lang.annotation.ElementType.PARAMETER; 35 | import static java.lang.annotation.RetentionPolicy.RUNTIME; 36 | 37 | /** 38 | * Annotation to reference a whole {@link TableRow} of a {@link TableSource}. 39 | * 40 | *
This is a shorter version equivalent to {@code @AggregateWith(TableRowAggregator.class)}. 41 | */ 42 | @Target({ANNOTATION_TYPE, PARAMETER}) 43 | @Retention(RUNTIME) 44 | @Documented 45 | @AggregateWith(TableRowAggregator.class) 46 | public @interface AggregateTableRow { 47 | } 48 | -------------------------------------------------------------------------------- /spockito-table/src/main/java/org/tools4j/spockito/table/SpockitoData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2017-2022 tools4j.org (Marco Terzer) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package org.tools4j.spockito.table; 25 | 26 | /** 27 | * Class that can be extended and whose {@link Data data} provider elements will be automatically initialised upon 28 | * construction. 29 | * 30 | *
For instance a table can be inlined in a (test) method as follows: 31 | * 32 | *
33 | void printPersons() {
34 | final class Person {
35 | String name;
36 | int age;
37 | }
38 | final class MyData extends SpockitoData {
39 | {@code @TableData}({
40 | "| Name | Age |",
41 | "| Henry | 27 |",
42 | "| Frank | 29 |"
43 | })
44 | {@code List persons;}
45 | }
46 |
47 | final MyData data = new MyData();
48 | data.persons.forEach(person -> System.out.println(person.name + " is " + person.age + " years old"));
49 | }
50 | *
51 | */
52 | public class SpockitoData {
53 |
54 | /**
55 | * Default constructor; invokes {@link SpockitoAnnotations#initData(Object)} with itself.
56 | */
57 | public SpockitoData() {
58 | SpockitoAnnotations.initData(this);
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/spockito-junit5/src/main/java/org/tools4j/spockito/jupiter/SpockitoExtension.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2017-2022 tools4j.org (Marco Terzer)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package org.tools4j.spockito.jupiter;
25 |
26 | import org.junit.jupiter.api.extension.BeforeAllCallback;
27 | import org.junit.jupiter.api.extension.ExtensionContext;
28 | import org.junit.jupiter.api.extension.TestInstancePostProcessor;
29 | import org.tools4j.spockito.table.SpockitoAnnotations;
30 |
31 | /**
32 | * Test extension to initialise {@linkplain org.tools4j.spockito.table.DataProvider data providers} such as fields
33 | * annotated with {@link org.tools4j.spockito.table.Data @Data} or {@link TableSource @TableSource}.
34 | *
35 | * @see SpockitoAnnotations#initData(Object)
36 | * @see SpockitoAnnotations#initStaticData(Class)
37 | */
38 | public class SpockitoExtension implements BeforeAllCallback, TestInstancePostProcessor {
39 |
40 | @Override
41 | public void beforeAll(final ExtensionContext context) {
42 | SpockitoAnnotations.initStaticData(context.getRequiredTestClass());
43 | }
44 |
45 | @Override
46 | public void postProcessTestInstance(final Object testInstance, final ExtensionContext context) {
47 | SpockitoAnnotations.initData(testInstance);
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/spockito-table/src/test/java/org/tools4j/spockito/table/UnescapeTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2017-2022 tools4j.org (Marco Terzer)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package org.tools4j.spockito.table;
25 |
26 | import org.junit.jupiter.api.Test;
27 |
28 | import static org.junit.jupiter.api.Assertions.assertEquals;
29 |
30 | /**
31 | * Unit test for {@link Strings#unescape(String)}
32 | */
33 | public class UnescapeTest {
34 |
35 | @Test
36 | public void shouldUnescape() {
37 | assertEquals(",", Strings.unescape("\\,"));
38 | assertEquals(";", Strings.unescape("\\;"));
39 | assertEquals("|", Strings.unescape("\\|"));
40 | assertEquals("=", Strings.unescape("\\="));
41 | assertEquals("\\", Strings.unescape("\\\\"));
42 | assertEquals("'", Strings.unescape("\\'"));
43 | assertEquals("123|456", Strings.unescape("123\\|456"));
44 | }
45 |
46 | @Test
47 | public void shouldNotUnescape() {
48 | assertEquals("\\blabla", Strings.unescape("\\blabla"));
49 | assertEquals("\\123", Strings.unescape("\\123"));
50 | }
51 |
52 | @Test
53 | public void shouldUnescapeMultiple() {
54 | assertEquals("\\,123|456;\\a\\;\\8bla'\\'xxx", Strings.unescape("\\\\,123\\|456\\;\\a\\\\\\;\\8bla\\'\\\\'xxx"));
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/spockito-table/src/main/java/org/tools4j/spockito/table/TableRow.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2017-2022 tools4j.org (Marco Terzer)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package org.tools4j.spockito.table;
25 |
26 | import java.lang.reflect.Type;
27 | import java.util.Iterator;
28 | import java.util.List;
29 | import java.util.Map;
30 | import java.util.stream.Stream;
31 | import java.util.stream.StreamSupport;
32 |
33 | /**
34 | * Represents a single row of a {@link Table}; cell values are kept as strings but convenience methods exist to convert
35 | * them to a value of any desired type.
36 | */
37 | public interface TableRow extends IterableA {@code DataProvider} can be registered via the {@link Data @Data} annotation. 31 | * 32 | *
Implementations must provide a no-args constructor. 33 | */ 34 | public interface DataProvider { 35 | 36 | /** 37 | * Returns true if the data provider is applicable for the given injection context. The method returns true by 38 | * default but some implementations may return false in certain circumstances for instance to prevent double 39 | * injection of data when running methods as tests. 40 | * 41 | * @param context the injection context 42 | * @return true by default 43 | */ 44 | default boolean applicable(final InjectionContext context) { 45 | return true; 46 | } 47 | 48 | /** 49 | * Provides the data to be injected to a field or to method parameters. 50 | * 51 | * @param context the current injection context; never {@code null} 52 | * @return the data to inject; never {@code null} 53 | */ 54 | Object provideData(InjectionContext context); 55 | 56 | } 57 | -------------------------------------------------------------------------------- /spockito-junit4/src/test/java/org/tools4j/spockito/Operation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2017-2022 tools4j.org (Marco Terzer) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package org.tools4j.spockito; 25 | 26 | public enum Operation { 27 | Add { 28 | public int evaluate(final int operand1, final int operand2) { 29 | return operand1 + operand2; 30 | } 31 | @Override 32 | public int neutralSecondOperand() { 33 | return 0; 34 | } 35 | }, 36 | Subtract { 37 | public int evaluate(final int operand1, final int operand2) { 38 | return operand1 - operand2; 39 | } 40 | @Override 41 | public int neutralSecondOperand() { 42 | return 0; 43 | } 44 | }, 45 | Multiply { 46 | public int evaluate(final int operand1, final int operand2) { 47 | return operand1 * operand2; 48 | } 49 | @Override 50 | public int neutralSecondOperand() { 51 | return 1; 52 | } 53 | }, 54 | Divide { 55 | public int evaluate(final int operand1, final int operand2) { 56 | return operand1 / operand2; 57 | } 58 | @Override 59 | public int neutralSecondOperand() { 60 | return 1; 61 | } 62 | }; 63 | abstract public int evaluate(int operand1, int operand2); 64 | abstract public int neutralSecondOperand(); 65 | } 66 | -------------------------------------------------------------------------------- /spockito-junit5/src/test/java/org/tools4j/spockito/jupiter/Operation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2017-2022 tools4j.org (Marco Terzer) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package org.tools4j.spockito.jupiter; 25 | 26 | public enum Operation { 27 | Add { 28 | public int evaluate(final int operand1, final int operand2) { 29 | return operand1 + operand2; 30 | } 31 | @Override 32 | public int neutralSecondOperand() { 33 | return 0; 34 | } 35 | }, 36 | Subtract { 37 | public int evaluate(final int operand1, final int operand2) { 38 | return operand1 - operand2; 39 | } 40 | @Override 41 | public int neutralSecondOperand() { 42 | return 0; 43 | } 44 | }, 45 | Multiply { 46 | public int evaluate(final int operand1, final int operand2) { 47 | return operand1 * operand2; 48 | } 49 | @Override 50 | public int neutralSecondOperand() { 51 | return 1; 52 | } 53 | }, 54 | Divide { 55 | public int evaluate(final int operand1, final int operand2) { 56 | return operand1 / operand2; 57 | } 58 | @Override 59 | public int neutralSecondOperand() { 60 | return 1; 61 | } 62 | }; 63 | abstract public int evaluate(int operand1, int operand2); 64 | abstract public int neutralSecondOperand(); 65 | } 66 | -------------------------------------------------------------------------------- /spockito-table/src/main/java/org/tools4j/spockito/table/Data.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2017-2022 tools4j.org (Marco Terzer) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package org.tools4j.spockito.table; 25 | 26 | import java.lang.annotation.Documented; 27 | import java.lang.annotation.Retention; 28 | import java.lang.annotation.RetentionPolicy; 29 | import java.lang.annotation.Target; 30 | 31 | import static java.lang.annotation.ElementType.ANNOTATION_TYPE; 32 | import static java.lang.annotation.ElementType.FIELD; 33 | import static java.lang.annotation.ElementType.METHOD; 34 | import static java.lang.annotation.ElementType.PARAMETER; 35 | 36 | /** 37 | * {@code @Data} is an annotation that is used to register {@linkplain DataProvider data providers} for the annotated 38 | * field, method or method parameter. 39 | * 40 | *
{@code @Data} may also be used as a meta-annotation in order to create a custom composed annotation 41 | * that inherits the semantics of {@code @Data}. 42 | * 43 | *
{@code @Data} are injected via {@link SpockitoAnnotations#initData(Object)} or when creating subclass instances of 44 | * {@link SpockitoData}. 45 | */ 46 | @Target({ANNOTATION_TYPE, METHOD, FIELD, PARAMETER}) 47 | @Retention(RetentionPolicy.RUNTIME) 48 | @Documented 49 | public @interface Data { 50 | /** 51 | * The type of {@link DataProvider} to be used. 52 | * @return the data provider type 53 | */ 54 | Class extends DataProvider> value(); 55 | } 56 | -------------------------------------------------------------------------------- /spockito-table/src/main/java/org/tools4j/spockito/table/Column.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2017-2022 tools4j.org (Marco Terzer) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package org.tools4j.spockito.table; 25 | 26 | import java.lang.annotation.Documented; 27 | import java.lang.annotation.Retention; 28 | import java.lang.annotation.RetentionPolicy; 29 | import java.lang.annotation.Target; 30 | 31 | import static java.lang.annotation.ElementType.ANNOTATION_TYPE; 32 | import static java.lang.annotation.ElementType.FIELD; 33 | import static java.lang.annotation.ElementType.PARAMETER; 34 | 35 | /** 36 | * Annotation for fields or parameters referencing a column of a {@link TableRow}. Fields need only be annotated if the 37 | * field name differs from the column name. Parameters need to be annotated if the index does not match the column 38 | * index in the table. 39 | * 40 | *
{@code @Column} may also be used as a meta-annotation in order to create a custom composed annotation 41 | * that inherits the semantics of {@code @Column}. 42 | */ 43 | @Retention(RetentionPolicy.RUNTIME) 44 | @Target(value = {ANNOTATION_TYPE, FIELD, PARAMETER}) 45 | @Documented 46 | public @interface Column { 47 | /** 48 | * Returns the name to reference a column in the table. The value can be omitted when annotating a field whose name 49 | * matches the column name. 50 | * 51 | * @return the column name, empty to match field name 52 | */ 53 | String value() default ""; 54 | } -------------------------------------------------------------------------------- /spockito-junit5/src/main/java/org/tools4j/spockito/jupiter/TableValueConverter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2017-2022 tools4j.org (Marco Terzer) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package org.tools4j.spockito.jupiter; 25 | 26 | import org.junit.jupiter.api.extension.ParameterContext; 27 | import org.junit.jupiter.params.converter.ArgumentConversionException; 28 | import org.junit.jupiter.params.converter.ArgumentConverter; 29 | import org.tools4j.spockito.table.SpockitoValueConverter; 30 | import org.tools4j.spockito.table.TableData; 31 | import org.tools4j.spockito.table.ValueConverter; 32 | 33 | import java.lang.reflect.Executable; 34 | import java.lang.reflect.Parameter; 35 | 36 | public class TableValueConverter implements ArgumentConverter { 37 | 38 | @Override 39 | public Object convert(final Object source, final ParameterContext context) throws ArgumentConversionException { 40 | final Parameter parameter = context.getParameter(); 41 | final ValueConverter valueConverter = valueConverter(context); 42 | return valueConverter.convert(parameter.getType(), parameter.getParameterizedType(), String.valueOf(source)); 43 | } 44 | 45 | static ValueConverter valueConverter(final ParameterContext context) { 46 | final Executable executable = context.getDeclaringExecutable(); 47 | final TableData tableSource = executable.getAnnotation(TableData.class); 48 | final Class extends ValueConverter> valueConverterClass = tableSource != null ? tableSource.valueConverter() : 49 | SpockitoValueConverter.class; 50 | return ValueConverter.create(valueConverterClass); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /spockito-junit5/src/main/java/org/tools4j/spockito/jupiter/TableRowAggregator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * The MIT License (MIT) 3 | * 4 | * Copyright (c) 2017-2022 tools4j.org (Marco Terzer) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package org.tools4j.spockito.jupiter; 25 | 26 | import org.junit.jupiter.api.extension.ParameterContext; 27 | import org.junit.jupiter.params.aggregator.ArgumentsAccessor; 28 | import org.junit.jupiter.params.aggregator.ArgumentsAggregationException; 29 | import org.junit.jupiter.params.aggregator.ArgumentsAggregator; 30 | import org.tools4j.spockito.table.Table; 31 | import org.tools4j.spockito.table.TableRow; 32 | import org.tools4j.spockito.table.ValueConverter; 33 | 34 | import java.lang.reflect.Parameter; 35 | 36 | import static org.tools4j.spockito.jupiter.TableValueConverter.valueConverter; 37 | 38 | /** 39 | * Aggregator used by {@linkplain AggregateTableRow @AggregateTableRow} or if used with the 40 | * {@linkplain org.junit.jupiter.params.aggregator.AggregateWith @AggregateWith} annotation. 41 | * 42 | *
The annotated method parameter references a whole {@link TableRow} of a {@link Table}.
43 | */
44 | public class TableRowAggregator implements ArgumentsAggregator {
45 |
46 | @Override
47 | public Object aggregateArguments(final ArgumentsAccessor accessor, final ParameterContext context) throws ArgumentsAggregationException {
48 | final Parameter parameter = context.getParameter();
49 | final ValueConverter valueConverter = valueConverter(context);
50 | final TableRow tableRow = accessor.get(context.getIndex(), TableRow.class);
51 | return tableRow.to(parameter.getType(), parameter.getParameterizedType(), valueConverter);
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/spockito-table/src/main/java/org/tools4j/spockito/table/Primitives.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2017-2022 tools4j.org (Marco Terzer)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package org.tools4j.spockito.table;
25 |
26 | /**
27 | * Contains static helper methods related to primitive types.
28 | */
29 | enum Primitives {
30 | ;
31 | /**
32 | * Returns the boxing type given a primitive type.
33 | *
34 | * @param type a primitive type such as {@code int.class}
35 | * @param The implementation is based on {@link TableDataProvider} but annotated {@linkplain Testable testable} methods are
44 | * not invoked. The test framework invokes testable methods using {@link TableArgumentsProvider}.
45 | */
46 | public class TableSourceDataProvider extends TableDataProvider {
47 |
48 | public static final TableSourceDataProvider DEFAULT_INSTANCE = new TableSourceDataProvider();
49 |
50 | public TableSourceDataProvider() {
51 | super(TableSourceDataProvider::table, TableSourceDataProvider::valueConverter);
52 | }
53 |
54 | private static Table table(final InjectionContext injectionContext) {
55 | final TableSource tableSource = injectionContext.annotatedElement().getAnnotation(TableSource.class);
56 | return Table.parse(tableSource.value());
57 | }
58 |
59 | private static Class extends ValueConverter> valueConverter(final InjectionContext injectionContext) {
60 | final TableSource tableSource = injectionContext.annotatedElement().getAnnotation(TableSource.class);
61 | return tableSource.valueConverter();
62 | }
63 |
64 | @Override
65 | public boolean applicable(final InjectionContext context) {
66 | if (context.phase() == Phase.INIT) {
67 | final AnnotatedElement element = context.annotatedElement();
68 | if (element instanceof Method) {
69 | final Testable testable = annotationDirectOrMeta(element, Testable.class);
70 | //invoke test methods during TEST phase
71 | return testable == null;
72 | }
73 | }
74 | return true;
75 | }
76 |
77 | @Override
78 | protected TableRowConverter tableRowConverter(final InjectionContext context,
79 | final Parameter parameter,
80 | final int index,
81 | final ValueConverter valueConverter) {
82 | return TableRowConverters.create(context, parameter, index, valueConverter);
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/spockito-table/src/main/java/org/tools4j/spockito/table/ValueConverter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2017-2022 tools4j.org (Marco Terzer)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package org.tools4j.spockito.table;
25 |
26 | import java.lang.reflect.Type;
27 | import java.util.Collection;
28 | import java.util.Map;
29 |
30 | /**
31 | * Handles the conversion of string values to arbitrary target types; supports conversion into generic types such as
32 | * {@code List
41 | * | ColumnA | ColumnB | ColumnC |
42 | * |-----------|-----------|-----------|
43 | * | value_1_A | value_1_B | value_1_C |
44 | * | value_2_A | value_2_B | value_2_C |
45 | * etc...
46 | *
47 | * The separator row after the column headers is optional and = instead of - can be used. Separator rows can be
48 | * placed anywhere in the table and are ignored when the table is parsed.
49 | */
50 | @Target({ANNOTATION_TYPE, METHOD, FIELD, PARAMETER})
51 | @Retention(RUNTIME)
52 | @Documented
53 | @Inherited
54 | @Data(TableDataProvider.class)
55 | public @interface TableData {
56 | /**
57 | * Test case data for parameterized tests structured as follows:
58 | *
59 | * | ColumnA | ColumnB | ColumnC |
60 | * |-----------|-----------|-----------|
61 | * | value_1_A | value_1_B | value_1_C |
62 | * | value_2_A | value_2_B | value_2_C |
63 | * etc...
64 | *
65 | * The separator row after the column headers is optional and = instead of - can be used. Separator rows can be
66 | * placed anywhere in the table and are ignored when the table is parsed.
67 | *
68 | * @return An array of strings represented as table data; string[0] contains the header
69 | * row with column names
70 | */
71 | String[] value();
72 |
73 | /**
74 | * Converter to use for individual values; conversion is done purely based on the value type.
75 | * Returned classes must have a public no-argument constructor.
76 | *
77 | * @return the value converter to use
78 | * @see SpockitoValueConverter
79 | */
80 | Class extends ValueConverter> valueConverter() default SpockitoValueConverter.class;
81 | }
82 |
--------------------------------------------------------------------------------
/spockito-junit5/src/main/java/org/tools4j/spockito/jupiter/TableSource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2017-2022 tools4j.org (Marco Terzer)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package org.tools4j.spockito.jupiter;
25 |
26 | import org.junit.jupiter.params.provider.ArgumentsSource;
27 | import org.tools4j.spockito.table.Data;
28 | import org.tools4j.spockito.table.SpockitoValueConverter;
29 | import org.tools4j.spockito.table.ValueConverter;
30 |
31 | import java.lang.annotation.Documented;
32 | import java.lang.annotation.Retention;
33 | import java.lang.annotation.Target;
34 |
35 | import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
36 | import static java.lang.annotation.ElementType.FIELD;
37 | import static java.lang.annotation.ElementType.METHOD;
38 | import static java.lang.annotation.ElementType.PARAMETER;
39 | import static java.lang.annotation.RetentionPolicy.RUNTIME;
40 |
41 | /**
42 | * Source for {@link org.junit.jupiter.params.ParameterizedTest ParameterizedTest} data declared in a table like
43 | * structure as follows:
44 | *
45 | * | ColumnA | ColumnB | ColumnC |
46 | * |-----------|-----------|-----------|
47 | * | value_1_A | value_1_B | value_1_C |
48 | * | value_2_A | value_2_B | value_2_C |
49 | * etc...
50 | *
51 | * The separator row after the column headers is optional and = instead of - can be used. Separator rows can be
52 | * placed anywhere in the table and are ignored when the table is parsed.
53 | */
54 | @Target({ANNOTATION_TYPE, METHOD, FIELD, PARAMETER})
55 | @Retention(RUNTIME)
56 | @Documented
57 | @ArgumentsSource(TableArgumentsProvider.class)
58 | @Data(TableSourceDataProvider.class)
59 | public @interface TableSource {
60 | /**
61 | * Test case data for parameterized tests structured as follows:
62 | *
63 | * | ColumnA | ColumnB | ColumnC |
64 | * |-----------|-----------|-----------|
65 | * | value_1_A | value_1_B | value_1_C |
66 | * | value_2_A | value_2_B | value_2_C |
67 | * etc...
68 | *
69 | * The separator row after the column headers is optional and = instead of - can be used. Separator rows can be
70 | * placed anywhere in the table and are ignored when the table is parsed.
71 | *
72 | * @return An array of strings represented as table data; string[0] contains the header
73 | * row with column names
74 | */
75 | String[] value();
76 |
77 | /**
78 | * Converter to use for individual values; conversion is done purely based on the value type.
79 | * Returned classes must have a public no-argument constructor.
80 | *
81 | * @return the value converter to use
82 | * @see SpockitoValueConverter
83 | */
84 | Class extends ValueConverter> valueConverter() default SpockitoValueConverter.class;
85 | }
86 |
--------------------------------------------------------------------------------
/spockito-junit4/src/test/java/org/tools4j/spockito/UnrollMethodDataTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2017-2022 tools4j.org (Marco Terzer)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package org.tools4j.spockito;
25 |
26 | import org.junit.Assert;
27 | import org.junit.Test;
28 | import org.junit.runner.RunWith;
29 |
30 | import java.time.LocalDate;
31 |
32 | @RunWith(Spockito.class)
33 | public class UnrollMethodDataTest {
34 |
35 | @Test
36 | @Spockito.Unroll({
37 | "| Last Name | First Name |",
38 | "| Jones | David |",
39 | "| Jensen | Astrid |"
40 | })
41 | public void testUnrollNames(String lastName, String firstName) {
42 | Assert.assertTrue("Last Name should start with J", lastName.startsWith("J"));
43 | Assert.assertTrue("First Name should end with id", firstName.endsWith("id"));
44 | }
45 |
46 | @Test
47 | @Spockito.Unroll({
48 | "| Name | Year | Birthday |",
49 | "|-------|------|------------|",
50 | "| Henry | 1981 | 1981-11-28 |",
51 | "| Jessy | 1965 | 1965-03-28 |"
52 | })
53 | @Spockito.Name("[{row}]: Name={0}")
54 | public void testUnrollBirthdays(String name, int year, LocalDate birthday) {
55 | Assert.assertEquals("Name should have 5 characters", 5, name.length());
56 | Assert.assertTrue("Year is before 1990", 1990 > year);
57 | Assert.assertEquals("Day is 28th", 28, birthday.getDayOfMonth());
58 | Assert.assertEquals("Year is consistent with birthday", year, birthday.getYear());
59 | }
60 |
61 | @Test
62 | @Spockito.Unroll({
63 | "| Name | Year | Birthday |",
64 | "|-------|------|------------|",
65 | "| Henry | 1981 | 1981-11-28 |",
66 | "| Jessy | 1965 | 1965-03-28 |"
67 | })
68 | @Spockito.Name("[{row}]: Name={0}")
69 | public void testUnrollNameAndYearOnly(String name, int year) {
70 | Assert.assertEquals("Name should have 5 characters", 5, name.length());
71 | Assert.assertTrue("Year is before 1990", 1990 > year);
72 | }
73 |
74 | @Test
75 | @Spockito.Unroll({
76 | "| Object | Vertices | Angle sum |",
77 | "|==========|==========|===========|",
78 | "| Triangle | 3 | 180 |",
79 | "| Square | 4 | 360 |",
80 | "| Pentagon | 5 | 540 |",
81 | "|----------|----------|-----------|",
82 | })
83 | @Spockito.Name("[{Object}]: ({Vertices}-2)*180 = {Angle sum}")
84 | public void testUnrollAngularSums(@Spockito.Ref("Vertices") int n,
85 | @Spockito.Ref("Angle sum") int degrees,
86 | @Spockito.Ref("Object") String name) {
87 | Assert.assertTrue("There should be 3 or more vertices", 3 <= n);
88 | Assert.assertEquals("Angular sum is wrong for: " + name, degrees, (n-2)*180);
89 | }
90 | }
--------------------------------------------------------------------------------
/spockito-junit5/src/test/java/org/tools4j/spockito/jupiter/TableSourceTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2017-2022 tools4j.org (Marco Terzer)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package org.tools4j.spockito.jupiter;
25 |
26 | import org.junit.jupiter.params.ParameterizedTest;
27 | import org.tools4j.spockito.table.Column;
28 |
29 | import java.time.LocalDate;
30 |
31 | import static org.junit.jupiter.api.Assertions.assertEquals;
32 | import static org.junit.jupiter.api.Assertions.assertTrue;
33 |
34 | public class TableSourceTest {
35 |
36 | @TableSource({
37 | "| Last Name | First Name |",
38 | "| Jones | David |",
39 | "| Jensen | Astrid |"
40 | })
41 | @ParameterizedTest(name = "[{index}] {1} {0}")
42 | public void testUnrollNames(String lastName, String firstName) {
43 | assertTrue(lastName.startsWith("J"), "Last Name should start with J");
44 | assertTrue(firstName.endsWith("id"), "First Name should end with id");
45 | }
46 |
47 | @TableSource({
48 | "| Name | Year | Birthday |",
49 | "|-------|------|------------|",
50 | "| Henry | 1981 | 1981-11-28 |",
51 | "| Jessy | 1965 | 1965-03-28 |"
52 | })
53 | @ParameterizedTest(name = "[{index}] {0}")
54 | public void testUnrollBirthdays(String name, int year, LocalDate birthday) {
55 | assertEquals(5, name.length(), "Name should have 5 characters");
56 | assertTrue(1990 > year, "Year is before 1990");
57 | assertEquals(28, birthday.getDayOfMonth(), "Day is 28th");
58 | assertEquals(year, birthday.getYear(), "Year is consistent with birthday");
59 | }
60 |
61 | @TableSource({
62 | "| Name | Year | Birthday |",
63 | "|-------|------|------------|",
64 | "| Henry | 1981 | 1981-11-28 |",
65 | "| Jessy | 1965 | 1965-03-28 |"
66 | })
67 | @ParameterizedTest(name = "[{index}] {0}")
68 | public void testUnrollNameAndYearOnly(String name, int year) {
69 | assertEquals(5, name.length(), "Name should have 5 characters");
70 | assertTrue(1990 > year, "Year is before 1990");
71 | }
72 |
73 | @TableSource({
74 | "| Object | Vertices | Angle sum |",
75 | "|==========|==========|===========|",
76 | "| Triangle | 3 | 180 |",
77 | "| Square | 4 | 360 |",
78 | "| Pentagon | 5 | 540 |",
79 | "|----------|----------|-----------|",
80 | })
81 | @ParameterizedTest(name = "{2}: ({0}-2)*180 = {1}")
82 | public void testUnrollAngularSums(@Column("Vertices") int n,
83 | @Column("Angle sum") int degrees,
84 | @Column("Object") String name) {
85 | assertTrue(3 <= n, "There should be 3 or more vertices");
86 | assertEquals(degrees, (n-2)*180, "Angular sum is wrong for: " + name);
87 | }
88 | }
--------------------------------------------------------------------------------
/spockito-junit5/src/main/java/org/tools4j/spockito/jupiter/TableSourceDataProvider.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2017-2022 tools4j.org (Marco Terzer)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package org.tools4j.spockito.jupiter;
25 |
26 | import org.junit.platform.commons.annotation.Testable;
27 | import org.tools4j.spockito.table.InjectionContext;
28 | import org.tools4j.spockito.table.InjectionContext.Phase;
29 | import org.tools4j.spockito.table.Table;
30 | import org.tools4j.spockito.table.TableDataProvider;
31 | import org.tools4j.spockito.table.TableRowConverter;
32 | import org.tools4j.spockito.table.ValueConverter;
33 |
34 | import java.lang.reflect.AnnotatedElement;
35 | import java.lang.reflect.Method;
36 | import java.lang.reflect.Parameter;
37 |
38 | import static org.tools4j.spockito.table.SpockitoAnnotations.annotationDirectOrMeta;
39 |
40 | /**
41 | * Provides values defined by a {@link TableSource @TableSource} annotation.
42 | *
43 | * > rows = new ArrayList<>();
118 | for (int i = 0; i < childRows; i++) {
119 | final TableRow row = child.getRow(i);
120 | if (matcher.test(row)) {
121 | rows.add(row.toList());
122 | }
123 | }
124 | return new SpockitoTable(child.getColumnNames(), rows);
125 | }
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/spockito-junit4/src/main/java/org/tools4j/spockito/TableRowConverters.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2017-2022 tools4j.org (Marco Terzer)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package org.tools4j.spockito;
25 |
26 | import org.tools4j.spockito.Spockito.Ref;
27 | import org.tools4j.spockito.table.Data;
28 | import org.tools4j.spockito.table.InjectionContext;
29 | import org.tools4j.spockito.table.InjectionContext.Phase;
30 | import org.tools4j.spockito.table.SpockitoTableRowConverter;
31 | import org.tools4j.spockito.table.TableRow;
32 | import org.tools4j.spockito.table.TableRowConverter;
33 | import org.tools4j.spockito.table.ValueConverter;
34 |
35 | import java.lang.reflect.AnnotatedElement;
36 | import java.lang.reflect.Executable;
37 | import java.lang.reflect.Field;
38 | import java.lang.reflect.Parameter;
39 | import java.lang.reflect.Type;
40 |
41 | import static org.tools4j.spockito.Spockito.fieldRefOrName;
42 | import static org.tools4j.spockito.Spockito.parameterRefOrNameOrNull;
43 | import static org.tools4j.spockito.table.SpockitoAnnotations.annotationDirectOrMeta;
44 |
45 | /**
46 | * Similar to the converters created by the factory methods in {@link TableRowConverter} but this time the parameters or
47 | * fields can be annotated to override the default name or index.
48 | */
49 | enum TableRowConverters {
50 | ;
51 | static TableRowConverter create(final InjectionContext context, final Parameter parameter, final int index, final ValueConverter valueConverter) {
52 | final TableRowConverter special = specialRefConverterOrNull(parameter.getAnnotation(Ref.class),
53 | parameter.getType(), parameter.getParameterizedType(), valueConverter);
54 | if (special != null) {
55 | return special;
56 | }
57 | return new SpockitoTableRowConverter(dataSubContextOrNull(context, parameter), parameter,
58 | parameterRefOrNameOrNull(parameter), index, parameter.getType(), parameter.getParameterizedType(),
59 | valueConverter);
60 | }
61 |
62 | static TableRowConverter create(final Field field, final ValueConverter valueConverter) {
63 | final TableRowConverter special = specialRefConverterOrNull(field.getAnnotation(Ref.class), field.getType(),
64 | field.getGenericType(), valueConverter);
65 | if (special != null) {
66 | return special;
67 | }
68 | return new SpockitoTableRowConverter(null, field, fieldRefOrName(field), -1, field.getType(),
69 | field.getGenericType(), valueConverter);
70 | }
71 |
72 | private static TableRowConverter specialRefConverterOrNull(final Ref ref, final Class> type, final Type genericType, final ValueConverter valueConverter) {
73 | if (ref != null) {
74 | if (Ref.ALL_COLUMNS.equals(ref.value())) {
75 | return tableRow -> valueConverter.convert(type, genericType, tableRow.toMap().toString());
76 | }
77 | if (Ref.ROW_INDEX.equals(ref.value())) {
78 | return tableRow -> Integer.toString(tableRow.getRowIndex());
79 | }
80 | }
81 | return null;
82 | }
83 |
84 | static Object[] convert(final TableRow tableRow, final Executable executable, final ValueConverter valueConverter) {
85 | final Parameter[] parameters = executable.getParameters();
86 | final Object[] values = new Object[parameters.length];
87 | for (int i = 0; i < values.length; i++) {
88 | values[i] = create(null, parameters[i], i, valueConverter).convert(tableRow);
89 | }
90 | return values;
91 | }
92 |
93 | static Object[] convert(final TableRow tableRow, final Field[] fields, final ValueConverter valueConverter) {
94 | final Object[] values = new Object[fields.length];
95 | for (int i = 0; i < values.length; i++) {
96 | values[i] = create(fields[i], valueConverter).convert(tableRow);
97 | }
98 | return values;
99 | }
100 |
101 | private static InjectionContext dataSubContextOrNull(final InjectionContext context,
102 | final AnnotatedElement annotatedElement) {
103 | final Data data = annotationDirectOrMeta(annotatedElement, Data.class);
104 | if (data != null) {
105 | return InjectionContext.create(context == null ? Phase.TEST : context.phase(), annotatedElement);
106 | }
107 | return null;
108 | }
109 |
110 | }
111 |
--------------------------------------------------------------------------------
/spockito-table/src/main/java/org/tools4j/spockito/table/GenericTypes.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2017-2022 tools4j.org (Marco Terzer)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package org.tools4j.spockito.table;
25 |
26 | import java.lang.reflect.GenericArrayType;
27 | import java.lang.reflect.ParameterizedType;
28 | import java.lang.reflect.Type;
29 | import java.lang.reflect.WildcardType;
30 | import java.util.List;
31 | import java.util.Properties;
32 |
33 | import static java.util.Objects.requireNonNull;
34 |
35 | /**
36 | * Contains static helper methods to inspect and specify generic types.
37 | */
38 | public enum GenericTypes {
39 | ;
40 | public interface ActualType {
41 | Class> rawType();
42 | Type genericType();
43 |
44 | static ActualType create(final Class> rawType, final Type genericType) {
45 | requireNonNull(rawType);
46 | requireNonNull(genericType);
47 | return new ActualType() {
48 | @Override
49 | public Class> rawType() {
50 | return rawType;
51 | }
52 |
53 | @Override
54 | public Type genericType() {
55 | return genericType;
56 | }
57 |
58 | @Override
59 | public String toString() {
60 | return "ActualType{rawType=" + rawType + ", genericType=" + genericType + "}";
61 | }
62 | };
63 | }
64 | }
65 |
66 | public static ActualType actualTypeForTypeParam(final Type type, final int paramIndex, final int paramCount) {
67 | if (type instanceof ParameterizedType) {
68 | final Type[] actualTypeArgs = ((ParameterizedType) type).getActualTypeArguments();
69 | if (actualTypeArgs.length == paramCount) {
70 | Type actualType = actualTypeArgs[paramIndex];
71 | if (actualType instanceof WildcardType) {
72 | final Type[] bounds = ((WildcardType) actualType).getUpperBounds();
73 | if (bounds.length == 1) {
74 | actualType = bounds[0];
75 | }
76 | }
77 | if (actualType instanceof Class) {
78 | return ActualType.create((Class>) actualType, actualType);
79 | }
80 | if (actualType instanceof ParameterizedType) {
81 | final ParameterizedType parameterizedType = (ParameterizedType)actualType;
82 | if (parameterizedType.getRawType() instanceof Class) {
83 | return ActualType.create((Class>)parameterizedType.getRawType(), parameterizedType);
84 | }
85 | }
86 | }
87 | }
88 | if (Properties.class.equals(type) && paramCount == 2) {
89 | return ActualType.create(String.class, String.class);
90 | }
91 | throw new IllegalArgumentException("Could not derive actual generic type [" + paramIndex + "] for " + type);
92 | }
93 |
94 | public static ActualType genericComponentType(final Class> arrayType, final Type genericType) {
95 | final Class> componentType = arrayType.getComponentType();
96 | if (componentType == null) {
97 | throw new IllegalArgumentException("Must be an array type: " + arrayType);
98 | }
99 | if (genericType instanceof GenericArrayType) {
100 | return ActualType.create(componentType, ((GenericArrayType)genericType).getGenericComponentType());
101 | }
102 | return ActualType.create(componentType, componentType);
103 | }
104 |
105 | public static ParameterizedType genericListType(final Type listElementType) {
106 | requireNonNull(listElementType);
107 | return new ParameterizedType() {
108 | @Override
109 | public Type[] getActualTypeArguments() {
110 | return new Type[]{listElementType};
111 | }
112 | @Override
113 | public Type getRawType() {
114 | return List.class;
115 | }
116 | @Override
117 | public Type getOwnerType() {
118 | return null;
119 | }
120 | @Override
121 | public String toString() {
122 | return List.class.getName() + "<" + listElementType + ">";
123 | }
124 | };
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/spockito-junit4/src/test/java/org/tools4j/spockito/FaqTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2017-2022 tools4j.org (Marco Terzer)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package org.tools4j.spockito;
25 |
26 | import org.junit.AfterClass;
27 | import org.junit.Assert;
28 | import org.junit.BeforeClass;
29 | import org.junit.Test;
30 | import org.junit.runner.RunWith;
31 |
32 | import java.math.BigInteger;
33 | import java.util.concurrent.atomic.AtomicInteger;
34 |
35 | @RunWith(Spockito.class)
36 | public class FaqTest {
37 |
38 | private static final AtomicInteger SPECIAL_STRING_COUNT = new AtomicInteger();
39 |
40 | @BeforeClass
41 | public static void initClass() {
42 | SPECIAL_STRING_COUNT.set(0);
43 | }
44 |
45 | @AfterClass
46 | public static void assertSpecialStringTestCount() {
47 | if (SPECIAL_STRING_COUNT.get() > 0) {
48 | Assert.assertEquals("Expected 4 runs of testSpecialStrings()", 4, SPECIAL_STRING_COUNT.get());
49 | }
50 | }
51 |
52 | /** Example related to issue #1 */
53 | @Test(expected = IllegalArgumentException.class)
54 | @Spockito.Unroll({
55 | "|Input|",
56 | "||",
57 | "|''|",
58 | "|'|",
59 | "|' '|"
60 | })
61 | @Spockito.Name("[row]: Input=<{Input}>")
62 | public void testSpecialStrings(String input) {
63 | SPECIAL_STRING_COUNT.incrementAndGet();
64 | if (input.isEmpty()) throw new IllegalArgumentException("empty");
65 | if (input.trim().isEmpty()) throw new IllegalArgumentException("spaces");
66 | if (input.equals("'")) throw new IllegalArgumentException("single quote");
67 | Assert.fail("should have thrown an exception");
68 | }
69 |
70 | /** Example related to issue #2 */
71 | @Test
72 | @Spockito.Unroll({
73 | "|Input|Location ID|Event ID|",
74 | "|123\\|321|123|321|",
75 | "|123%7c321|123|321|"
76 | })
77 | public void testWithPipe(String input, BigInteger locationId, BigInteger eventId) {
78 | Assert.assertTrue(!input.contains("\\"));
79 | Assert.assertTrue(input.contains("|") || input.startsWith("123") && input.endsWith("321"));
80 | }
81 |
82 | /** Example related to issue #6 */
83 | @Test
84 | @Spockito.Unroll({
85 | "|Character|",
86 | "|'\u0001'|",
87 | "|'\u0002'|",
88 | "|'\u0003'|",
89 | "|'\u0004'|",
90 | "|'\u0005'|",
91 | "|'\u0006'|",
92 | "|'\u0007'|",
93 | "|'\u0008'|",
94 | "|'\u0009'|",
95 | "|'\u000b'|",
96 | "|'\u000c'|",
97 | "|'\u000e'|",
98 | "|'\u000f'|",
99 | "|'\u0010'|",
100 | "|'\u0011'|",
101 | "|'\u0012'|",
102 | "|'\u0013'|",
103 | "|'\u0014'|",
104 | "|'\u0015'|",
105 | "|'\u0016'|",
106 | "|'\u0017'|",
107 | "|'\u0018'|",
108 | "|'\u0019'|",
109 | "|'\u001a'|",
110 | "|'\u001b'|",
111 | "|'\u001c'|",
112 | "|'\u001d'|",
113 | "|'\u001e'|",
114 | "|'\u001f'|",
115 | "|'\u0020'|"
116 | })
117 | public void testNonPrintableOrWhitespaceChar(char ch) {
118 | Assert.assertTrue("Char should be non-printable or whitespace", ch <= '\u0021');
119 | }
120 |
121 | /** Example related to issue #6 */
122 | @Test
123 | @Spockito.Unroll({
124 | "|Character|",
125 | "|'\u0001'|",
126 | "|'\u0002'|",
127 | "|'\u0003'|",
128 | "|'\u0004'|",
129 | "|'\u0005'|",
130 | "|'\u0006'|",
131 | "|'\u0007'|",
132 | "|'\u0008'|",
133 | "|'\u0009'|",
134 | "|'\u000b'|",
135 | "|'\u000c'|",
136 | "|'\u000e'|",
137 | "|'\u000f'|",
138 | "|'\u0010'|",
139 | "|'\u0011'|",
140 | "|'\u0012'|",
141 | "|'\u0013'|",
142 | "|'\u0014'|",
143 | "|'\u0015'|",
144 | "|'\u0016'|",
145 | "|'\u0017'|",
146 | "|'\u0018'|",
147 | "|'\u0019'|",
148 | "|'\u001a'|",
149 | "|'\u001b'|",
150 | "|'\u001c'|",
151 | "|'\u001d'|",
152 | "|'\u001e'|",
153 | "|'\u001f'|",
154 | "|'\u0020'|"
155 | })
156 | public void testNonPrintableOrWhitespaceCharsAsString(String s) {
157 | Assert.assertEquals("String length should be 1", 1, s.length());
158 | Assert.assertTrue("Char should be non-printable or whitespace", s.charAt(0) <= '\u0021');
159 | }
160 |
161 | }
162 |
--------------------------------------------------------------------------------
/spockito-junit4/src/test/java/org/tools4j/spockito/AdvancedDataTypesTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License (MIT)
3 | *
4 | * Copyright (c) 2017-2022 tools4j.org (Marco Terzer)
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in all
14 | * copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | * SOFTWARE.
23 | */
24 | package org.tools4j.spockito;
25 |
26 | import org.junit.Assert;
27 | import org.junit.Test;
28 | import org.junit.runner.RunWith;
29 |
30 | import java.util.List;
31 | import java.util.Map;
32 |
33 | @RunWith(Spockito.class)
34 | public class AdvancedDataTypesTest {
35 |
36 | public static class FieldBean {
37 | public int index;
38 | public String name;
39 | }
40 |
41 | public static class AccessorBean {
42 | private int index;
43 | private String name;
44 | public void setIndex(int index) {
45 | this.index = index;
46 | }
47 |
48 | private int getIndex() {
49 | return index;
50 | }
51 | public void setName(String name) {
52 | this.name = name;
53 | }
54 |
55 | private String getName() {
56 | return name;
57 | }
58 | }
59 |
60 | @Test
61 | @Spockito.Unroll({
62 | "| List | Count |",
63 | "| 1,2,3,4,5 | 5 |",
64 | "| 17,99,101 | 3 |"
65 | })
66 | @Spockito.Name("[{row}]")
67 | public void testUnrollSingleColumnsIntoList(final List
> rows) {
57 | this.headers = new SpockitoTableRow(this, headers);
58 | for (final List
53 | *
58 | */
59 | enum TableRowConverters {
60 | ;
61 | static TableRowConverter create(final InjectionContext context,
62 | final Parameter parameter,
63 | final int index,
64 | final ValueConverter valueConverter) {
65 | if (annotationDirectOrMeta(parameter, ConvertWith.class) != null) {
66 | return objConverter(context, parameter, index, valueConverter);
67 | }
68 | final AggregateWith aggregateWith = annotationDirectOrMeta(parameter, AggregateWith.class);
69 | if (aggregateWith != null) {
70 | final Class> agg = aggregateWith.value();
71 | if (TableRowAggregator.class.isAssignableFrom(agg)) {
72 | return tableRow -> tableRow;
73 | }
74 | return objConverter(context, parameter, index, valueConverter);
75 | }
76 | final JoinOn joinOn = annotationDirectOrMeta(parameter, JoinOn.class);
77 | if (joinOn != null) {
78 | final Data data = annotationDirectOrMeta(parameter, Data.class);
79 | if (data != null) {
80 | final Class extends DataProvider> dataProvider = data.value();
81 | if (TableDataProvider.class.isAssignableFrom(dataProvider)) {
82 | final TableRowConverter joinedConverter = joinedConverterOrNull(parameter, joinOn);
83 | if (joinedConverter != null) {
84 | return joinedConverter;
85 | }
86 | }
87 | }
88 | }
89 | return SpockitoTableRowConverter.create(context, parameter, index, valueConverter);
90 | }
91 |
92 | private static TableRowConverter objConverter(final InjectionContext context,
93 | final Parameter parameter,
94 | final int index,
95 | final ValueConverter valueConverter) {
96 | return new SpockitoTableRowConverter(context.createSubContextOrNull(parameter, Data.class), parameter,
97 | parameter.getName(), index, Object.class, Object.class, valueConverter);
98 | }
99 |
100 | private static TableRowConverter joinedConverterOrNull(final Parameter parameter, final JoinOn joinedOn) {
101 | requireNonNull(parameter);
102 | requireNonNull(joinedOn);
103 | final Data data = annotationDirectOrMeta(parameter, Data.class);
104 | try {
105 | final DataProvider dataProvider = data.value().newInstance();
106 | if (dataProvider instanceof TableDataProvider) {
107 | final TableDataProvider tableDataProvider = (TableDataProvider)dataProvider;
108 | final InjectionContext ctxt = InjectionContext.create(Phase.INIT, parameter);
109 | if (dataProvider.applicable(ctxt)) {
110 | final Table table = tableDataProvider.provideTable(ctxt);
111 | final ValueConverter valueConverter = tableDataProvider.provideValueConverter(ctxt);
112 | return tableRow -> tableDataProvider.provideData(ctxt, join(table, tableRow, joinedOn), valueConverter);
113 | }
114 | }
115 | return null;
116 | } catch (final Exception e) {
117 | throw new SpockitoException("Cannot provide data for " + parameter + " annotated with @"
118 | + TableData.class.getSimpleName() + " (or meta annotation)", e);
119 | }
120 | }
121 |
122 | private static Table join(final Table child, final TableRow parent, final JoinOn joinOn) {
123 | final String[] children = joinOn.child();
124 | final String[] parents = joinOn.parent();
125 | if (children.length != parents.length) {
126 | throw new IllegalArgumentException("JoinOn.parent=" + Arrays.toString(joinOn.parent()) + " and JoinOn.child="
127 | + Arrays.toString(joinOn.parent()) + " must have matching number of entries");
128 | }
129 | final TableJoiner joiner = child.join(parent);
130 | JoinBuilder builder = null;
131 | for (final String common : joinOn.value()) {
132 | builder = builder == null ? joiner.on(common) : builder.and(common);
133 | }
134 | for (int i = 0; i < children.length; i++) {
135 | builder = builder == null ? joiner.on(children[i], parents[i]) :
136 | builder.and(children[i], parents[i]);
137 | }
138 | if (builder != null) {
139 | return builder.apply();
140 | }
141 | throw new IllegalArgumentException("JoinOn must define at least one value");
142 | }
143 | }
144 |
--------------------------------------------------------------------------------