or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

dotnet.mdexpression-factory.mdgo.mdindex.mdjava.mdjavascript-typescript.mdparameter-types.mdpython.mdruby.md

java.mddocs/

0

# Java Implementation

1

2

Enterprise-grade Java implementation with strong typing, comprehensive built-in types, annotation support, and extensive configuration options for robust BDD testing in Java ecosystems.

3

4

## Package Information

5

6

- **Maven Artifact**: `io.cucumber:cucumber-expressions:18.0.1`

7

- **Package**: `io.cucumber.cucumberexpressions`

8

- **Language**: Java 8+

9

- **API Stability**: Stable (marked with `@API(status = API.Status.STABLE)`)

10

11

## Core Imports

12

13

```java

14

import io.cucumber.cucumberexpressions.CucumberExpression;

15

import io.cucumber.cucumberexpressions.ParameterType;

16

import io.cucumber.cucumberexpressions.ParameterTypeRegistry;

17

import io.cucumber.cucumberexpressions.ExpressionFactory;

18

import io.cucumber.cucumberexpressions.CucumberExpressionGenerator;

19

import io.cucumber.cucumberexpressions.Argument;

20

import io.cucumber.cucumberexpressions.GeneratedExpression;

21

import io.cucumber.cucumberexpressions.Expression;

22

```

23

24

## Capabilities

25

26

### Expression Creation and Matching

27

28

Create and match Cucumber expressions with strong typing and comprehensive type hint support.

29

30

```java { .api }

31

/**

32

* Main class for parsing and matching Cucumber expressions

33

* Stable API - safe for production use

34

*/

35

@API(status = API.Status.STABLE)

36

public final class CucumberExpression implements Expression {

37

/**

38

* Create a new Cucumber expression

39

* @param expression The Cucumber expression string

40

* @param parameterTypeRegistry Registry containing parameter types

41

*/

42

CucumberExpression(String expression, ParameterTypeRegistry parameterTypeRegistry);

43

44

/**

45

* Match text against this expression and extract arguments

46

* @param text Text to match against the expression

47

* @param typeHints Optional type hints for anonymous parameters

48

* @return List of matched arguments or null if no match

49

*/

50

@Override

51

public List<Argument<?>> match(String text, Type... typeHints);

52

53

/**

54

* Get the original expression string

55

* @return The source expression

56

*/

57

@Override

58

public String getSource();

59

60

/**

61

* Get the compiled regular expression

62

* @return The regex pattern

63

*/

64

@Override

65

public Pattern getRegexp();

66

}

67

68

/**

69

* Common interface for all expression types

70

*/

71

@API(status = API.Status.STABLE)

72

public interface Expression {

73

/**

74

* Match text against this expression

75

* @param text Text to match

76

* @param typeHints Optional type hints for resolution

77

* @return List of arguments or null if no match

78

*/

79

List<Argument<?>> match(String text, Type... typeHints);

80

81

/**

82

* Get the source expression string

83

* @return Source string

84

*/

85

String getSource();

86

87

/**

88

* Get the compiled regular expression

89

* @return Regex pattern

90

*/

91

Pattern getRegexp();

92

}

93

```

94

95

**Usage Examples:**

96

97

