or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdjest-integration.mdrendering.mdtree-traversal.mdtype-checking.md
tile.json

jest-integration.mddocs/

0

# Jest Integration API

1

2

Native Jest snapshot testing support with functions to convert VNodes and rendered components to Jest-compatible snapshots. These utilities enable seamless integration with Jest's snapshot testing capabilities for Inferno applications.

3

4

## Snapshot Functions

5

6

### vNodeToSnapshot

7

8

```javascript { .api }

9

/**

10

* Converts a VNode to a Jest-compatible snapshot object

11

* @param vNode - VNode to convert to snapshot

12

* @returns InfernoSnapshot object compatible with Jest snapshots

13

*/

14

function vNodeToSnapshot(vNode: VNode): InfernoSnapshot

15

```

16

17

This function converts individual VNodes into the snapshot format that Jest expects, making them suitable for snapshot testing.

18

19

```javascript

20

import { vNodeToSnapshot } from 'inferno-test-utils';

21

import { createElement } from 'inferno-create-element';

22

23

// Simple DOM element snapshot

24

const simpleVNode = <div className="test">Hello World</div>;

25

const snapshot = vNodeToSnapshot(simpleVNode);

26

27

console.log(snapshot);

28

// {

29

// type: "div",

30

// props: { className: "test" },

31

// children: ["Hello World"],

32

// $$typeof: Symbol(react.test.json)

33

// }

34

35

// Complex nested structure

36

const complexVNode = (

37

<div className="container">

38

<h1>Title</h1>

39

<p>Description</p>

40

<button disabled>Action</button>

41

</div>

42

);

43

44

const complexSnapshot = vNodeToSnapshot(complexVNode);

45

console.log(complexSnapshot);

46

// {

47

// type: "div",

48

// props: { className: "container" },

49

// children: [

50

// { type: "h1", props: {}, children: ["Title"] },

51

// { type: "p", props: {}, children: ["Description"] },

52

// { type: "button", props: { disabled: true }, children: ["Action"] }

53

// ],

54

// $$typeof: Symbol(react.test.json)

55

// }

56

```

57

58

### renderToSnapshot

59

60

```javascript { .api }

61

/**

62

* Renders a VNode and converts it to a Jest-compatible snapshot

63

* @param input - VNode to render and convert to snapshot

64

* @returns InfernoSnapshot object suitable for Jest snapshot testing

65

*/

66

function renderToSnapshot(input: VNode): InfernoSnapshot

67

```

68

69

This function combines rendering and snapshot conversion in one step, handling the full render lifecycle including state updates and component lifecycle methods.

70

71

```javascript

72

import { renderToSnapshot } from 'inferno-test-utils';

73

import { Component } from 'inferno';

74

75

// Simple component snapshot

76

function SimpleComponent({ name }) {

77

return <div className="greeting">Hello {name}!</div>;

78

}

79

80

const simpleSnapshot = renderToSnapshot(<SimpleComponent name="World" />);

81

console.log(simpleSnapshot);

82

// {

83

// type: "div",

84

// props: { className: "greeting" },

85

// children: ["Hello World!"],

86

// $$typeof: Symbol(react.test.json)

87

// }

88

89

// Class component with state

90

class StatefulComponent extends Component {

91

constructor(props) {

92

super(props);

93

this.state = { count: props.initialCount || 0 };

94

}

95

96

render() {

97

return (

98

<div className="counter">

99

<span>Count: {this.state.count}</span>

100

<button>Increment</button>

101

</div>

102

);

103

}

104

}

105

106

const statefulSnapshot = renderToSnapshot(<StatefulComponent initialCount={5} />);

107

console.log(statefulSnapshot);

108

// {

109

// type: "div",

110

// props: { className: "counter" },

111

// children: [

112

// { type: "span", props: {}, children: ["Count: 5"] },

113

// { type: "button", props: {}, children: ["Increment"] }

114

// ],

115

// $$typeof: Symbol(react.test.json)

116

// }

117

```

118

119

## Jest Integration Patterns

120

121

### Basic Snapshot Testing

122

123

```javascript

124

import { renderToSnapshot } from 'inferno-test-utils';

125

import { Component } from 'inferno';

126

127

// Component to test

128

class WelcomeMessage extends Component {

129

render() {

130

const { name, role } = this.props;

131

return (

132

<div className="welcome">

133

<h2>Welcome, {name}!</h2>

134

{role && <p className="role">Role: {role}</p>}

135

<button className="btn-primary">Get Started</button>

136

</div>

137

);

138

}

139

}

140

141

// Jest test

142

describe('WelcomeMessage', () => {

143

it('renders correctly with name only', () => {

144

const snapshot = renderToSnapshot(<WelcomeMessage name="John" />);

145

expect(snapshot).toMatchSnapshot();

146

});

147

148

it('renders correctly with name and role', () => {

149

const snapshot = renderToSnapshot(<WelcomeMessage name="Jane" role="Admin" />);

150

expect(snapshot).toMatchSnapshot();

151

});

152

});

153

```

