0
# Advanced Features
1
2
Advanced functionality including RequireJS support, CoffeeScript integration, file watching, helper file loading, and programmatic test execution.
3
4
## Capabilities
5
6
### Programmatic Test Execution
7
8
Execute test suites programmatically with full configuration control.
9
10
```javascript { .api }
11
/**
12
* Execute specs in specified folders with comprehensive options
13
* @param options - Execution configuration object
14
*/
15
function executeSpecsInFolder(options: ExecutionOptions): void;
16
17
interface ExecutionOptions {
18
/** Array of directories containing spec files */
19
specFolders: string[];
20
/** Callback function when test execution completes */
21
onComplete?: (passed: boolean) => void;
22
/** Enable verbose output with detailed progress */
23
isVerbose?: boolean;
24
/** Enable colored terminal output */
25
showColors?: boolean;
26
/** Enable TeamCity reporter output */
27
teamcity?: boolean;
28
/** Enable RequireJS for spec loading (boolean or setup file path) */
29
useRequireJs?: boolean | string;
30
/** Regular expression for matching spec files */
31
regExpSpec?: RegExp;
32
/** JUnit XML report configuration */
33
junitreport?: JUnitReportConfig;
34
/** Include stack traces in error output */
35
includeStackTrace?: boolean;
36
/** Enable Growl desktop notifications */
37
growl?: boolean;
38
}
39
40
interface JUnitReportConfig {
41
/** Enable JUnit XML report generation */
42
report: boolean;
43
/** Directory path for saving XML reports */
44
savePath: string;
45
/** Use dot notation for nested describe blocks */
46
useDotNotation?: boolean;
47
/** Consolidate all results into single XML file */
48
consolidate?: boolean;
49
}
50
```
51
52
**Usage Examples:**
53
54
```javascript
55
const jasmine = require("jasmine-node");
56
57
// Basic programmatic execution
58
jasmine.executeSpecsInFolder({
59
specFolders: ['spec/', 'test/unit/'],
60
onComplete: function(passed) {
61
console.log("Tests " + (passed ? "PASSED" : "FAILED"));
62
process.exit(passed ? 0 : 1);
63
}
64
});
65
66
// Advanced configuration
67
jasmine.executeSpecsInFolder({
68
specFolders: ['spec/'],
69
isVerbose: true,
70
showColors: true,
71
includeStackTrace: true,
72
regExpSpec: /spec\.(js|coffee)$/i,
73
junitreport: {
74
report: true,
75
savePath: './test-reports/',
76
useDotNotation: true,
77
consolidate: true
78
},
79
growl: true,
80
onComplete: function(passed) {
81
if (!passed) {
82
console.error("Test failures detected!");
83
process.exit(1);
84
}
85
}
86
});
87
88
// RequireJS integration
89
jasmine.executeSpecsInFolder({
90
specFolders: ['spec/'],
91
useRequireJs: true, // Use default RequireJS setup
92
onComplete: function(passed) {
93
process.exit(passed ? 0 : 1);
94
}
95
});
96
97
// Custom RequireJS setup file
98
jasmine.executeSpecsInFolder({
99
specFolders: ['spec/'],
100
useRequireJs: './test/requirejs-config.js',
101
onComplete: function(passed) {
102
process.exit(passed ? 0 : 1);
103
}
104
});
105
```
106
107
### Helper File Loading
108
109
Automatically load helper functions and setup code before executing specs.
110
111
```javascript { .api }
112
/**
113
* Load helper files from a directory matching a pattern
114
* @param folder - Directory path containing helper files
115
* @param matcher - Regular expression for matching helper files
116
*/
117
function loadHelpersInFolder(folder: string, matcher?: RegExp): void;
118
```
119
120
**Usage Examples:**
121
122
```javascript
123
const jasmine = require("jasmine-node");
124
125
// Load all JavaScript helper files
126
jasmine.loadHelpersInFolder('./spec/helpers/');
127
128
// Load helpers with custom pattern
129
jasmine.loadHelpersInFolder('./test/support/', /helper\.(js|coffee)$/i);
130
131
// Multiple helper directories
132
jasmine.loadHelpersInFolder('./spec/helpers/');
133
jasmine.loadHelpersInFolder('./spec/fixtures/');
134
jasmine.loadHelpersInFolder('./spec/matchers/');
135
136
// Example helper file: spec/helpers/customMatchers.js
137
module.exports = {
138
toBeWithinRange: function(min, max) {
139
return this.actual >= min && this.actual <= max;
140
},
141
toHaveProperty: function(propertyName) {
142
return this.actual.hasOwnProperty(propertyName);
143
}
144
};
145
146
// Example helper file: spec/helpers/testSetup.js
147
module.exports = {
148
setupDatabase: function() {
149
// Database setup code
150
global.testDb = new MockDatabase();
151
},
152
153
cleanupDatabase: function() {
154
// Database cleanup code
155
if (global.testDb) {
156
global.testDb.close();
157
global.testDb = null;
158
}
159
}
160
};
161
```
162
163
### RequireJS Integration
164
165
Advanced module loading support for AMD-style projects using RequireJS. jasmine-node provides a specialized runner that executes specs in isolated contexts with proper RequireJS module resolution.
166
167
```javascript { .api }
168
/**
169
* Execute specs using RequireJS module loading in isolated VM contexts
170
* @param specCollection - Collection of spec files to execute
171
* @param done - Completion callback function
172
* @param jasmineEnv - Jasmine environment instance
173
* @param setupFile - Optional RequireJS configuration file path (defaults to built-in template)
174
*/
175
function executeJsRunner(
176
specCollection: SpecCollection,
177
done: (passed: boolean) => void,
178
jasmineEnv: jasmine.Env,
179
setupFile?: string
180
): void;
181
182
// RequireJS configuration object for setup files
183
interface RequireJSConfig {
184
/** Base URL for module resolution */
185
baseUrl?: string;
186
/** Path mappings for module names */
187
paths?: { [key: string]: string };
188
/** Shim configuration for non-AMD modules */
189
shim?: { [key: string]: any };
190
/** Dependencies to load before executing */
191
deps?: string[];
192
/** Callback function after configuration */
193
callback?: () => void;
194
}
195
```
196
197
The RequireJS runner creates isolated VM contexts for each spec file, ensuring proper module isolation while maintaining access to Jasmine globals (`describe`, `it`, `expect`, etc.). It uses a wrapper template that sets up RequireJS within each context and handles both JavaScript and CoffeeScript spec files.
198
199
**Usage Examples:**
200
201
```javascript
202
// RequireJS setup file: test/requirejs-config.js
203
require.config({
204
baseUrl: '../lib',
205
paths: {
206
'jquery': '../node_modules/jquery/dist/jquery',
207
'underscore': '../node_modules/underscore/underscore',
208
'backbone': '../node_modules/backbone/backbone'
209
},
210
shim: {
211
'backbone': {
212
deps: ['underscore', 'jquery'],
213
exports: 'Backbone'
214
}
215
}
216
});
217
218
// RequireJS spec file example: spec/modelSpec.js
219
define(['models/user', 'backbone'], function(User, Backbone) {
220
describe("User Model", function() {
221
it("should create a user instance", function() {
222
const user = new User({name: "John", email: "john@example.com"});
223
expect(user.get('name')).toBe("John");
224
});
225
226
it("should validate email format", function() {
227
const user = new User({name: "John", email: "invalid-email"});
228
expect(user.isValid()).toBe(false);
229
});
230
});
231
});
232
233
// Command line usage with RequireJS
234
// jasmine-node --runWithRequireJs --requireJsSetup ./test/requirejs-config.js spec/
235
```
236
237
### CoffeeScript Support
238
239
Full support for CoffeeScript and Literate CoffeeScript test files.
240
241
```coffeescript { .api }
242
# CoffeeScript spec file example: spec/calculatorSpec.coffee
243
describe "Calculator", ->
244
calculator = null
245
246
beforeEach ->
247
calculator = new Calculator()
248
249
it "should add two numbers", ->
250
result = calculator.add(2, 3)
251
expect(result).toEqual(5)
252
253
it "should handle async operations", (done) ->
254
calculator.asyncAdd 2, 3, (result) ->
255
expect(result).toEqual(5)
256
done()
257
258
# Literate CoffeeScript spec file example: spec/userSpec.litcoffee
259
# User Model Specifications
260
#
261
# This file contains specifications for the User model,
262
# demonstrating various user operations and validations.
263
264
describe "User Model", ->
265
266
## User Creation
267
268
When creating a new user, we need to ensure all required
269
fields are properly validated and stored.
270
271
it "should create user with valid data", ->
272
user = new User(name: "Alice", email: "alice@example.com")
273
expect(user.isValid()).toBe(true)
274
275
## Email Validation
276
277
The user model should validate email addresses using
278
standard email format validation.
279
280
it "should reject invalid email formats", ->
281
user = new User(name: "Bob", email: "invalid-email")
282
expect(user.isValid()).toBe(false)
283
```
284
285
### File Watching and Auto-Testing
286
287
Automatically re-run tests when source files or spec files change using the built-in autotest module.
288
289
```javascript { .api }
290
/**
291
* Start file watching for automatic test execution
292
* @param loadpaths - Directories containing spec files
293
* @param watchFolders - Additional directories to watch for changes
294
* @param patterns - File patterns to watch
295
*/
296
function start(loadpaths: string[], watchFolders: string[], patterns: string[]): void;
297
```
298
299
The autotest module uses the `gaze` library internally to watch for file changes and automatically re-runs the test suite when changes are detected. It maintains state about the last test run result and only shows output for subsequent runs.
300
301
**Usage Examples:**
302
303
```javascript
304
const autotest = require("jasmine-node/lib/jasmine-node/autotest");
305
306
// Basic auto-testing - watches spec files only
307
autotest.start(['spec/'], [], ['**/*.js']);
308
309
// Watch additional directories for source changes
310
autotest.start(
311
['spec/', 'test/'], // Spec directories to load tests from
312
['lib/', 'src/', 'app/'], // Additional directories to watch for changes
313
['**/*.js', '**/*.coffee'] // File patterns to monitor
314
);
315
316
// Custom patterns for different file types
317
autotest.start(
318
['spec/'],
319
['lib/', 'config/'],
320
['**/*.js', '**/*.json', '**/*.coffee']
321
);
322
323
// Single file watching (useful for focused testing)
324
autotest.start(['spec/userSpec.js'], ['lib/user.js'], ['**/*.js']);
325
```
326
327
### Spec Collection Management
328
329
Programmatically manage and filter spec files for execution using the built-in spec-collection module.
330
331
```javascript { .api }
332
/**
333
* Load spec files from directories using file pattern matching
334
* @param loadpaths - Array of directory paths to search
335
* @param matcher - Regular expression for matching spec files
336
*/
337
function load(loadpaths: string[], matcher: RegExp): void;
338
339
/**
340
* Get loaded spec files sorted alphabetically by path
341
* @returns Array of spec file objects with utility methods
342
*/
343
function getSpecs(): SpecFile[];
344
345
interface SpecFile {
346
/** Full file system path to spec file */
347
path(): string;
348
/** Relative path from root directory (with leading slash removed) */
349
relativePath(): string;
350
/** Directory containing the spec file (with forward slashes) */
351
directory(): string;
352
/** Relative directory path (with forward slashes) */
353
relativeDirectory(): string;
354
/** Filename only without path */
355
filename(): string;
356
}
357
```
358
359
The spec-collection module uses the `walkdir` library to recursively search directories for test files. It automatically excludes `node_modules` directories and sorts results alphabetically to ensure deterministic test execution order.
360
361
**Usage Examples:**
362
363
```javascript
364
const specCollection = require("jasmine-node/lib/jasmine-node/spec-collection");
365
366
// Load specs with default pattern
367
specCollection.load(['spec/', 'test/'], /spec\.(js|coffee)$/i);
368
369
// Get loaded specs
370
const specs = specCollection.getSpecs();
371
specs.forEach(function(spec) {
372
console.log("Found spec:", spec.relativePath());
373
console.log("Directory:", spec.directory());
374
console.log("Filename:", spec.filename());
375
});
376
377
// Custom filtering
378
specCollection.load(['spec/'], /integration.*spec\.js$/i);
379
const integrationSpecs = specCollection.getSpecs();
380
381
// Multiple pattern loading
382
specCollection.load(['spec/unit/'], /spec\.js$/i);
383
const unitSpecs = specCollection.getSpecs();
384
385
specCollection.load(['spec/e2e/'], /e2e.*spec\.js$/i);
386
const e2eSpecs = specCollection.getSpecs();
387
```
388
389
### Environment Configuration
390
391
Configure the global test environment and default behaviors.
392
393
```javascript { .api }
394
/**
395
* Global jasmine environment access
396
*/
397
declare namespace jasmine {
398
/** Default timeout for asynchronous operations */
399
var defaultTimeoutInterval: number;
400
401
/** Get the global object (window in browser, global in Node.js) */
402
function getGlobal(): any;
403
404
/** Get current Jasmine environment */
405
function getEnv(): jasmine.Env;
406
407
/** Reference to setTimeout for async operations */
408
var setTimeout: (fn: Function, delay: number) => any;
409
410
/** Reference to setInterval for async operations */
411
var setInterval: (fn: Function, delay: number) => any;
412
}
413
```
414
415
**Usage Examples:**
416
417
```javascript
418
const jasmine = require("jasmine-node");
419
420
// Configure default timeout for all async tests
421
jasmine.getEnv().defaultTimeoutInterval = 10000; // 10 seconds
422
423
// Set up global test environment
424
const testEnv = jasmine.getEnv();
425
426
// Add custom global functions
427
jasmine.getGlobal().customHelper = function() {
428
return "test helper function";
429
};
430
431
// Configure multiple reporters
432
testEnv.addReporter(new jasmine.TerminalReporter({ color: true }));
433
testEnv.addReporter(new jasmine.JUnitXmlReporter('./reports/'));
434
435
// Custom environment setup
436
testEnv.beforeEach(function() {
437
// Global setup before each test
438
jasmine.getGlobal().testStartTime = Date.now();
439
});
440
441
testEnv.afterEach(function() {
442
// Global cleanup after each test
443
const duration = Date.now() - jasmine.getGlobal().testStartTime;
444
if (duration > 1000) {
445
console.warn("Slow test detected:", duration + "ms");
446
}
447
});
448
449
// Execute with custom environment
450
testEnv.execute();
451
```
452
453
### Exception Handling
454
455
Advanced error handling and global exception capture.
456
457
```javascript { .api }
458
/**
459
* Configure global exception handling for tests
460
*/
461
interface ExceptionHandling {
462
/** Capture uncaught exceptions and continue testing */
463
captureExceptions: boolean;
464
/** Custom exception handler function */
465
exceptionHandler?: (error: Error) => void;
466
/** Force exit after test completion */
467
forceExit: boolean;
468
}
469
```
470
471
**Usage Examples:**
472
473
```javascript
474
// Global exception handling setup
475
process.on('uncaughtException', function(error) {
476
console.error("Uncaught exception in tests:", error);
477
process.exit(1);
478
});
479
480
// Custom exception handler
481
const handleTestException = function(error) {
482
console.error("Test exception:", error.message);
483
console.error("Stack:", error.stack);
484
485
// Log to file or external service
486
require('fs').appendFileSync('./test-errors.log',
487
new Date().toISOString() + ': ' + error.stack + '\n'
488
);
489
};
490
491
// Integration with jasmine-node CLI options
492
jasmine.executeSpecsInFolder({
493
specFolders: ['spec/'],
494
captureExceptions: true,
495
forceExit: true,
496
onComplete: function(passed) {
497
if (!passed) {
498
handleTestException(new Error("Tests failed"));
499
}
500
process.exit(passed ? 0 : 1);
501
}
502
});
503
```