```java

98

import io.cucumber.cucumberexpressions.*;

99

import java.util.List;

100

101

// Create registry with built-in parameter types

102

ParameterTypeRegistry registry = new ParameterTypeRegistry();

103

104

// Simple integer parameter

105

CucumberExpression expr1 = new CucumberExpression("I have {int} cucumbers", registry);

106

List<Argument<?>> args1 = expr1.match("I have 42 cucumbers");

107

if (args1 != null) {

108

Integer count = (Integer) args1.get(0).getValue();

109

System.out.println(count); // 42

110

}

111

112

// Multiple parameters with type safety

113

CucumberExpression expr2 = new CucumberExpression("User {word} has {int} items", registry);

114

List<Argument<?>> args2 = expr2.match("User alice has 42 items");

115

if (args2 != null) {

116

String username = (String) args2.get(0).getValue();

117

Integer itemCount = (Integer) args2.get(1).getValue();

118

System.out.println("User: " + username + ", Items: " + itemCount);

119

}

120

121

// Optional text

122

CucumberExpression expr3 = new CucumberExpression("I have {int} cucumber(s)", registry);

123

System.out.println(expr3.match("I have 1 cucumber") != null); // true

124

System.out.println(expr3.match("I have 5 cucumbers") != null); // true

125

126

// Alternative text

127

CucumberExpression expr4 = new CucumberExpression("I put it in my belly/stomach", registry);

128

System.out.println(expr4.match("I put it in my belly") != null); // true

129

System.out.println(expr4.match("I put it in my stomach") != null); // true

130

131

// String parameters (removes quotes)

132

CucumberExpression expr5 = new CucumberExpression("I say {string}", registry);

133

List<Argument<?>> args5 = expr5.match("I say \"hello world\"");

134

if (args5 != null) {

135

String message = (String) args5.get(0).getValue();

136

System.out.println(message); // "hello world" (without quotes)

137

}

138

139

// Type hints for anonymous parameters

140

CucumberExpression expr6 = new CucumberExpression("Value is {}", registry);

141

List<Argument<?>> args6 = expr6.match("Value is 42", Integer.class);

142

if (args6 != null) {

143

Integer value = (Integer) args6.get(0).getValue(); // Converted to Integer

144

System.out.println(value); // 42

145

}

146

```

147

148

### Parameter Type Definition

149

150

Define custom parameter types with strong typing, multiple constructor overloads, and transformer functions.

151

152

```java { .api }

153

/**

154

* Defines a parameter type with name, patterns, and transformer

155

* Stable API with comprehensive constructor overloads

156

*/

157

@API(status = API.Status.STABLE)

158

public final class ParameterType<T> implements Comparable<ParameterType<?>> {

159

/**

160

* Create parameter type with capture group transformer

161

* @param name Name used in expressions

162

* @param regexps List of regular expression patterns

163

* @param type Target class type

164

* @param transformer Function to transform capture groups

165

*/

166

public ParameterType(

167

String name,

168

List<String> regexps,

169

Class<T> type,

170

CaptureGroupTransformer<T> transformer

171

);

172

173

/**

174

* Create parameter type with simple transformer

175

* @param name Name used in expressions

176

* @param regexp Single regular expression pattern

177

* @param type Target class type

178

* @param transformer Function to transform single match

179

*/

180

public ParameterType(

181

String name,

182

String regexp,

183

Class<T> type,

184

Transformer<T> transformer

185

);

186

187

/**

188

* Create parameter type with all options

189

* @param name Name used in expressions

190

* @param regexps List of regular expression patterns

191

* @param type Target class type

192

* @param transformer Capture group transformer

193

* @param useForSnippets Whether to use for snippet generation

194

* @param preferForRegexpMatch Whether to prefer for regexp matches

195

*/

196

public ParameterType(

197

String name,

198

List<String> regexps,

199

Class<T> type,

200

CaptureGroupTransformer<T> transformer,

201

boolean useForSnippets,

202

boolean preferForRegexpMatch

203

);

204

205

// Many additional constructor overloads available...

206

207

/**

208

* Check if parameter type name is valid

209

* @param name Name to validate

210

* @throws CucumberExpressionException if invalid

211

*/

212

static void checkParameterTypeName(String name);

213

214

/**

215

* Test if parameter type name is valid

216

* @param name Name to test

217

* @return true if valid

218

*/

219

static boolean isValidParameterTypeName(String name);

220

221

/**

222

* Create anonymous parameter type for regexp matching

223

* @param regexp Regular expression pattern

224

* @return Anonymous parameter type

225

*/

226

static ParameterType<Object> createAnonymousParameterType(String regexp);

227

228

/**

229

* Create parameter type from enum class

230

* @param enumClass Enum class to create type for

231

* @return Parameter type for enum

232

*/

233

static <E extends Enum> ParameterType<E> fromEnum(final Class<E> enumClass);

234

235

/**

236

* Get parameter type name

237

* @return Name or null for anonymous types

238

*/

239

public String getName();

240

241

/**

242

* Get target type

243

* @return Java type

244

*/

245

public Type getType();

246

247

/**

248

* Get regular expression patterns

249

* @return List of regex strings

250

*/

251

public List<String> getRegexps();

252

253

/**

254

* Whether this type is preferred for regexp matches

255

* @return true if preferred

256

*/

257

public boolean preferForRegexpMatch();

258

259

/**

260

* Whether this type should be used for snippets

261

* @return true if used for snippets

262

*/

263

public boolean useForSnippets();

264

265

/**

266

* Whether regexp match provides strong type hint

267

* @return true if strong type hint

268

*/

269

public boolean useRegexpMatchAsStrongTypeHint();

270

271

/**

272

* Transform matched groups to target type

273

* @param groupValues List of matched strings

274

* @return Transformed value

275

* @throws Throwable if transformation fails

276

*/

277

T transform(List<String> groupValues) throws Throwable;

278

279

/**

280

* Compare parameter types for sorting

281

* @param o Other parameter type

282

* @return Comparison result

283

*/

284

@Override

285

public int compareTo(ParameterType<?> o);

286

287

/**

288

* Get parameter type weight for ranking

289

* @return Weight value

290

*/

291

public int weight();

292

}

293

294

/**

295

* Transformer for multiple capture groups

296

*/

297

@FunctionalInterface

298

public interface CaptureGroupTransformer<T> {

299

/**

300

* Transform capture group array to target type

301

* @param args Array of captured strings

302

* @return Transformed value

303

* @throws Throwable if transformation fails

304

*/

305

T transform(String[] args) throws Throwable;

306

}

307

308

/**

309

* Transformer for single capture group

310

*/

311

@FunctionalInterface

312

public interface Transformer<T> {

313

/**

314

* Transform single string to target type

315

* @param arg Captured string

316

* @return Transformed value

317

* @throws Throwable if transformation fails

318

*/

319

T transform(String arg) throws Throwable;

320

}

321

```

