or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

babel-integration.mdcoverage-reading.mdindex.mdinstrumentation.md
tile.json

instrumentation.mddocs/

0

# Code Instrumentation

1

2

Core instrumentation functionality for transforming JavaScript code with coverage tracking capabilities. The instrumenter adds counters for statements, branches, and functions while preserving original code semantics.

3

4

## Capabilities

5

6

### Create Instrumenter

7

8

Creates a new instrumenter instance with configurable options for different instrumentation scenarios.

9

10

```javascript { .api }

11

/**

12

* Creates a new instrumenter with the supplied options

13

* @param opts - Instrumenter configuration options

14

* @returns New Instrumenter instance

15

*/

16

function createInstrumenter(opts?: InstrumenterOptions): Instrumenter;

17

18

interface InstrumenterOptions {

19

/** Name of global coverage variable (default: "__coverage__") */

20

coverageVariable?: string;

21

/** Report boolean value of logical expressions (default: false) */

22

reportLogic?: boolean;

23

/** Preserve comments in output (default: false) */

24

preserveComments?: boolean;

25

/** Generate compact code (default: true) */

26

compact?: boolean;

27

/** Set to true to instrument ES6 modules (default: false) */

28

esModules?: boolean;

29

/** Set to true to allow return statements outside of functions (default: false) */

30

autoWrap?: boolean;

31

/** Set to true to produce a source map for the instrumented code (default: false) */

32

produceSourceMap?: boolean;

33

/** Set to array of class method names to ignore for coverage (default: []) */

34

ignoreClassMethods?: string[];

35

/** Callback function called when a source map URL is found (default: null) */

36

sourceMapUrlCallback?: (filename: string, url: string) => void;

37

/** Turn debugging on (default: false) */

38

debug?: boolean;

39

/** Set babel parser plugins (default: from @istanbuljs/schema) */

40

parserPlugins?: string[];

41

/** The global coverage variable scope (default: "this") */

42

coverageGlobalScope?: string;

43

/** Use an evaluated function to find coverageGlobalScope (default: true) */

44

coverageGlobalScopeFunc?: boolean;

45

/** Set babel generator options */

46

generatorOpts?: object;

47

}

48

```

49

50

**Usage Examples:**

51

52

```javascript

53

const { createInstrumenter } = require("istanbul-lib-instrument");

54

55

// Basic instrumenter

56

const instrumenter = createInstrumenter();

57

58

// Instrumenter with custom options

59

const customInstrumenter = createInstrumenter({

60

coverageVariable: "__cov__",

61

esModules: true,

62

preserveComments: true,

63

produceSourceMap: true

64

});

65

66

// Instrumenter for browser environments

67

const browserInstrumenter = createInstrumenter({

68

coverageGlobalScope: "window",

69

compact: true,

70

reportLogic: true

71

});

72

```

73

74

### Instrumenter Class

75

76

Main instrumenter class providing synchronous and asynchronous instrumentation methods.

77

78

```javascript { .api }

79

class Instrumenter {

80

constructor(opts?: InstrumenterOptions);

81

}

82

```

83

84

### Synchronous Instrumentation

85

86

Transform code synchronously and track coverage against the supplied filename. Throws if invalid code is passed.

87

88

```javascript { .api }

89

/**

90

* Instrument the supplied code and track coverage against the supplied filename

91

* @param code - The code to instrument

92

* @param filename - The filename against which to track coverage

93

* @param inputSourceMap - Source map that maps uninstrumented code back to original form

94

* @returns The instrumented code

95

* @throws Error if invalid code is passed

96

*/

97

instrumentSync(code: string, filename: string, inputSourceMap?: object): string;

98

```

99

100

**Usage Examples:**

101

102

```javascript

103

const { createInstrumenter } = require("istanbul-lib-instrument");

104

105

const instrumenter = createInstrumenter();

106

107

// Basic instrumentation

108

const code = `

109

function calculateTax(price, rate) {

110

if (price > 0 && rate > 0) {

111

return price * rate;

112

}

113

return 0;

114

}

115

`;

116

117

const instrumentedCode = instrumenter.instrumentSync(code, 'tax-calculator.js');

118

119

// Instrumentation with source map

120

const sourceMap = { /* source map object */ };

121

const instrumentedWithMap = instrumenter.instrumentSync(

122

code,

123

'tax-calculator.js',

124

sourceMap

125

);

126

```

127

128

### Asynchronous Instrumentation

129

130

Callback-style instrument method that calls back with an error instead of throwing. Note that the callback is called synchronously.

131

132

