or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cross-platform.mdevent-handling.mdindex.mdsbt-framework.mdtest-runners.md

event-handling.mddocs/

0

# Event Handling

1

2

This document covers the event handling system that converts ZIO test execution events to SBT-compatible formats.

3

4

## ZTestEvent

5

6

Represents a test event in SBT's format, converting ZIO test results to SBT's event model.

7

8

```scala { .api }

9

final case class ZTestEvent(

10

fullyQualifiedName0: String,

11

selector0: sbt.testing.Selector,

12

status0: sbt.testing.Status,

13

maybeThrowable: Option[Throwable],

14

duration0: Long,

15

fingerprint0: sbt.testing.Fingerprint

16

) extends sbt.testing.Event {

17

18

def duration(): Long

19

def fingerprint(): sbt.testing.Fingerprint

20

def fullyQualifiedName(): String

21

def selector(): sbt.testing.Selector

22

def status(): sbt.testing.Status

23

def throwable(): sbt.testing.OptionalThrowable

24

}

25

```

26

27

### Constructor Parameters

28

29

- `fullyQualifiedName0`: Full class name of the test

30

- `selector0`: Test selector (typically `TestSelector` with test name)

31

- `status0`: Test status (`Success`, `Failure`, `Ignored`)

32

- `maybeThrowable`: Optional exception for failed tests

33

- `duration0`: Test execution duration in milliseconds

34

- `fingerprint0`: Test fingerprint (always `ZioSpecFingerprint`)

35

36

### Methods

37

38

All methods implement the SBT `Event` interface:

39

40

#### duration

41

42

Returns test execution duration.

43

44

```scala

45

event.duration()

46

// Returns: Long (milliseconds)

47

```

48

49

#### fingerprint

50

51

Returns the test fingerprint.

52

53

```scala

54

event.fingerprint()

55

// Returns: sbt.testing.Fingerprint (ZioSpecFingerprint)

56

```

57

58

#### fullyQualifiedName

59

60

Returns the fully qualified test class name.

61

62

```scala

63

event.fullyQualifiedName()

64

// Returns: String

65

```

66

67

#### selector

68

69

Returns the test selector identifying the specific test.

70

71

```scala

72

event.selector()

73

// Returns: sbt.testing.Selector

74

```

75

76

#### status

77

78

Returns the test execution status.

79

80

```scala

81

event.status()

82

// Returns: sbt.testing.Status

83

```

84

85

#### throwable

86

87

Returns optional throwable for failed tests.

88

89

```scala

90

event.throwable()

91

// Returns: sbt.testing.OptionalThrowable

92

```

93

94

## ZTestEvent Companion Object

95

96

Provides factory methods and conversion utilities.

97

98

```scala { .api }

99

object ZTestEvent {

100

def convertEvent(

101

test: zio.test.ExecutionEvent.Test[_],

102

taskDef: sbt.testing.TaskDef,

103

renderer: zio.test.render.TestRenderer

104

): sbt.testing.Event

105

}

106

```

107

108

### convertEvent

109

110

Converts a ZIO test execution event to an SBT event.

111

112

**Parameters:**

113

- `test`: ZIO test execution event containing results

114

- `taskDef`: SBT task definition for context

115

- `renderer`: Test renderer for formatting failure messages

116

117

**Returns:** SBT-compatible `Event`

118

119

**Conversion Logic:**

120

- **Test Status**: Maps ZIO test results to SBT status codes

121

- `TestSuccess.Succeeded``Status.Success`

122

- `TestSuccess.Ignored``Status.Ignored`

123

- Test failures → `Status.Failure`

124

- **Test Selector**: Creates `TestSelector` from test label hierarchy

125

- **Failure Messages**: Renders failure details with ANSI colors using the provided renderer

126

- **Duration**: Preserves test execution timing

127

128

### Usage Example

129

130

```scala

131

import zio.test.sbt._

132

import zio.test.render.ConsoleRenderer

133

134

val zioTestResult: zio.test.ExecutionEvent.Test[_] = ???

135

val taskDef: sbt.testing.TaskDef = ???

136

137

val sbtEvent = ZTestEvent.convertEvent(

138

test = zioTestResult,

139

taskDef = taskDef,

140

renderer = ConsoleRenderer

141

)

142

143

println(s"Test: ${sbtEvent.fullyQualifiedName()}")

144

println(s"Status: ${sbtEvent.status()}")

145

println(s"Duration: ${sbtEvent.duration()}ms")

146

```

147

148

## ZTestEventHandlerSbt

149

150

Handles ZIO test execution events and forwards them to SBT's event system.

151

152

```scala { .api }

153

class ZTestEventHandlerSbt(

154

eventHandler: sbt.testing.EventHandler,

155

taskDef: sbt.testing.TaskDef,

156

renderer: zio.test.render.TestRenderer

157

) extends zio.test.ZTestEventHandler {

158

159

val semaphore: zio.Semaphore

160

def handle(event: zio.test.ExecutionEvent): zio.UIO[Unit]

161

}

162

```