322

323

**Usage Examples:**

324

325

```java

326

import io.cucumber.cucumberexpressions.*;

327

import java.time.LocalDate;

328

import java.time.LocalDateTime;

329

import java.util.Arrays;

330

import java.math.BigDecimal;

331

332

// Simple enum parameter type

333

enum Priority {

334

LOW, MEDIUM, HIGH;

335

336

public static Priority fromString(String s) {

337

return valueOf(s.toUpperCase());

338

}

339

}

340

341

ParameterType<Priority> priorityType = new ParameterType<>(

342

"priority",

343

"low|medium|high",

344

Priority.class,

345

Priority::fromString

346

);

347

348

// Complex object with multiple capture groups

349

class User {

350

final String name;

351

final int age;

352

final String email;

353

354

User(String name, int age, String email) {

355

this.name = name;

356

this.age = age;

357

this.email = email;

358

}

359

360

@Override

361

public String toString() {

362

return String.format("User{name='%s', age=%d, email='%s'}", name, age, email);

363

}

364

}

365

366

ParameterType<User> userType = new ParameterType<>(

367

"user",

368

Arrays.asList("(\\w+):(\\d+):([^:]+)"),

369

User.class,

370

(String[] args) -> new User(args[0], Integer.parseInt(args[1]), args[2])

371

);

372

373

// Date parameter type with validation

374

ParameterType<LocalDate> dateType = new ParameterType<>(

375

"date",

376

Arrays.asList("(\\d{4})-(\\d{2})-(\\d{2})"),

377

LocalDate.class,

378

(String[] args) -> {

379

int year = Integer.parseInt(args[0]);

380

int month = Integer.parseInt(args[1]);

381

int day = Integer.parseInt(args[2]);

382

383

if (month < 1 || month > 12) {

384

throw new IllegalArgumentException("Invalid month: " + month);

385

}

386

if (day < 1 || day > 31) {

387

throw new IllegalArgumentException("Invalid day: " + day);

388

}

389

390

return LocalDate.of(year, month, day);

391

}

392

);

393

394

// Money parameter type with BigDecimal

395

class Money {

396

final BigDecimal amount;

397

final String currency;

398

399

Money(BigDecimal amount, String currency) {

400

this.amount = amount;

401

this.currency = currency;

402

}

403

404

@Override

405

public String toString() {

406

return amount + " " + currency;

407

}

408

}

409

410

ParameterType<Money> moneyType = new ParameterType<>(

411

"money",

412

"\\$([0-9]+(?:\\.[0-9]{2})?)\\s+(USD|EUR|GBP)",

413

Money.class,

414

(String[] args) -> new Money(new BigDecimal(args[0]), args[1])

415

);

416

417

// Register and use parameter types

418

ParameterTypeRegistry registry = new ParameterTypeRegistry();

419

registry.defineParameterType(priorityType);

420

registry.defineParameterType(userType);

421

registry.defineParameterType(dateType);

422

registry.defineParameterType(moneyType);

423

424

// Use in expressions

425

CucumberExpression priorityExpr = new CucumberExpression("Task has {priority} priority", registry);

426

List<Argument<?>> priorityArgs = priorityExpr.match("Task has high priority");

427

Priority p = (Priority) priorityArgs.get(0).getValue();

428

System.out.println(p); // HIGH

429

430

CucumberExpression userExpr = new CucumberExpression("Create {user}", registry);

431

List<Argument<?>> userArgs = userExpr.match("Create alice:25:alice@example.com");

432

User user = (User) userArgs.get(0).getValue();

433

System.out.println(user); // User{name='alice', age=25, email='alice@example.com'}

434

435

CucumberExpression dateExpr = new CucumberExpression("Meeting on {date}", registry);

436

List<Argument<?>> dateArgs = dateExpr.match("Meeting on 2023-12-25");

437

LocalDate date = (LocalDate) dateArgs.get(0).getValue();

438

System.out.println(date); // 2023-12-25

439

440

CucumberExpression moneyExpr = new CucumberExpression("Price is {money}", registry);

441

List<Argument<?>> moneyArgs = moneyExpr.match("Price is $29.99 USD");

442

Money money = (Money) moneyArgs.get(0).getValue();

443

System.out.println(money); // 29.99 USD

444

445

// Enum from class (automatic pattern generation)

446

ParameterType<Priority> autoEnumType = ParameterType.fromEnum(Priority.class);

447

registry.defineParameterType(autoEnumType);

448

System.out.println(autoEnumType.getRegexps()); // [LOW|MEDIUM|HIGH]

449

```