```javascript { .api }

133

/**

134

* Callback-style instrument method that calls back with an error

135

* @param code - The code to instrument

136

* @param filename - The filename against which to track coverage

137

* @param callback - The callback function

138

* @param inputSourceMap - Source map that maps uninstrumented code back to original form

139

*/

140

instrument(

141

code: string,

142

filename: string,

143

callback: (err: Error | null, result?: string) => void,

144

inputSourceMap?: object

145

): void;

146

147

// Alternative signature with filename optional

148

instrument(

149

code: string,

150

callback: (err: Error | null, result?: string) => void,

151

inputSourceMap?: object

152

): void;

153

```

154

155

**Usage Examples:**

156

157

```javascript

158

const { createInstrumenter } = require("istanbul-lib-instrument");

159

160

const instrumenter = createInstrumenter();

161

162

// Callback-style instrumentation

163

instrumenter.instrument(code, 'calculator.js', (err, instrumentedCode) => {

164

if (err) {

165

console.error('Instrumentation failed:', err);

166

return;

167

}

168

console.log('Instrumented code:', instrumentedCode);

169

});

170

171

// With filename as optional parameter

172

instrumenter.instrument(code, (err, instrumentedCode) => {

173

if (err) {

174

console.error('Instrumentation failed:', err);

175

return;

176

}

177

// filename will be auto-generated

178

console.log('Instrumented code:', instrumentedCode);

179

});

180

```

181

182

### Coverage Data Access

183

184

Retrieve coverage information for the last instrumented file.

185

186

```javascript { .api }

187

/**

188

* Returns the file coverage object for the last file instrumented

189

* @returns The file coverage object with statement, branch, and function tracking

190

*/

191

lastFileCoverage(): object;

192

193

/**

194

* Returns the source map produced for the last file instrumented

195

* @returns The source map object or null if no source map was produced

196

*/

197

lastSourceMap(): object | null;

198

```

199

200

**Usage Examples:**

201

202

```javascript

203

const { createInstrumenter } = require("istanbul-lib-instrument");

204

205

const instrumenter = createInstrumenter({ produceSourceMap: true });

206

207

// Instrument code

208

const instrumentedCode = instrumenter.instrumentSync(code, 'example.js');

209

210

// Get coverage data structure

211

const coverage = instrumenter.lastFileCoverage();

212

console.log('Statement map:', coverage.statementMap);

213

console.log('Function map:', coverage.fnMap);

214

console.log('Branch map:', coverage.branchMap);

215

216

// Get source map if produced

217

const sourceMap = instrumenter.lastSourceMap();

218

if (sourceMap) {

219

console.log('Source map version:', sourceMap.version);

220

console.log('Source map mappings:', sourceMap.mappings);

221

}

222

```

223

224

## Configuration Options Details

225

226

### Coverage Variable Options

227

228

- **coverageVariable**: Name of the global variable where coverage data is stored

229

- **coverageGlobalScope**: The scope where the coverage variable is attached ("this", "window", "global")

230

- **coverageGlobalScopeFunc**: Whether to use an evaluated function to determine the scope

231

232

### Code Generation Options

233

234

- **compact**: Generate compact code without unnecessary whitespace

235

- **preserveComments**: Keep comments in the instrumented output

236

- **generatorOpts**: Pass-through options to Babel's code generator

237

238

### Module System Options

239

240

- **esModules**: Enable ES6 module instrumentation (required for `import`/`export`)

241

- **autoWrap**: Allow `return` statements outside functions (useful for module-level returns)

242

243

### Advanced Options

244

245

- **reportLogic**: Track boolean evaluation in logical expressions (&&, ||)

246

- **ignoreClassMethods**: Array of method names to skip instrumentation on classes

247

- **parserPlugins**: Babel parser plugins for advanced syntax support

248

- **produceSourceMap**: Generate source maps for debugging instrumented code

249

- **sourceMapUrlCallback**: Custom handling of source map URLs found in code

250

251

## Error Handling

252

253

The instrumenter can throw errors in several scenarios:

254

255

- **Invalid Code**: Syntax errors in the input JavaScript code

256

- **Parser Configuration**: Invalid parser plugin configurations

257

- **File System**: Issues accessing files when source maps are involved

258

259

```javascript

260

const { createInstrumenter } = require("istanbul-lib-instrument");

261

262

const instrumenter = createInstrumenter();

263

264

try {

265

const result = instrumenter.instrumentSync('invalid javascript code {', 'test.js');

266

} catch (error) {

267

console.error('Instrumentation failed:', error.message);

268

// Handle parsing or transformation errors

269

}

270

271

// For callback style, errors are passed to callback

272

instrumenter.instrument('invalid code', 'test.js', (err, result) => {

273

if (err) {

274

console.error('Instrumentation failed:', err.message);

275

return;

276

}

277

// Process result

278

});

279

```