The powerful, easy-to-use testing framework for JavaScript applications
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Helper functions for object comparison, type checking, serialization, and debugging that support QUnit's testing capabilities.
Compare complex objects and data structures for equality.
/**
* Deep equality comparison utility used by deepEqual assertions
* @param {any} a - First value to compare
* @param {any} b - Second value to compare
* @returns {boolean} True if values are deeply equal
*/
QUnit.equiv(a, b)Usage Examples:
import QUnit from "qunit";
QUnit.test("manual deep comparison", function(assert) {
const obj1 = { name: "Alice", settings: { theme: "dark", lang: "en" } };
const obj2 = { name: "Alice", settings: { theme: "dark", lang: "en" } };
const obj3 = { name: "Bob", settings: { theme: "light", lang: "fr" } };
assert.ok(QUnit.equiv(obj1, obj2), "objects with same structure and values are equal");
assert.notOk(QUnit.equiv(obj1, obj3), "objects with different values are not equal");
// Arrays
assert.ok(QUnit.equiv([1, 2, 3], [1, 2, 3]), "arrays with same elements are equal");
assert.notOk(QUnit.equiv([1, 2, 3], [1, 2, 4]), "arrays with different elements are not equal");
// Nested structures
const complex1 = { users: [{ id: 1, name: "Alice" }], meta: { count: 1 } };
const complex2 = { users: [{ id: 1, name: "Alice" }], meta: { count: 1 } };
assert.ok(QUnit.equiv(complex1, complex2), "complex nested structures can be compared");
});Serialize objects for display and debugging purposes.
/**
* Serialize object to human-readable string representation
* @param {any} obj - Object to serialize
* @returns {string} String representation of the object
*/
QUnit.dump.parse(obj)Usage Examples:
QUnit.test("object serialization", function(assert) {
const user = { id: 1, name: "Alice", active: true, tags: ["admin", "user"] };
const serialized = QUnit.dump.parse(user);
console.log("User object:", serialized);
// Output: { "id": 1, "name": "Alice", "active": true, "tags": [ "admin", "user" ] }
// Useful for debugging complex objects
const complexObj = {
nested: { deep: { value: 42 } },
fn: function() { return "test"; },
date: new Date("2023-01-01"),
regex: /test/gi
};
console.log("Complex object:", QUnit.dump.parse(complexObj));
assert.ok(typeof serialized === "string", "returns string representation");
});Detailed type checking utilities for runtime type validation.
/**
* Check if value matches specific type
* @param {string} type - Type name to check against
* @param {any} obj - Value to check
* @returns {boolean} True if value matches the specified type
*/
QUnit.is(type, obj)
/**
* Get detailed object type information
* @param {any} obj - Object to analyze
* @returns {string} String describing the object's type
*/
QUnit.objectType(obj)Usage Examples:
QUnit.test("type checking utilities", function(assert) {
// Type checking - QUnit.is checks against specific type names
// Common types: 'string', 'number', 'boolean', 'object', 'array', 'function'
// 'null', 'undefined', 'regexp', 'date', etc.
assert.ok(QUnit.is('string', 'hello'), 'identifies strings');
assert.ok(QUnit.is('number', 42), 'identifies numbers');
assert.ok(QUnit.is('boolean', true), 'identifies booleans');
assert.ok(QUnit.is('array', [1, 2, 3]), 'identifies arrays');
assert.ok(QUnit.is('object', { key: 'value' }), 'identifies objects');
assert.ok(QUnit.is('function', function() {}), 'identifies functions');
// Object type analysis - returns specific type strings
assert.strictEqual(QUnit.objectType('hello'), 'string');
assert.strictEqual(QUnit.objectType([1, 2, 3]), 'array');
assert.strictEqual(QUnit.objectType(new Date()), 'date');
assert.strictEqual(QUnit.objectType(/test/), 'regexp');
assert.strictEqual(QUnit.objectType(null), 'null');
assert.strictEqual(QUnit.objectType(undefined), 'undefined');
// Custom objects
function CustomClass() {}
const instance = new CustomClass();
assert.strictEqual(QUnit.objectType(instance), "object");
});Calculate and display differences between values for better error reporting.
/**
* Calculate difference between two values for assertion error reporting
* @param {any} a - First value
* @param {any} b - Second value
* @returns {string|null} String describing the differences or null if no meaningful diff
*/
QUnit.diff(a, b)Usage Examples:
QUnit.test("difference calculation", function(assert) {
const original = "The quick brown fox";
const modified = "The quick blue fox";
const difference = QUnit.diff(original, modified);
console.log("String difference:", difference);
// Object differences
const obj1 = { name: "Alice", age: 30, city: "New York" };
const obj2 = { name: "Alice", age: 31, city: "Boston" };
const objDiff = QUnit.diff(obj1, obj2);
console.log("Object difference:", objDiff);
// Array differences
const arr1 = [1, 2, 3, 4, 5];
const arr2 = [1, 2, 4, 5, 6];
const arrDiff = QUnit.diff(arr1, arr2);
console.log("Array difference:", arrDiff);
// No difference
const noDiff = QUnit.diff("same", "same");
assert.strictEqual(noDiff, null, "returns null when values are equal");
});
// Custom assertion using diff
QUnit.test("custom assertion with diff", function(assert) {
function customDeepEqual(actual, expected, message) {
const isEqual = QUnit.equiv(actual, expected);
if (!isEqual) {
const difference = QUnit.diff(actual, expected);
const enhancedMessage = message + (difference ? `\nDifference: ${difference}` : "");
assert.pushResult({
result: false,
actual: actual,
expected: expected,
message: enhancedMessage
});
} else {
assert.pushResult({
result: true,
actual: actual,
expected: expected,
message: message
});
}
}
const user1 = { name: "Alice", age: 30, roles: ["admin"] };
const user2 = { name: "Alice", age: 31, roles: ["user"] };
customDeepEqual(user1, user2, "users should be equal");
});Generate and analyze stack traces for debugging and error reporting.
/**
* Get stack trace with optional offset
* @param {number} [offset=0] - Number of stack frames to skip
* @returns {string} Stack trace string
*/
QUnit.stack(offset)Usage Examples:
QUnit.test("stack trace utilities", function(assert) {
function helperFunction() {
// Get stack trace from current location
return QUnit.stack();
}
function wrapperFunction() {
return helperFunction();
}
const stackTrace = wrapperFunction();
console.log("Stack trace:", stackTrace);
// Skip frames to get cleaner stack traces
const cleanStack = QUnit.stack(2); // Skip 2 frames
console.log("Clean stack trace:", cleanStack);
assert.ok(typeof stackTrace === "string", "returns string");
assert.ok(stackTrace.length > 0, "stack trace is not empty");
});Combine utilities for advanced testing scenarios.
Usage Examples:
QUnit.test("combined utility usage", function(assert) {
// Custom comparison with detailed reporting
function advancedCompare(actual, expected, message) {
const type1 = QUnit.objectType(actual);
const type2 = QUnit.objectType(expected);
if (type1 !== type2) {
assert.pushResult({
result: false,
actual: `${type1}: ${QUnit.dump.parse(actual)}`,
expected: `${type2}: ${QUnit.dump.parse(expected)}`,
message: `${message} - Type mismatch`
});
return;
}
const isEqual = QUnit.equiv(actual, expected);
if (!isEqual) {
const difference = QUnit.diff(actual, expected);
assert.pushResult({
result: false,
actual: QUnit.dump.parse(actual),
expected: QUnit.dump.parse(expected),
message: `${message}${difference ? `\nDiff: ${difference}` : ""}`
});
} else {
assert.pushResult({
result: true,
actual: actual,
expected: expected,
message: message
});
}
}
// Test the custom comparison
const obj1 = { users: [{ name: "Alice" }], count: 1 };
const obj2 = { users: [{ name: "Bob" }], count: 1 };
advancedCompare(obj1, obj2, "complex objects should be equal");
});
// Performance testing helper
QUnit.test("performance testing utilities", function(assert) {
function performanceTest(fn, iterations = 1000) {
const start = performance.now();
for (let i = 0; i < iterations; i++) {
fn();
}
const duration = performance.now() - start;
const avgTime = duration / iterations;
return {
totalTime: duration,
averageTime: avgTime,
iterations: iterations
};
}
// Test object comparison performance
const largeObj1 = { data: new Array(1000).fill(0).map((_, i) => ({ id: i, value: i * 2 })) };
const largeObj2 = { data: new Array(1000).fill(0).map((_, i) => ({ id: i, value: i * 2 })) };
const perfResult = performanceTest(() => {
QUnit.equiv(largeObj1, largeObj2);
}, 100);
console.log(`Comparison performance: ${perfResult.averageTime.toFixed(3)}ms average`);
assert.ok(perfResult.averageTime < 100, "comparison should be reasonably fast");
});The following utility functions are available on the QUnit object:
/**
* Core utility functions available in QUnit v2.24.1
*/
// Deep comparison
QUnit.equiv(a, b) // Deep equivalence check used by deepEqual
// Object serialization
QUnit.dump.parse(obj) // Convert object to string representation
// Type checking
QUnit.is(type, obj) // Check if object matches type
QUnit.objectType(obj) // Get detailed type information
// Debugging utilities
QUnit.diff(a, b) // Generate diff between values (used in error reporting)
QUnit.stack(offset) // Get stack trace with optional frame offset
// Configuration and state
QUnit.config // Configuration object
QUnit.version // QUnit version string
QUnit.isLocal // Whether running from file:// protocol
// Test execution control
QUnit.start() // Start test execution (when autostart is false)
QUnit.pushFailure(msg, source) // Push test failure
// Error handling
QUnit.onError(callback) // Register global error handler
QUnit.onUncaughtException(callback) // Register uncaught exception handlerThe QUnit.objectType() and QUnit.is() functions recognize these type strings:
'string' - String values'number' - Number values (including NaN)'boolean' - Boolean values'object' - Plain objects and custom objects'array' - Array objects'function' - Function objects'regexp' - Regular expression objects'date' - Date objects'null' - null value'undefined' - undefined valueQUnit.equiv() handles circular references and provides deep comparisonQUnit.dump.parse() respects QUnit.config.maxDepth for object traversalQUnit.diff() may return null if no meaningful difference can be calculatedQUnit.stack() provides clean stack traces for error reportingInstall with Tessl CLI
npx tessl i tessl/npm-qunit