154

155

### Component State Snapshots

156

157

```javascript

158

import { renderToSnapshot, renderIntoContainer } from 'inferno-test-utils';

159

import { Component } from 'inferno';

160

161

class ToggleComponent extends Component {

162

constructor(props) {

163

super(props);

164

this.state = { isOpen: false };

165

}

166

167

toggle = () => {

168

this.setState({ isOpen: !this.state.isOpen });

169

}

170

171

render() {

172

return (

173

<div className="toggle">

174

<button onClick={this.toggle}>

175

{this.state.isOpen ? 'Close' : 'Open'}

176

</button>

177

{this.state.isOpen && (

178

<div className="content">

179

<p>Toggle content is visible</p>

180

</div>

181

)}

182

</div>

183

);

184

}

185

}

186

187

describe('ToggleComponent', () => {

188

it('renders correctly in closed state', () => {

189

const snapshot = renderToSnapshot(<ToggleComponent />);

190

expect(snapshot).toMatchSnapshot();

191

});

192

193

it('renders correctly in open state', () => {

194

// Render component to access instance

195

const rendered = renderIntoContainer(<ToggleComponent />);

196

197

// Change state

198

rendered.toggle();

199

200

// Create snapshot of updated state

201

const snapshot = vNodeToSnapshot(rendered.$LI); // Access VNode from instance

202

expect(snapshot).toMatchSnapshot();

203

});

204

});

205

```

206

207

### Complex Component Hierarchies

208

209

```javascript

210

import { renderToSnapshot } from 'inferno-test-utils';

211

import { Component } from 'inferno';

212

213

// Child components

214

function UserAvatar({ user }) {

215

return (

216

<div className="avatar">

217

<img src={user.avatar} alt={user.name} />

218

<span className="status" data-status={user.status}></span>

219

</div>

220

);

221

}

222

223

function UserInfo({ user }) {

224

return (

225

<div className="user-info">

226

<h3>{user.name}</h3>

227

<p>{user.email}</p>

228

<span className="role">{user.role}</span>

229

</div>

230

);

231

}

232

233

// Parent component

234

class UserCard extends Component {

235

render() {

236

const { user, showActions } = this.props;

237

238

return (

239

<div className="user-card">

240

<UserAvatar user={user} />

241

<UserInfo user={user} />

242

{showActions && (

243

<div className="actions">

244

<button className="btn-edit">Edit</button>

245

<button className="btn-delete">Delete</button>

246

</div>

247

)}

248

</div>

249

);

250

}

251

}

252

253

describe('UserCard', () => {

254

const mockUser = {

255

name: 'John Doe',

256

email: 'john@example.com',

257

role: 'Developer',

258

status: 'online',

259

avatar: 'avatar.jpg'

260

};

261

262

it('renders user card without actions', () => {

263

const snapshot = renderToSnapshot(

264

<UserCard user={mockUser} showActions={false} />

265

);

266

expect(snapshot).toMatchSnapshot();

267

});

268

269

it('renders user card with actions', () => {

270

const snapshot = renderToSnapshot(

271

<UserCard user={mockUser} showActions={true} />

272

);

273

expect(snapshot).toMatchSnapshot();

274

});

275

});

276

```

277

278

### Conditional Rendering Snapshots

279

280