163

164

### Constructor Parameters

165

166

- `eventHandler`: SBT's event handler for forwarding events

167

- `taskDef`: Task definition for context

168

- `renderer`: Test renderer for formatting output

169

170

### Properties

171

172

- `semaphore`: Ensures thread-safe event handling (initialized with permit 1)

173

174

### Methods

175

176

#### handle

177

178

Processes ZIO execution events and converts them to SBT events.

179

180

```scala

181

def handle(event: zio.test.ExecutionEvent): zio.UIO[Unit]

182

```

183

184

**Supported Event Types:**

185

186

##### ExecutionEvent.TestStarted

187

Test initiation events - no action taken.

188

189

```scala

190

case ExecutionEvent.TestStarted(_, _, _, _, _) => zio.ZIO.unit

191

```

192

193

##### ExecutionEvent.Test

194

Completed test events - converted to SBT events.

195

196

```scala

197

case evt @ ExecutionEvent.Test(_, _, _, _, _, _, _) =>

198

val zTestEvent = ZTestEvent.convertEvent(evt, taskDef, renderer)

199

semaphore.withPermit(zio.ZIO.succeed(eventHandler.handle(zTestEvent)))

200

```

201

202

##### ExecutionEvent.SectionStart/SectionEnd

203

Test section boundaries - no action taken.

204

205

```scala

206

case ExecutionEvent.SectionStart(_, _, _) => zio.ZIO.unit

207

case ExecutionEvent.SectionEnd(_, _, _) => zio.ZIO.unit

208

```

209

210

##### ExecutionEvent.TopLevelFlush

211

Output flushing events - no action taken.

212

213

```scala

214

case ExecutionEvent.TopLevelFlush(_) => zio.ZIO.unit

215

```

216

217

##### ExecutionEvent.RuntimeFailure

218

Runtime failure events - converted to SBT failure events.

219

220

```scala

221

case ExecutionEvent.RuntimeFailure(_, _, failure, _) =>

222

failure match {

223

case TestFailure.Assertion(_, _) => zio.ZIO.unit // Handled via Test events

224

case TestFailure.Runtime(cause, annotations) =>

225

val zTestEvent = ZTestEvent(

226

taskDef.fullyQualifiedName(),

227

taskDef.selectors().head,

228

sbt.testing.Status.Failure,

229

cause.dieOption,

230

annotations.get(zio.test.TestAnnotation.timing).toMillis,

231

ZioSpecFingerprint

232

)

233

semaphore.withPermit(zio.ZIO.succeed(eventHandler.handle(zTestEvent)))

234

}

235

```

236

237

## Event Flow

238

239

The event handling system follows this flow:

240

241

1. **ZIO Test Execution**: ZIO tests run and generate `ExecutionEvent`s

242

2. **Event Handler**: `ZTestEventHandlerSbt` receives ZIO events

243

3. **Event Conversion**: `ZTestEvent.convertEvent` transforms ZIO events to SBT format

244

4. **SBT Forwarding**: Converted events are sent to SBT's `EventHandler`

245

5. **Result Aggregation**: SBT collects events for final reporting

246

247

## Usage Examples

248

249

### Custom Event Handling

250

251

```scala

252

import zio.test.sbt._

253

import sbt.testing._

254

255

// Create custom event handler

256

class CustomEventHandler extends EventHandler {

257

def handle(event: Event): Unit = {

258

event.status() match {

259

case Status.Success => println(s"✓ ${event.fullyQualifiedName()}")

260

case Status.Failure => println(s"✗ ${event.fullyQualifiedName()}")

261

case Status.Ignored => println(s"○ ${event.fullyQualifiedName()}")

262

}

263

}

264

}

265

266

// Use with ZTestEventHandlerSbt

267

val customHandler = new CustomEventHandler()

268

val taskDef: TaskDef = ???

269

val renderer = zio.test.render.ConsoleRenderer

270

271

val zioHandler = new ZTestEventHandlerSbt(customHandler, taskDef, renderer)

272

```

273

274

### Event Filtering

275

276

```scala

277

// Create filtering event handler

278

class FilteringEventHandler(underlying: EventHandler, filter: Event => Boolean) extends EventHandler {

279

def handle(event: Event): Unit = {

280

if (filter(event)) {

281

underlying.handle(event)

282

}

283

}

284

}

285

286

// Only handle failures

287

val failureFilter = (event: Event) => event.status() == Status.Failure

288

val filteringHandler = new FilteringEventHandler(originalHandler, failureFilter)

289

```

290

291

### Manual Event Creation

292

293

```scala

294

// Create test event manually

295

val testEvent = ZTestEvent(

296

fullyQualifiedName0 = "com.example.MyTest",

297

selector0 = new TestSelector("should pass"),

298

status0 = Status.Success,

299

maybeThrowable = None,

300

duration0 = 150L,

301

fingerprint0 = ZioSpecFingerprint

302

)

303

304

// Handle the event

305

eventHandler.handle(testEvent)

306

```