450

451

### Parameter Type Registry

452

453

Comprehensive registry with default parameter transformers and advanced lookup capabilities.

454

455

```java { .api }

456

/**

457

* Registry for managing parameter types with built-in type support

458

*/

459

@API(status = API.Status.STABLE)

460

public final class ParameterTypeRegistry implements DefinesParameterType {

461

/**

462

* Create new parameter type registry with built-in types

463

*/

464

public ParameterTypeRegistry();

465

466

/**

467

* Define new parameter type in registry

468

* @param parameterType Parameter type to register

469

*/

470

public <T> void defineParameterType(ParameterType<T> parameterType);

471

472

/**

473

* Look up parameter type by name

474

* @param typeName Name of parameter type

475

* @return Parameter type or null if not found

476

*/

477

public ParameterType<?> lookupByTypeName(String typeName);

478

479

/**

480

* Look up parameter type by regular expression

481

* @param parameterTypeRegexp Regex pattern to match

482

* @param expressionRegexp Full expression regex

483

* @param text Text being matched

484

* @return Matching parameter type or null

485

*/

486

public ParameterType<?> lookupByRegexp(

487

String parameterTypeRegexp,

488

Pattern expressionRegexp,

489

String text

490

);

491

492

/**

493

* Get default parameter transformer for type conversion

494

* @return Current default transformer

495

*/

496

public ParameterByTypeTransformer getDefaultParameterTransformer();

497

498

/**

499

* Set default parameter transformer for anonymous parameters

500

* @param defaultParameterTransformer Transformer to use

501

*/

502

public void setDefaultParameterTransformer(ParameterByTypeTransformer defaultParameterTransformer);

503

}

504

505

/**

506

* Interface for parameter type registration

507

*/

508

public interface DefinesParameterType {

509

/**

510

* Define parameter type

511

* @param parameterType Parameter type to define

512

*/

513

<T> void defineParameterType(ParameterType<T> parameterType);

514

}

515

516

/**

517

* Interface for transforming parameters by target type

518

*/

519

public interface ParameterByTypeTransformer {

520

/**

521

* Transform parameter to target type

522

* @param fromValue Source string value

523

* @param toValueType Target type

524

* @return Transformed value

525

* @throws Throwable if transformation fails

526

*/

527

Object transform(String fromValue, Type toValueType) throws Throwable;

528

}

529

```