```javascript

281

import { renderToSnapshot } from 'inferno-test-utils';

282

283

function LoadingComponent({ isLoading, data, error }) {

284

if (error) {

285

return (

286

<div className="error">

287

<h3>Error occurred</h3>

288

<p>{error.message}</p>

289

<button>Retry</button>

290

</div>

291

);

292

}

293

294

if (isLoading) {

295

return (

296

<div className="loading">

297

<div className="spinner"></div>

298

<p>Loading...</p>

299

</div>

300

);

301

}

302

303

return (

304

<div className="data">

305

<h3>Data loaded</h3>

306

<ul>

307

{data.map(item => (

308

<li key={item.id}>{item.name}</li>

309

))}

310

</ul>

311

</div>

312

);

313

}

314

315

describe('LoadingComponent', () => {

316

it('renders loading state', () => {

317

const snapshot = renderToSnapshot(

318

<LoadingComponent isLoading={true} data={null} error={null} />

319

);

320

expect(snapshot).toMatchSnapshot();

321

});

322

323

it('renders error state', () => {

324

const error = { message: 'Failed to load data' };

325

const snapshot = renderToSnapshot(

326

<LoadingComponent isLoading={false} data={null} error={error} />

327

);

328

expect(snapshot).toMatchSnapshot();

329

});

330

331

it('renders data state', () => {

332

const data = [

333

{ id: 1, name: 'Item 1' },

334

{ id: 2, name: 'Item 2' }

335

];

336

const snapshot = renderToSnapshot(

337

<LoadingComponent isLoading={false} data={data} error={null} />

338

);

339

expect(snapshot).toMatchSnapshot();

340

});

341

});

342

```

343

344

## Types and Interfaces

345

346

### InfernoSnapshot

347

348

```typescript { .api }

349

interface InfernoSnapshot {

350

type: string;

351

props: Record<string, any>;

352

children: null | InfernoTestRendererNode[];

353

$$typeof?: symbol | string;

354

}

355

356

type InfernoTestRendererNode = InfernoSnapshot | string;

357

```

358

359

The InfernoSnapshot interface represents the structure of snapshot objects created by the testing utilities:

360

361

- **type**: The HTML tag name or component name as a string

362

- **props**: All props passed to the element/component (excludes children)

363

- **children**: Array of child snapshots or text content, null if no children

364

- **$$typeof**: React test renderer compatibility symbol

365

366

```javascript

367

import { vNodeToSnapshot } from 'inferno-test-utils';

368

369

const vnode = (

370

<div className="example" id="test">

371

<span>Text content</span>

372

<button disabled>Click me</button>

373

</div>

374

);

375

376

const snapshot = vNodeToSnapshot(vnode);

377

// Type: InfernoSnapshot

378

// {

379

// type: "div",

380

// props: { className: "example", id: "test" },

381

// children: [

382

// { type: "span", props: {}, children: ["Text content"] },

383

// { type: "button", props: { disabled: true }, children: ["Click me"] }

384

// ],

385

// $$typeof: Symbol(react.test.json)

386

// }

387

```

388

389

## Snapshot Testing Best Practices

390

391

### Testing Props Variations

392

393

```javascript

394

import { renderToSnapshot } from 'inferno-test-utils';

395

396

function Button({ variant, size, disabled, children }) {

397

const className = `btn btn-${variant} btn-${size}`;

398

return (

399

<button className={className} disabled={disabled}>

400

{children}

401

</button>

402

);

403

}

404

405

describe('Button component', () => {

406

const testCases = [

407

{ variant: 'primary', size: 'large', disabled: false },

408

{ variant: 'secondary', size: 'medium', disabled: false },

409

{ variant: 'danger', size: 'small', disabled: true }

410

];

411

412

testCases.forEach(({ variant, size, disabled }) => {

413

it(`renders ${variant} ${size} button (disabled: ${disabled})`, () => {

414

const snapshot = renderToSnapshot(

415

<Button variant={variant} size={size} disabled={disabled}>

416

Test Button

417

</Button>

418

);

419

expect(snapshot).toMatchSnapshot();

420

});

421

});

422

});

423

```

424

425

### Testing with Mock Data

426

427

```javascript

428

import { renderToSnapshot } from 'inferno-test-utils';

429

430

function ProductList({ products }) {

431

return (

432

<div className="product-list">

433

{products.map(product => (

434

<div key={product.id} className="product-item">

435

<h3>{product.name}</h3>

436

<p className="price">${product.price}</p>

437

<p className="description">{product.description}</p>

438

</div>

439

))}

440

</div>

441

);

442

}

443

444

describe('ProductList', () => {

445

it('renders empty list', () => {

446

const snapshot = renderToSnapshot(<ProductList products={[]} />);

447

expect(snapshot).toMatchSnapshot();

448

});

449

450

it('renders multiple products', () => {

451

const mockProducts = [

452

{ id: 1, name: 'Product 1', price: 10.99, description: 'Description 1' },

453

{ id: 2, name: 'Product 2', price: 15.99, description: 'Description 2' }

454

];

455

456

const snapshot = renderToSnapshot(<ProductList products={mockProducts} />);

457

expect(snapshot).toMatchSnapshot();

458

});

459

});

460

```

461

462

The Jest integration utilities ensure that your Inferno components can be tested with the same snapshot testing workflow as React components, providing consistency across different component libraries.