or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdexecution-model.mdfixtures.mdformatters.mdindex.mdmatchers-types.mdstep-definitions.md

matchers-types.mddocs/

0

# Matchers and Types

1

2

Pattern matching and parameter conversion system for extracting and transforming data from step text into Python objects. Supports multiple matching strategies and custom type registration.

3

4

## Capabilities

5

6

### Type Registration

7

8

Register custom step parameter types for converting matched text into specific Python objects. This enables automatic type conversion in step parameters.

9

10

```python { .api }

11

def register_type(name: str, func):

12

"""

13

Register a custom type converter for step parameters.

14

15

Parameters:

16

- name: str, name to use in step patterns (e.g., "color", "number")

17

- func: callable, function that converts matched string to desired type

18

19

Returns:

20

None

21

"""

22

```

23

24

Usage example:

25

```python

26

# Define type converter

27

def parse_color(text):

28

color_map = {

29

'red': '#FF0000',

30

'green': '#00FF00',

31

'blue': '#0000FF'

32

}

33

return color_map.get(text.lower(), text)

34

35

# Register the type

36

register_type('color', parse_color)

37

38

# Use in step definition

39

@given('the background is {color:color}')

40

def step_impl(context, color):

41

# color parameter is automatically converted

42

context.background_color = color # e.g., '#FF0000' for 'red'

43

```

44

45

### Step Matcher Selection

46

47

Set the step matcher to use for pattern matching in the current module. Different matchers provide different pattern syntax options.

48

49

```python { .api }

50

def use_step_matcher(name: str):

51

"""

52

Set the step matcher to use for current module.

53

54

Parameters:

55

- name: str, matcher name ("parse", "cfparse", "re")

56

57

Returns:

58

None

59

"""

60

```

61

62

Usage example:

63

```python

64

# Use parse matcher (default)

65

use_step_matcher("parse")

66

67

@given('I have {count:d} items')

68

def step_impl(context, count):

69

pass

70

71

# Use regular expression matcher

72

use_step_matcher("re")

73

74

@given(r'I have (\d+) items')

75

def step_impl(context, count):

76

count = int(count) # Manual conversion needed

77

```

78

79

## Step Matchers

80

81

Behave supports multiple step matching strategies:

82

83

### Parse Matcher

84

85

Default matcher using parse library syntax for simple parameter extraction with type conversion.

86

87

```python { .api }

88

class ParseMatcher:

89

"""

90

Parse-based step matcher using parse library for parameter extraction.

91

92

Methods:

93

- check_match(pattern, step_text): Check if pattern matches step text

94

- match(pattern, step_text): Extract parameters from matched step text

95

"""

96

```

97

98

Parse patterns support:

99

- `{name}` - matches any text

100

- `{name:d}` - matches integers

101

- `{name:f}` - matches floats

102

- `{name:w}` - matches words (no whitespace)

103

- `{name:S}` - matches non-whitespace

104

- Custom types via `register_type()`

105

106

### Case-insensitive Parse Matcher

107

108

Parse matcher that ignores case differences in step text.

109

110

```python { .api }

111

class CFParseMatcher:

112

"""

113

Case-insensitive parse matcher.

114

115

Methods:

116

- check_match(pattern, step_text): Check if pattern matches (case-insensitive)

117

- match(pattern, step_text): Extract parameters (case-insensitive)

118

"""

119

```

120

121

### Regular Expression Matcher

122

123

Traditional regex-based matcher for complex patterns requiring full regular expression support.

124

125

```python { .api }

126

class RegexMatcher:

127

"""

128

Regular expression-based step matcher.

129

130

Methods:

131

- check_match(pattern, step_text): Check if regex pattern matches

132

- match(pattern, step_text): Extract groups from regex match

133

"""

134

```

135

136

### Cucumber Expression Matcher

137

138

Cucumber-style expression matcher for compatibility with Cucumber frameworks.

139

140

```python { .api }

141

class CucumberExpressionMatcher:

142

"""

143

Cucumber-style expression matcher.

144

145

Methods:

146

- check_match(pattern, step_text): Check if Cucumber expression matches

147

- match(pattern, step_text): Extract parameters from Cucumber expression

148

"""

149

```