530

531

**Usage Examples:**

532

533

```java

534

import io.cucumber.cucumberexpressions.*;

535

import java.lang.reflect.Type;

536

import java.time.LocalDateTime;

537

import java.time.format.DateTimeFormatter;

538

539

ParameterTypeRegistry registry = new ParameterTypeRegistry();

540

541

// Check built-in types

542

ParameterType<?> intType = registry.lookupByTypeName("int");

543

System.out.println(intType.getName()); // "int"

544

System.out.println(intType.getType()); // class java.lang.Integer

545

546

// Custom default parameter transformer

547

ParameterByTypeTransformer customTransformer = new ParameterByTypeTransformer() {

548

@Override

549

public Object transform(String fromValue, Type toValueType) throws Throwable {

550

if (toValueType == LocalDateTime.class) {

551

return LocalDateTime.parse(fromValue, DateTimeFormatter.ISO_LOCAL_DATE_TIME);

552

}

553

// Fallback to default behavior

554

return fromValue;

555

}

556

};

557

558

registry.setDefaultParameterTransformer(customTransformer);

559

560

// Now anonymous parameters can be converted to LocalDateTime

561

CucumberExpression expr = new CucumberExpression("Event at {}", registry);

562

List<Argument<?>> args = expr.match("Event at 2023-12-25T14:30:00", LocalDateTime.class);

563

if (args != null) {

564

LocalDateTime eventTime = (LocalDateTime) args.get(0).getValue();

565

System.out.println(eventTime); // 2023-12-25T14:30

566

}

567

568

// Define and verify custom type

569

ParameterType<String> customType = new ParameterType<>(

570

"uuid",

571

"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}",

572

String.class,

573

s -> s.toUpperCase()

574

);

575

576

registry.defineParameterType(customType);

577

ParameterType<?> retrieved = registry.lookupByTypeName("uuid");

578

System.out.println(retrieved == customType); // true

579

```

580

581

### Expression Factory

582

583

Factory for creating expressions with automatic type detection.

584

585

```java { .api }

586

/**

587

* Factory for creating expressions with automatic type detection

588

*/

589

@API(status = API.Status.STABLE)

590

public final class ExpressionFactory {

591

/**

592

* Create expression factory with parameter type registry

593

* @param parameterTypeRegistry Registry for parameter types

594

*/

595

public ExpressionFactory(ParameterTypeRegistry parameterTypeRegistry);

596

597

/**

598

* Create expression from string with automatic type detection

599

* @param expressionString Expression string or regex pattern

600

* @return Expression instance

601

*/

602

public Expression createExpression(String expressionString);

603

604

/**

605

* Create expression from Pattern

606

* @param pattern Regular expression pattern

607

* @return RegularExpression instance

608

*/

609

public Expression createExpression(Pattern pattern);

610

}

611

```

612

613

**Usage Examples:**

614

615

```java

616

import io.cucumber.cucumberexpressions.*;

617

import java.util.regex.Pattern;

618

619

ParameterTypeRegistry registry = new ParameterTypeRegistry();

620

ExpressionFactory factory = new ExpressionFactory(registry);

621

622

// Cucumber expression from string

623

Expression cucumberExpr = factory.createExpression("I have {int} items");

624

System.out.println(cucumberExpr.getClass().getSimpleName()); // "CucumberExpression"

625

626

// Regular expression from anchored string

627

Expression regexExpr = factory.createExpression("^I have (\\d+) items$");

628

System.out.println(regexExpr.getClass().getSimpleName()); // "RegularExpression"

629

630

// Regular expression from Pattern

631

Pattern pattern = Pattern.compile("^Count: (\\d+)$");

632

Expression patternExpr = factory.createExpression(pattern);

633

System.out.println(patternExpr.getClass().getSimpleName()); // "RegularExpression"

634

635

// Use expressions

636

List<Argument<?>> cucumberArgs = cucumberExpr.match("I have 42 items");

637

List<Argument<?>> regexArgs = regexExpr.match("I have 42 items");

638

639

Integer cucumberValue = (Integer) cucumberArgs.get(0).getValue(); // 42 as Integer

640

String regexValue = (String) regexArgs.get(0).getValue(); // "42" as String

641

```

