11package io .cucumber .cucumberexpressions ;
22
3+ import org .jspecify .annotations .NullMarked ;
4+ import org .jspecify .annotations .Nullable ;
35import org .junit .jupiter .api .Test ;
46import org .junit .jupiter .api .extension .ParameterContext ;
57import org .junit .jupiter .api .function .Executable ;
1921import java .nio .file .Path ;
2022import java .nio .file .Paths ;
2123import java .util .ArrayList ;
24+ import java .util .Arrays ;
2225import java .util .Comparator ;
2326import java .util .List ;
2427import java .util .Locale ;
3235import static org .hamcrest .Matchers .equalTo ;
3336import static org .hamcrest .core .Is .is ;
3437import static org .junit .jupiter .api .Assertions .assertEquals ;
38+ import static org .junit .jupiter .api .Assertions .assertNotNull ;
3539import static org .junit .jupiter .api .Assertions .assertThrows ;
3640
41+ @ NullMarked
3742class CucumberExpressionTest {
3843 private final ParameterTypeRegistry parameterTypeRegistry = new ParameterTypeRegistry (Locale .ENGLISH );
3944
40- private static List <Path > acceptance_tests_pass () throws IOException {
45+ static List <Path > acceptance_tests_pass () throws IOException {
4146 List <Path > paths = new ArrayList <>();
4247 Path path = Paths .get (".." , "testdata" , "cucumber-expression" , "matching" );
4348 try (DirectoryStream <Path > directories = newDirectoryStream (path )){
@@ -57,7 +62,7 @@ void acceptance_tests_pass(@ConvertWith(Converter.class) Expectation expectation
5762 .map (Argument ::getValue )
5863 .collect (Collectors .toList ());
5964
60- assertThat (values , CustomMatchers .equalOrCloseTo (expectation .expected_args ));
65+ assertThat (values , CustomMatchers .equalOrCloseTo (expectation .expectedArgs ));
6166 } else {
6267 Executable executable = () -> {
6368 CucumberExpression expression = new CucumberExpression (expectation .expression , parameterTypeRegistry );
@@ -69,17 +74,29 @@ void acceptance_tests_pass(@ConvertWith(Converter.class) Expectation expectation
6974 }
7075
7176 static class Expectation {
72- public String expression ;
73- public String text ;
74- public List <?> expected_args ;
75- public String exception ;
77+ public final String expression ;
78+ public final String text ;
79+ public final List <?> expectedArgs ;
80+ public final @ Nullable String exception ;
81+
82+ Expectation (String expression , String text , List <?> expectedArgs , String exception ) {
83+ this .expression = expression ;
84+ this .text = text ;
85+ this .expectedArgs = expectedArgs ;
86+ this .exception = exception ;
87+ }
7688 }
7789
90+ @ NullMarked
7891 static class Converter implements ArgumentConverter {
7992 Yaml yaml = new Yaml ();
8093
8194 @ Override
82- public Expectation convert (Object source , ParameterContext context ) throws ArgumentConversionException {
95+ public Expectation convert (@ Nullable Object source , ParameterContext context ) throws ArgumentConversionException {
96+ if (source == null ) {
97+ throw new ArgumentConversionException ("Could not load null" );
98+ }
99+
83100 try {
84101 Path path = (Path ) source ;
85102 InputStream inputStream = newInputStream (path );
@@ -109,6 +126,7 @@ void documents_match_arguments() {
109126 String expr = "I have {int} cuke(s)" ;
110127 Expression expression = new CucumberExpression (expr , parameterTypeRegistry );
111128 List <Argument <?>> args = expression .match ("I have 7 cukes" );
129+ assertNotNull (args );
112130 assertEquals (7 , args .get (0 ).getValue ());
113131 }
114132
@@ -149,7 +167,7 @@ void matches_double_with_comma_for_locale_using_comma() {
149167 @ Test
150168 void matches_float_with_zero () {
151169 List <?> values = match ("{float}" , "0" , Locale .ENGLISH );
152- assertEquals (0.0f , values . get ( 0 ) );
170+ assertEquals (singletonList ( 0.0f ) , values );
153171 }
154172
155173 @ Test
@@ -158,12 +176,11 @@ void unmatched_optional_groups_have_null_values() {
158176 parameterTypeRegistry .defineParameterType (new ParameterType <>(
159177 "textAndOrNumber" ,
160178 singletonList ("([A-Z]+)?(?: )?([0-9]+)?" ),
161- new TypeReference <List <String >>() {
162- }.getType (),
179+ new TypeReference <List <String >>() {}.getType (),
163180 new CaptureGroupTransformer <List <String >>() {
164181 @ Override
165- public List <String > transform (String ... args ) {
166- return asList (args );
182+ public List <String > transform (@ Nullable String [] args ) {
183+ return Arrays . asList (args );
167184 }
168185 },
169186 false ,
@@ -173,15 +190,18 @@ public List<String> transform(String... args) {
173190 assertThat (match ("{textAndOrNumber}" , "123" , parameterTypeRegistry ), is (singletonList (asList (null , "123" ))));
174191 }
175192
193+ @ Nullable
176194 private List <?> match (String expr , String text , Type ... typeHints ) {
177195 return match (expr , text , parameterTypeRegistry , typeHints );
178196 }
179197
198+ @ Nullable
180199 private List <?> match (String expr , String text , Locale locale , Type ... typeHints ) {
181200 ParameterTypeRegistry parameterTypeRegistry = new ParameterTypeRegistry (locale );
182201 return match (expr , text , parameterTypeRegistry , typeHints );
183202 }
184203
204+ @ Nullable
185205 private List <?> match (String expr , String text , ParameterTypeRegistry parameterTypeRegistry , Type ... typeHints ) {
186206 CucumberExpression expression = new CucumberExpression (expr , parameterTypeRegistry );
187207 List <Argument <?>> args = expression .match (text , typeHints );
0 commit comments