or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

assertion-modifiers.mdcontent-testing.mdcore-functions.mdfunction-testing.mdindex.mdnumeric-comparisons.mdpattern-validation.mdpromise-testing.mdsettings.mdstring-assertions.mdtype-assertions.mdvalue-assertions.md
tile.json

settings.mddocs/

Settings and Configuration

Global configuration options for customizing @hapi/code behavior.

Settings Object

The

settings
object provides global configuration options that affect all assertions.

/**
 * 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
};

Configuration Options

truncateMessages

Controls whether long assertion error messages are truncated for improved readability.

/**
 * Truncate long assertion error messages for readability
 * @type {boolean}
 * @default false
 */
settings.truncateMessages

Usage 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:

  • Strings longer than 40 characters: Show first 40 characters + "..."
  • Arrays: Show "[Array(length)]" format
  • Objects: Show "{ Object (key1, key2, ...) }" format with up to 2 keys
// 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, ...) }"

comparePrototypes

Controls whether object prototypes are included in deep equality comparisons.

/**
 * Include object prototypes when doing deep comparisons
 * @type {boolean}
 * @default false
 */
settings.comparePrototypes

Usage 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 reference

Per-Assertion Options

Some methods accept options that override global settings for specific assertions:

equal() Method Options

/**
 * 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

Configuration Best Practices

Test Suite Configuration

// 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;
    });
});

Environment-Based Configuration

// 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;
}

Temporary Setting Changes

// 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 test

Integration with Test Runners

@hapi/lab Integration

const 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);
});

Other Test Runners

// 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;
});

Settings Validation

// 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
});