642

643

### Expression Generation

644

645

Generate Cucumber expressions from example text with comprehensive metadata.

646

647

```java { .api }

648

/**

649

* Generates Cucumber expressions from example text

650

*/

651

@API(status = API.Status.STABLE)

652

public final class CucumberExpressionGenerator {

653

/**

654

* Create generator with parameter type registry

655

* @param parameterTypeRegistry Registry containing parameter types

656

*/

657

public CucumberExpressionGenerator(ParameterTypeRegistry parameterTypeRegistry);

658

659

/**

660

* Generate expressions from example text

661

* @param text Example text to analyze

662

* @return List of generated expressions ranked by specificity

663

*/

664

public List<GeneratedExpression> generateExpressions(String text);

665

}

666

667

/**

668

* Generated expression with comprehensive metadata

669

*/

670

@API(status = API.Status.STABLE)

671

public final class GeneratedExpression {

672

/**

673

* Create generated expression

674

* @param expressionTemplate Template with parameter placeholders

675

* @param parameterTypes List of parameter types in order

676

*/

677

public GeneratedExpression(String expressionTemplate, List<ParameterType<?>> parameterTypes);

678

679

/**

680

* Get generated expression source

681

* @return Expression string

682

*/

683

public String getSource();

684

685

/**

686

* Get parameter names for code generation

687

* @return List of parameter names

688

*/

689

public List<String> getParameterNames();

690

691

/**

692

* Get parameter information for IDE integration

693

* @return List of parameter information

694

*/

695

public List<ParameterInfo> getParameterInfos();

696

697

/**

698

* Get parameter types in declaration order

699

* @return List of parameter types

700

*/

701

public List<ParameterType<?>> getParameterTypes();

702

}

703

704

/**

705

* Parameter information for code generation and IDE support

706

*/

707

@API(status = API.Status.STABLE)

708

public final class ParameterInfo {

709

/**

710

* Get parameter type name for code generation

711

* @return Type name or null

712

*/

713

public String getType();

714

715

/**

716

* Get suggested parameter name

717

* @return Parameter name

718

*/

719

public String getName();

720

721

/**

722

* Get parameter occurrence count

723

* @return Number of occurrences

724

*/

725

public int getCount();

726

}

727

```

728

729

**Usage Examples:**

730

731

```java

732

import io.cucumber.cucumberexpressions.*;

733

import java.util.List;

734

735

ParameterTypeRegistry registry = new ParameterTypeRegistry();

736

CucumberExpressionGenerator generator = new CucumberExpressionGenerator(registry);

737

738

// Generate from simple text

739

List<GeneratedExpression> expressions = generator.generateExpressions("I have 42 items");

740

GeneratedExpression best = expressions.get(0);

741

System.out.println("Expression: " + best.getSource()); // "I have {int} items"

742

System.out.println("Parameter count: " + best.getParameterTypes().size()); // 1

743

744

// Generate step definition template

745

System.out.println("Step definition:");

746

System.out.println("@Given(\"" + best.getSource() + "\")");

747

StringBuilder params = new StringBuilder();

748

for (int i = 0; i < best.getParameterInfos().size(); i++) {

749

ParameterInfo info = best.getParameterInfos().get(i);

750

if (i > 0) params.append(", ");

751

params.append(getJavaType(info.getType())).append(" ").append(info.getName());

752

}

753

System.out.println("public void iHaveItems(" + params + ") {");

754

System.out.println(" // Implementation here");

755

System.out.println("}");

756

757

// Generate from complex text

758

List<GeneratedExpression> complex = generator.generateExpressions(

759

"User alice with age 25 has balance 123.45"

760

);

761

System.out.println("Generated options:");

762

for (int i = 0; i < Math.min(3, complex.size()); i++) {

763

GeneratedExpression expr = complex.get(i);

764

System.out.printf("%d. %s (%s)%n",

765

i + 1,

766

expr.getSource(),

767

expr.getParameterTypes().stream()

768

.map(pt -> pt.getName())

769

.collect(java.util.stream.Collectors.joining(", "))

770

);

771

}

772

773

private static String getJavaType(String paramTypeName) {

774

switch (paramTypeName) {

775

case "int": return "Integer";

776

case "float": return "Float";

777

case "double": return "Double";

778

case "string": return "String";

779

case "word": return "String";

780

default: return "Object";

781

}

782

}

783

```

