Global configuration options for customizing @hapi/code behavior.
The
settings/**
* Global settings object for configuring @hapi/code behavior
*/
const settings = {
truncateMessages: false, // Truncate long error messages for readability
comparePrototypes: false // Include object prototypes in deep comparisons
};Controls whether long assertion error messages are truncated for improved readability.
/**
* Truncate long assertion error messages for readability
* @type {boolean}
* @default false
*/
settings.truncateMessagesUsage Examples:
const Code = require('@hapi/code');
const expect = Code.expect;
// Default behavior - full error messages
Code.settings.truncateMessages = false;
const longObject = {
property1: 'very long string value that will appear in full',
property2: 'another long string value',
property3: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
nested: {
deep: {
value: 'deeply nested long value'
}
}
};
try {
expect(longObject).to.equal({different: 'object'});
} catch (err) {
console.log(err.message); // Full object representation
}
// Truncated messages for readability
Code.settings.truncateMessages = true;
try {
expect(longObject).to.equal({different: 'object'});
} catch (err) {
console.log(err.message); // Truncated representation like "{ Object (property1, property2, ...) }"
}Truncation Rules:
// Examples of truncated output
Code.settings.truncateMessages = true;
// Long string
const longStr = "This is a very long string that exceeds the 40 character limit";
// Error message shows: "This is a very long string that exceeds t..."
// Large array
const largeArray = new Array(100).fill(0);
// Error message shows: "[Array(100)]"
// Complex object
const complexObj = {a: 1, b: 2, c: 3, d: 4, e: 5};
// Error message shows: "{ Object (a, b, ...) }"Controls whether object prototypes are included in deep equality comparisons.
/**
* Include object prototypes when doing deep comparisons
* @type {boolean}
* @default false
*/
settings.comparePrototypesUsage Examples:
// Default behavior - ignore prototypes
Code.settings.comparePrototypes = false;
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
return `Hello, ${this.name}`;
};
const person1 = new Person('Alice');
const person2 = {name: 'Alice'}; // Plain object without prototype
// This passes - prototypes ignored
expect(person1).to.equal(person2);
// Enable prototype comparison
Code.settings.comparePrototypes = true;
// This fails - person1 has Person.prototype, person2 doesn't
expect(person1).to.not.equal(person2);
// This passes - both have same prototype
const person3 = new Person('Alice');
expect(person1).to.equal(person3);Advanced Prototype Scenarios:
// Custom prototypes
const proto1 = {type: 'custom'};
const proto2 = {type: 'custom'};
const obj1 = Object.create(proto1);
obj1.value = 42;
const obj2 = Object.create(proto2);
obj2.value = 42;
// With prototype comparison disabled
Code.settings.comparePrototypes = false;
expect(obj1).to.equal(obj2); // Passes - only comparing own properties
// With prototype comparison enabled
Code.settings.comparePrototypes = true;
expect(obj1).to.not.equal(obj2); // Fails - different prototype objects
// Same prototype reference
const obj3 = Object.create(proto1);
obj3.value = 42;
expect(obj1).to.equal(obj3); // Passes - same prototype referenceSome methods accept options that override global settings for specific assertions:
/**
* Options for equal() method comparisons
*/
interface EqualOptions {
prototype?: boolean; // Override global comparePrototypes setting
deepFunction?: boolean; // Compare function implementations (default: true)
}Usage Examples:
const Code = require('@hapi/code');
const expect = Code.expect;
// Global setting
Code.settings.comparePrototypes = false;
const person1 = new Person('Alice');
const person2 = {name: 'Alice'};
// Override global setting for this assertion
expect(person1).to.equal(person2, {prototype: true}); // Fails - overrides global setting
// Function comparison options
const func1 = function(x) { return x * 2; };
const func2 = function(x) { return x * 2; };
const func3 = func1;
expect({fn: func1}).to.equal({fn: func2}, {deepFunction: true}); // Compare implementations
expect({fn: func1}).to.equal({fn: func3}, {deepFunction: false}); // Reference comparison only// Configure at test suite start
const Code = require('@hapi/code');
// Set global configuration for all tests
Code.settings.truncateMessages = true; // Cleaner error output
Code.settings.comparePrototypes = false; // Typical for most use cases
// Example test configuration
describe('API Tests', () => {
before(() => {
// Override settings for specific test suites
Code.settings.truncateMessages = false; // Full details for debugging
});
after(() => {
// Restore settings
Code.settings.truncateMessages = true;
});
});// Configure based on environment
const Code = require('@hapi/code');
if (process.env.NODE_ENV === 'development') {
Code.settings.truncateMessages = false; // Full error details for debugging
} else {
Code.settings.truncateMessages = true; // Cleaner output for CI/production
}
// Always customize for specific needs
if (process.env.DETAILED_ERRORS === 'true') {
Code.settings.truncateMessages = false;
}// Save and restore settings
const Code = require('@hapi/code');
const expect = Code.expect;
function withSettings(newSettings, testFn) {
const originalSettings = {...Code.settings};
try {
Object.assign(Code.settings, newSettings);
return testFn();
} finally {
Object.assign(Code.settings, originalSettings);
}
}
// Usage
withSettings({truncateMessages: false}, () => {
// Tests that need full error messages
expect(complexObject).to.equal(otherComplexObject);
});
// Settings automatically restored after testconst Lab = require('@hapi/lab');
const Code = require('@hapi/code');
const lab = exports.lab = Lab.script();
const expect = Code.expect;
// Configure for lab integration
lab.before(() => {
// Optimal settings for lab test runner
Code.settings.truncateMessages = true;
Code.settings.comparePrototypes = false;
});
lab.test('assertion count tracking', () => {
const initialCount = Code.count();
expect(1 + 1).to.equal(2);
expect('hello').to.be.a.string();
const finalCount = Code.count();
expect(finalCount - initialCount).to.equal(2);
});// Jest configuration
beforeAll(() => {
const Code = require('@hapi/code');
Code.settings.truncateMessages = true;
});
// Mocha configuration
before(() => {
const Code = require('@hapi/code');
Code.settings.truncateMessages = process.env.NODE_ENV !== 'development';
});
// Ava configuration
import test from 'ava';
import * as Code from '@hapi/code';
test.before(() => {
Code.settings.truncateMessages = true;
});// Validate settings values
const Code = require('@hapi/code');
// Type checking
if (typeof Code.settings.truncateMessages !== 'boolean') {
throw new Error('truncateMessages must be boolean');
}
if (typeof Code.settings.comparePrototypes !== 'boolean') {
throw new Error('comparePrototypes must be boolean');
}
// Helper function for safe configuration
function configureCode(options = {}) {
const validOptions = ['truncateMessages', 'comparePrototypes'];
for (const key of Object.keys(options)) {
if (!validOptions.includes(key)) {
throw new Error(`Invalid setting: ${key}`);
}
if (typeof options[key] !== 'boolean') {
throw new Error(`Setting ${key} must be boolean`);
}
}
Object.assign(Code.settings, options);
}
// Usage
configureCode({
truncateMessages: true,
comparePrototypes: false
});