150

151

## Type Registry

152

153

Central registry for managing custom parameter types and their conversion functions.

154

155

```python { .api }

156

class TypeRegistry:

157

"""

158

Registry for managing custom parameter type converters.

159

160

Methods:

161

- register_type(name, func): Register a type converter function

162

- convert(name, value): Convert value using registered type converter

163

- get_type(name): Get registered type converter by name

164

- clear(): Remove all registered type converters

165

"""

166

```

167

168

## Built-in Types

169

170

Behave includes several built-in parameter types:

171

172

### Numeric Types

173

```python

174

# Integer type

175

@given('I have {count:d} items')

176

def step_impl(context, count):

177

# count is automatically converted to int

178

assert isinstance(count, int)

179

180

# Float type

181

@given('the price is {amount:f} dollars')

182

def step_impl(context, amount):

183

# amount is automatically converted to float

184

assert isinstance(amount, float)

185

```

186

187

### String Types

188

```python

189

# Word type (no whitespace)

190

@given('the status is {status:w}')

191

def step_impl(context, status):

192

# status contains no whitespace

193

assert ' ' not in status

194

195

# Non-whitespace type

196

@given('the code is {code:S}')

197

def step_impl(context, code):

198

# code contains no whitespace characters

199

assert not any(c.isspace() for c in code)

200

```

201

202

## Custom Type Examples

203

204

### Boolean Type

205

```python

206

def parse_bool(text):

207

text = text.lower()

208

if text in ('true', 'yes', '1', 'on', 'enabled'):

209

return True

210

elif text in ('false', 'no', '0', 'off', 'disabled'):

211

return False

212

else:

213

raise ValueError(f"Cannot convert '{text}' to boolean")

214

215

register_type('bool', parse_bool)

216

217

@given('the feature is {enabled:bool}')

218

def step_impl(context, enabled):

219

context.feature_enabled = enabled

220

```

221

222

### Date Type

223

```python

224

from datetime import datetime

225

226

def parse_date(text):

227

try:

228

return datetime.strptime(text, '%Y-%m-%d')

229

except ValueError:

230

try:

231

return datetime.strptime(text, '%m/%d/%Y')

232

except ValueError:

233

raise ValueError(f"Cannot parse date: {text}")

234

235

register_type('date', parse_date)

236

237

@given('the event date is {date:date}')

238

def step_impl(context, date):

239

context.event_date = date

240

```

241

242

### Enum Type

243

```python

244

from enum import Enum

245

246

class Priority(Enum):

247

LOW = 'low'

248

MEDIUM = 'medium'

249

HIGH = 'high'

250

251

def parse_priority(text):

252

try:

253

return Priority(text.lower())

254

except ValueError:

255

raise ValueError(f"Invalid priority: {text}")

256

257

register_type('priority', parse_priority)

258

259

@given('the task priority is {priority:priority}')

260

def step_impl(context, priority):

261

context.task_priority = priority

262

```

263

264

### List Type

265

```python

266

def parse_list(text):

267

# Parse comma-separated values

268

return [item.strip() for item in text.split(',')]

269

270

register_type('list', parse_list)

271

272

@given('the tags are {tags:list}')

273

def step_impl(context, tags):

274

context.tags = tags # ['tag1', 'tag2', 'tag3']

275

```

276

277

## Advanced Pattern Matching

278

279

### Optional Parameters

280

```python

281

# Using parse syntax with optional parts

282

@given('I {action} {count:d} item(s)')

283

def step_impl(context, action, count):

284

# Matches both "I add 1 item" and "I add 5 items"

285

pass

286

```

287

288

### Alternative Patterns

289

```python

290

# Multiple patterns for same step

291

@given('I am logged in')

292

@given('I am authenticated')

293

def step_impl(context):

294

context.authenticated = True

295

```

296

297

### Complex Regex Patterns

298

```python

299

use_step_matcher("re")

300

301

@given(r'I have (\d+) (\w+)(?:s)? in my (\w+)')

302

def step_impl(context, count, item_type, container):

303

count = int(count)

304

# Handles pluralization automatically

305

pass

306

```