784

785

### Argument Extraction

786

787

Extract matched arguments with strong typing and comprehensive metadata.

788

789

```java { .api }

790

/**

791

* Represents a matched argument with type safety

792

*/

793

@API(status = API.Status.STABLE)

794

public final class Argument<T> {

795

/**

796

* Create argument with group and parameter type

797

* @param group Matched group from regex

798

* @param parameterType Parameter type for transformation

799

*/

800

public Argument(Group group, ParameterType<T> parameterType);

801

802

/**

803

* Build arguments from matched groups

804

* @param group Root group from regex match

805

* @param parameterTypes Parameter types for transformation

806

* @return List of arguments

807

*/

808

static List<Argument<?>> build(Group group, List<ParameterType<?>> parameterTypes);

809

810

/**

811

* Get transformed value

812

* @return Transformed value

813

*/

814

public T getValue();

815

816

/**

817

* Get parameter type used for transformation

818

* @return Parameter type

819

*/

820

public ParameterType<T> getParameterType();

821

822

/**

823

* Get matched group information

824

* @return Group with position and text

825

*/

826

public Group getGroup();

827

}

828

829

/**

830

* Represents a matched group with position information

831

*/

832

public final class Group {

833

/**

834

* Get matched text value

835

* @return Matched string or null

836

*/

837

public String getValue();

838

839

/**

840

* Get start position in source text

841

* @return Start index

842

*/

843

public int getStart();

844

845

/**

846

* Get end position in source text

847

* @return End index

848

*/

849

public int getEnd();

850

851

/**

852

* Get child groups

853

* @return List of child groups

854

*/

855

public List<Group> getChildren();

856

}

857

```

858

859

**Usage Examples:**

860

861

```java

862

import io.cucumber.cucumberexpressions.*;

863

import java.util.List;

864

865

ParameterTypeRegistry registry = new ParameterTypeRegistry();

866

CucumberExpression expr = new CucumberExpression("User {word} has {int} items", registry);

867

868

List<Argument<?>> args = expr.match("User alice has 42 items");

869

if (args != null) {

870

// Type-safe value access

871

String username = (String) args.get(0).getValue(); // "alice"

872

Integer itemCount = (Integer) args.get(1).getValue(); // 42

873

874

// Parameter type information

875

System.out.println("First param type: " + args.get(0).getParameterType().getName()); // "word"

876

System.out.println("Second param type: " + args.get(1).getParameterType().getName()); // "int"

877

878

// Position information

879

Group usernameGroup = args.get(0).getGroup();

880

System.out.println("Username at: " + usernameGroup.getStart() + "-" + usernameGroup.getEnd());

881

System.out.println("Username value: '" + usernameGroup.getValue() + "'"); // "alice"

882

883

Group itemGroup = args.get(1).getGroup();

884

System.out.println("Item count at: " + itemGroup.getStart() + "-" + itemGroup.getEnd());

885

System.out.println("Item count value: '" + itemGroup.getValue() + "'"); // "42"

886

}

887

```

888

889

### Built-in Parameter Types

890

891

Comprehensive built-in parameter types with appropriate Java type conversion.

892

893

```java { .api }

894

// Built-in parameter types in Java implementation:

895

896

{int} // Converts to Integer (java.lang.Integer)

897

{byte} // Converts to Byte (java.lang.Byte)

898

{short} // Converts to Short (java.lang.Short)

899

{long} // Converts to Long (java.lang.Long)

900

{float} // Converts to Float (java.lang.Float)

901

{double} // Converts to Double (java.lang.Double)

902

{biginteger} // Converts to BigInteger (java.math.BigInteger)

903

{bigdecimal} // Converts to BigDecimal (java.math.BigDecimal)

904

{word} // Returns as String (single word)

905

{string} // Returns as String (removes quotes)

906

{} // Anonymous - uses ParameterByTypeTransformer

907

```

908

909

**Usage Examples:**

910

911

