or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cleanup.mderror-snapshots.mdindex.mdpath-resolution.mdserialization.mdsnapshot-matchers.mdstate-management.md
tile.json

path-resolution.mddocs/

0

# Path Resolution

1

2

Snapshot file path management system that handles the relationship between test files and their corresponding snapshot files. Provides flexible path resolution with support for custom snapshot resolvers.

3

4

## Capabilities

5

6

### Snapshot Resolver

7

8

Interface for converting between test file paths and snapshot file paths, enabling customizable snapshot file organization.

9

10

```typescript { .api }

11

interface SnapshotResolver {

12

/**

13

* Resolves from test path to snapshot path

14

* @param testPath - Path to the test file

15

* @param snapshotExtension - Optional snapshot file extension (defaults to 'snap')

16

* @returns Path to the corresponding snapshot file

17

*/

18

resolveSnapshotPath(testPath: string, snapshotExtension?: string): string;

19

20

/**

21

* Resolves from snapshot path to test path

22

* @param snapshotPath - Path to the snapshot file

23

* @param snapshotExtension - Optional snapshot file extension (defaults to 'snap')

24

* @returns Path to the corresponding test file

25

*/

26

resolveTestPath(snapshotPath: string, snapshotExtension?: string): string;

27

28

/**

29

* Example test path used for consistency checking

30

* Must be a valid test path that can be resolved both ways

31

*/

32

testPathForConsistencyCheck: string;

33

}

34

```

35

36

### buildSnapshotResolver

37

38

Creates a snapshot resolver instance based on Jest configuration, with support for custom resolvers and caching.

39

40

```typescript { .api }

41

/**

42

* Builds a snapshot resolver for converting between test and snapshot paths

43

* @param config - Jest project configuration

44

* @param localRequire - Optional require function for loading custom resolvers

45

* @returns Promise resolving to a SnapshotResolver instance

46

*/

47

async function buildSnapshotResolver(

48

config: Config.ProjectConfig,

49

localRequire?: Promise<LocalRequire> | LocalRequire

50

): Promise<SnapshotResolver>;

51

52

type LocalRequire = (module: string) => unknown;

53

```

54

55

**Usage Examples:**

56

57

```typescript

58

import { buildSnapshotResolver } from "jest-snapshot";

59

60

// Basic resolver creation

61

const resolver = await buildSnapshotResolver({

62

rootDir: '/project/root',

63

snapshotResolver: undefined // use default resolver

64

});

65

66

// Custom resolver

67

const resolver = await buildSnapshotResolver({

68

rootDir: '/project/root',

69

snapshotResolver: './custom-snapshot-resolver.js'

70

});

71

72

// Use resolver to convert paths

73

const snapshotPath = resolver.resolveSnapshotPath(

74

'/project/src/components/Button.test.js'

75

);

76

// Returns: '/project/src/components/__snapshots__/Button.test.js.snap'

77

78

const testPath = resolver.resolveTestPath(

79

'/project/src/__snapshots__/utils.test.js.snap'

80

);

81

// Returns: '/project/src/utils.test.js'

82

```

83

84

### Default Path Resolution

85

86

The default snapshot resolver follows Jest's standard conventions:

87

88

**Test to Snapshot Path:**

89

- `src/components/Button.test.js``src/components/__snapshots__/Button.test.js.snap`

90

- `tests/user.spec.ts``tests/__snapshots__/user.spec.ts.snap`

91

- `app.test.jsx``__snapshots__/app.test.jsx.snap`

92

93

**Snapshot to Test Path:**

94

- `__snapshots__/Button.test.js.snap``Button.test.js`

95

- `src/__snapshots__/utils.spec.ts.snap``src/utils.spec.ts`

96

97

### Custom Snapshot Resolvers

98

99

Create custom resolvers to implement different snapshot organization strategies:

100

101

```javascript

102

// custom-snapshot-resolver.js

103

module.exports = {

104

// Resolve from test path to snapshot path

105

resolveSnapshotPath: (testPath, snapshotExtension) => {

106

// Custom logic: place all snapshots in a single directory

107

const testName = path.basename(testPath);

108

return path.join(

109

path.dirname(testPath),

110

'snapshots',

111

`${testName}.${snapshotExtension || 'snap'}`

112

);

113

},

114

115

// Resolve from snapshot path to test path

116

resolveTestPath: (snapshotPath, snapshotExtension) => {

117

// Reverse the custom logic

118

const snapshotName = path.basename(snapshotPath, `.${snapshotExtension || 'snap'}`);

119

return path.join(path.dirname(path.dirname(snapshotPath)), snapshotName);

120

},

121

122

// Example test path for consistency checking

123

testPathForConsistencyCheck: 'example.test.js'

124

};

125

```

