0
# Dependency Constraints
1
2
Environment dependency validation system for conditional test execution based on package versions and availability.
3
4
## Capabilities
5
6
### Dependency Constraint System
7
8
Version constraint specification for conditional test execution based on environment requirements.
9
10
```typescript { .api }
11
/**
12
* Map of package names to version constraints for conditional test execution
13
*/
14
type DependencyConstraint = Readonly<Record<string, VersionConstraint>>;
15
16
/**
17
* Version constraint specification - either a simple version string or complex semver range
18
*/
19
type VersionConstraint = AtLeastVersionConstraint | SemverVersionConstraint;
20
```
21
22
**Usage Examples:**
23
24
```typescript
25
import { RuleTester } from "@typescript-eslint/rule-tester";
26
27
// Test suite with TypeScript version constraint
28
const ruleTester = new RuleTester({
29
dependencyConstraints: {
30
typescript: ">=4.0.0",
31
},
32
});
33
34
// Individual test case with multiple constraints
35
const testCase = {
36
code: "const x: bigint = 123n;",
37
dependencyConstraints: {
38
typescript: ">=3.2.0",
39
"@typescript-eslint/parser": ">=4.0.0",
40
node: ">=10.4.0",
41
},
42
};
43
```
44
45
### Simple Version Constraints
46
47
Shorthand version constraints using "at least version" format.
48
49
```typescript { .api }
50
/**
51
* Minimum version constraint shorthand (equivalent to '>=' constraint)
52
*/
53
type AtLeastVersionConstraint =
54
| `${number}.${number}.${number}-${string}` // e.g., "4.1.0-beta"
55
| `${number}.${number}.${number}` // e.g., "4.1.0"
56
| `${number}.${number}` // e.g., "4.1"
57
| `${number}`; // e.g., "4"
58
```
59
60
**Usage Examples:**
61
62
```typescript
63
const constraints = {
64
// Exact version with prerelease
65
typescript: "4.1.0-beta.1" as AtLeastVersionConstraint,
66
67
// Exact version
68
eslint: "8.0.0" as AtLeastVersionConstraint,
69
70
// Major.minor version
71
node: "16.0" as AtLeastVersionConstraint,
72
73
// Major version only
74
npm: "7" as AtLeastVersionConstraint,
75
};
76
77
// Test case that only runs with TypeScript 4.5 or higher
78
const advancedTypeTest = {
79
code: "type Template<T extends string> = `Hello ${T}`;",
80
dependencyConstraints: {
81
typescript: "4.5.0",
82
},
83
};
84
```
85
86
### Complex Version Constraints
87
88
Advanced semver range constraints with optional configuration.
89
90
```typescript { .api }
91
/**
92
* Advanced semver version constraint with range and options
93
*/
94
interface SemverVersionConstraint {
95
/** Semver range string (e.g., "^4.0.0", ">=3.0.0 <5.0.0") */
96
readonly range: string;
97
/** Semver parsing and matching options */
98
readonly options?: boolean | RangeOptions;
99
}
100
101
/**
102
* Options for semver range parsing and matching
103
*/
104
interface RangeOptions {
105
/** Include prerelease versions in range matching */
106
includePrerelease?: boolean;
107
/** Use loose semver parsing (more permissive) */
108
loose?: boolean;
109
}
110
```
111
112
**Usage Examples:**
113
114
```typescript
115
const complexConstraints: Record<string, SemverVersionConstraint> = {
116
// Caret range (compatible versions)
117
typescript: {
118
range: "^4.0.0",
119
options: { includePrerelease: false },
120
},
121
122
// Tilde range (patch-level changes)
123
eslint: {
124
range: "~8.0.0",
125
},
126
127
// Complex range with multiple conditions
128
node: {
129
range: ">=14.0.0 <18.0.0",
130
options: { loose: true },
131
},
132
133
// Range with prerelease support
134
"@typescript-eslint/parser": {
135
range: ">=5.0.0-0",
136
options: {
137
includePrerelease: true,
138
loose: false,
139
},
140
},
141
};
142
143
// Test case with complex version requirements
144
const modernSyntaxTest = {
145
code: "const obj = { ...spread, newProp: 'value' };",
146
dependencyConstraints: {
147
typescript: {
148
range: "^4.1.0",
149
options: { includePrerelease: false },
150
},
151
node: {
152
range: ">=12.0.0",
153
},
154
},
155
};
156
```
157
158
### Practical Usage Patterns
159
160
Real-world examples of dependency constraints in test scenarios.
161
162
**TypeScript Feature Testing:**
163
164
```typescript
165
// Test modern TypeScript features
166
const templateLiteralTest = {
167
code: `
168
type EventName<T extends string> = \`on\${Capitalize<T>}\`;
169
type Handler = EventName<'click'>;
170
`,
171
dependencyConstraints: {
172
typescript: "4.1.0", // Template literal types introduced in 4.1
173
},
174
};
175
176
// Test conditional types (TypeScript 2.8+)
177
const conditionalTypeTest = {
178
code: "type NonNullable<T> = T extends null | undefined ? never : T;",
179
dependencyConstraints: {
180
typescript: "2.8.0",
181
},
182
};
183
```
184
185
**Environment-Specific Testing:**
186
187
```typescript
188
// Node.js specific features
189
const nodeFeatureTest = {
190
code: "import { Worker } from 'worker_threads';",
191
dependencyConstraints: {
192
node: "10.5.0", // Worker threads introduced in Node 10.5
193
},
194
};
195
196
// ES Module support
197
const esmTest = {
198
code: "export const value = await import('./module.js');",
199
dependencyConstraints: {
200
node: "14.0.0", // Top-level await in modules
201
},
202
languageOptions: {
203
parserOptions: {
204
sourceType: 'module',
205
ecmaVersion: 2022,
206
},
207
},
208
};
209
```
210
211
**Parser Version Testing:**
212
213
```typescript
214
// Test with specific parser capabilities
215
const parserFeatureTest = {
216
code: "class Example { #private = 42; }",
217
dependencyConstraints: {
218
"@typescript-eslint/parser": "4.0.0", // Private fields support
219
typescript: "3.8.0",
220
},
221
};
222
223
// Test with ESLint version requirements
224
const eslintFeatureTest = {
225
code: "const config = { rules: { 'new-rule': 'error' } };",
226
dependencyConstraints: {
227
eslint: {
228
range: ">=8.0.0", // Modern ESLint features
229
},
230
},
231
};
232
```
233
234
**Multi-Package Constraints:**
235
236
```typescript
237
// Test requiring multiple package versions
238
const fullStackTest = {
239
code: `
240
import type { Config } from '@typescript-eslint/utils';
241
const config: Config = { rules: {} };
242
`,
243
dependencyConstraints: {
244
typescript: ">=4.0.0",
245
"@typescript-eslint/utils": "^5.0.0",
246
"@typescript-eslint/parser": "^5.0.0",
247
eslint: {
248
range: ">=7.0.0 <9.0.0",
249
options: { includePrerelease: false },
250
},
251
},
252
};
253
```
254
255
**Constraint Configuration Strategies:**
256
257
```typescript
258
// Global constraints for entire test suite
259
const ruleTester = new RuleTester({
260
dependencyConstraints: {
261
typescript: ">=4.0.0", // Minimum TypeScript version for all tests
262
node: ">=14.0.0", // Minimum Node.js version
263
},
264
});
265
266
// Override constraints for specific test cases
267
ruleTester.run("my-rule", myRule, {
268
valid: [
269
// Standard test (uses global constraints)
270
"const x = 1;",
271
272
// Advanced test with higher requirements
273
{
274
code: "const obj = { ...props, key: 'value' };",
275
dependencyConstraints: {
276
typescript: ">=4.2.0", // Object spread requires 4.2+
277
},
278
},
279
],
280
invalid: [
281
{
282
code: "var x = 1;",
283
errors: [{ messageId: "noVar" }],
284
// Uses global constraints by default
285
},
286
],
287
});
288
```
289
290
## Constraint Validation
291
292
The dependency constraint system automatically validates environment requirements before executing tests:
293
294
1. **Package Detection**: Automatically detects installed package versions
295
2. **Version Comparison**: Uses semver-compatible version comparison
296
3. **Test Skipping**: Gracefully skips tests when constraints aren't met
297
4. **Error Reporting**: Provides clear messages when dependencies are missing or incompatible
298
299
**Example Constraint Validation Messages:**
300
301
```
302
✓ typescript@4.5.2 satisfies constraint ">=4.0.0"
303
⚠ Skipping test: node@12.22.0 does not satisfy constraint ">=14.0.0"
304
✗ Error: Package "@typescript-eslint/parser" not found, required by constraint ">=5.0.0"
305
```