```java

912

import io.cucumber.cucumberexpressions.*;

913

import java.math.BigDecimal;

914

import java.math.BigInteger;

915

import java.util.List;

916

917

ParameterTypeRegistry registry = new ParameterTypeRegistry();

918

919

// Test all numeric built-in types

920

CucumberExpression expr = new CucumberExpression(

921

"Numbers: {byte} {short} {int} {long} {float} {double} {biginteger} {bigdecimal}",

922

registry

923

);

924

925

List<Argument<?>> args = expr.match("Numbers: 127 32767 42 9223372036854775807 3.14 2.718281828 12345678901234567890 123.456789");

926

927

if (args != null) {

928

Byte byteVal = (Byte) args.get(0).getValue();

929

Short shortVal = (Short) args.get(1).getValue();

930

Integer intVal = (Integer) args.get(2).getValue();

931

Long longVal = (Long) args.get(3).getValue();

932

Float floatVal = (Float) args.get(4).getValue();

933

Double doubleVal = (Double) args.get(5).getValue();

934

BigInteger bigIntVal = (BigInteger) args.get(6).getValue();

935

BigDecimal bigDecVal = (BigDecimal) args.get(7).getValue();

936

937

System.out.println("Byte: " + byteVal + " (" + byteVal.getClass().getSimpleName() + ")");

938

System.out.println("Short: " + shortVal + " (" + shortVal.getClass().getSimpleName() + ")");

939

System.out.println("Integer: " + intVal + " (" + intVal.getClass().getSimpleName() + ")");

940

System.out.println("Long: " + longVal + " (" + longVal.getClass().getSimpleName() + ")");

941

System.out.println("Float: " + floatVal + " (" + floatVal.getClass().getSimpleName() + ")");

942

System.out.println("Double: " + doubleVal + " (" + doubleVal.getClass().getSimpleName() + ")");

943

System.out.println("BigInteger: " + bigIntVal + " (" + bigIntVal.getClass().getSimpleName() + ")");

944

System.out.println("BigDecimal: " + bigDecVal + " (" + bigDecVal.getClass().getSimpleName() + ")");

945

}

946

```

947

948

### Integration with Java Testing Frameworks

949

950

Common patterns for integrating with JUnit, TestNG, and Cucumber-JVM.

951

952

```java

953

// Cucumber-JVM integration

954

import io.cucumber.java.en.Given;

955

import io.cucumber.java.en.When;

956

import io.cucumber.java.en.Then;

957

import io.cucumber.cucumberexpressions.*;

958

959

public class StepDefinitions {

960

private ParameterTypeRegistry registry = new ParameterTypeRegistry();

961

962

// Custom parameter type registration

963

@ParameterType("red|green|blue")

964

public Color color(String color) {

965

return Color.valueOf(color.toUpperCase());

966

}

967

968

// Step definitions using built-in types

969

@Given("I have {int} cucumbers")

970

public void iHaveCucumbers(Integer count) {

971

// count is already converted to Integer

972

assert count instanceof Integer;

973

}

974

975

@When("I eat {int} cucumber(s)")

976

public void iEatCucumbers(Integer count) {

977

// Handles both singular and plural

978

}

979

980

@Then("I should have {int} cucumber(s) left")

981

public void iShouldHaveCucumbersLeft(Integer count) {

982

// Assertion logic here

983

}

984

985

// Using custom parameter types

986

@Given("I have a {color} car")

987

public void iHaveColorCar(Color color) {

988

// color is converted using custom parameter type

989

assert color instanceof Color;

990

}

991

}

992

993

// JUnit 5 integration example

994

import org.junit.jupiter.api.Test;

995

import io.cucumber.cucumberexpressions.*;

996

997

class CucumberExpressionTest {

998

@Test

999

void testParameterExtraction() {

1000

ParameterTypeRegistry registry = new ParameterTypeRegistry();

1001

CucumberExpression expr = new CucumberExpression("User {word} has {int} items", registry);

1002

1003

List<Argument<?>> args = expr.match("User alice has 42 items");

1004

1005

assertThat(args).hasSize(2);

1006

assertThat(args.get(0).getValue()).isEqualTo("alice");

1007

assertThat(args.get(1).getValue()).isEqualTo(42);

1008

}

1009

}

1010

```

1011

1012

The Java implementation provides enterprise-grade robustness with comprehensive type safety, extensive built-in parameter types, and seamless integration with Java testing ecosystems while maintaining full API compatibility with the Cucumber Expressions specification.