126

127

### Path Utilities

128

129

Utility functions for working with snapshot file paths.

130

131

```typescript { .api }

132

/**

133

* Checks if a given path is a snapshot file

134

* @param path - File path to check

135

* @returns True if the path ends with the snapshot extension

136

*/

137

function isSnapshotPath(path: string): boolean;

138

139

/**

140

* Snapshot file extension constant

141

*/

142

const EXTENSION: string; // 'snap'

143

144

/**

145

* Dot-prefixed snapshot extension

146

*/

147

const DOT_EXTENSION: string; // '.snap'

148

```

149

150

**Usage Examples:**

151

152

```typescript

153

import { isSnapshotPath, EXTENSION, DOT_EXTENSION } from "jest-snapshot";

154

155

// Check if path is a snapshot file

156

console.log(isSnapshotPath('Button.test.js.snap')); // true

157

console.log(isSnapshotPath('Button.test.js')); // false

158

159

// Use extension constants

160

const snapshotFile = `test.${EXTENSION}`; // 'test.snap'

161

const pattern = `*${DOT_EXTENSION}`; // '*.snap'

162

```

163

164

### Resolver Caching

165

166

The `buildSnapshotResolver` function implements caching to avoid recreating resolvers:

167

168

```typescript

169

// Cached by config.rootDir

170

const resolver1 = await buildSnapshotResolver(config);

171

const resolver2 = await buildSnapshotResolver(config);

172

// resolver1 === resolver2 (same instance from cache)

173

174

// Different rootDir = different cache entry

175

const differentConfig = { ...config, rootDir: '/different/path' };

176

const resolver3 = await buildSnapshotResolver(differentConfig);

177

// resolver3 !== resolver1 (different instance)

178

```

179

180

### Resolver Validation

181

182

Custom resolvers must pass consistency checks:

183

184

```typescript

185

// Resolver consistency check

186

const resolver = {

187

resolveSnapshotPath: (testPath) => `/snapshots/${path.basename(testPath)}.snap`,

188

resolveTestPath: (snapshotPath) => path.basename(snapshotPath, '.snap'),

189

testPathForConsistencyCheck: 'example.test.js'

190

};

191

192

// Jest validates:

193

// 1. testPath -> snapshotPath -> testPath should return original

194

// 2. Both functions should be consistent

195

```

196

197

### Integration with FileSystem

198

199

Resolvers work with Jest's file system abstraction:

200

201

```typescript

202

import { cleanup } from "jest-snapshot";

203

204

// Use resolver in cleanup operations

205

const result = cleanup(

206

fileSystem,

207

updateMode,

208

resolver,

209

testPathIgnorePatterns

210

);

211

212

// Resolver is used to:

213

// 1. Find all snapshot files matching the pattern

214

// 2. Convert snapshot paths back to test paths

215

// 3. Check if corresponding test files exist

216

```

217

218

## Error Handling

219

220

```typescript

221

// Invalid custom resolver

222

await buildSnapshotResolver({

223

rootDir: '/project',

224

snapshotResolver: './missing-resolver.js'

225

});

226

// Error: Cannot resolve module './missing-resolver.js'

227

228

// Inconsistent resolver functions

229

const badResolver = {

230

resolveSnapshotPath: (testPath) => 'snapshot.snap',

231

resolveTestPath: (snapshotPath) => 'different.test.js',

232

testPathForConsistencyCheck: 'test.js'

233

};

234

// Error: Inconsistent snapshot resolver implementation

235

236

// Missing required methods

237

const incompleteResolver = {

238

resolveSnapshotPath: (testPath) => `${testPath}.snap`

239

// Missing resolveTestPath and testPathForConsistencyCheck

240

};

241

// Error: Invalid snapshot resolver

242

```

243

244

## Types

245

246

```typescript { .api }

247

interface Config {

248

rootDir: string;

249

snapshotResolver?: string; // Path to custom resolver module

250

}

251

252

type LocalRequire = (module: string) => unknown;

253

254

interface ResolverCache extends Map<string, SnapshotResolver> {}

255

```