UNPKG

apiveritas

Version:

Lightweight CLI tool for consumer-driven API contract testing via JSON schema and payload comparisons.

73 lines (72 loc) 3.02 kB
"use strict"; /** * @file BasicComparator.ts * @author Mario Galea * @description * Provides a simple recursive comparison of two JSON-like objects, * optionally enforcing strict value matching. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.BasicComparator = void 0; class BasicComparator { /** * Creates an instance of BasicComparator. * * @param strictValues - If true, value mismatches are considered differences; otherwise, they are flagged but tolerated. */ constructor(strictValues = true) { this.strictValues = strictValues; } /** * Recursively compares two JSON-like objects and returns an array of human-readable difference strings. * * @param oldData - The original (expected) data object. * @param newData - The new (actual) data object to compare against the original. * @param pathPrefix - Internal use for recursion; tracks the nested path of the current key being compared. * @returns An array of difference messages. Empty if objects match (under configured tolerance). */ compare(oldData, newData, pathPrefix = '') { const diffs = []; if (typeof oldData !== 'object' || oldData === null) { diffs.push(`X Old data is not a valid object at ${this.formatPath(pathPrefix)}. Got: ${JSON.stringify(oldData)}`); return diffs; } if (typeof newData !== 'object' || newData === null) { diffs.push(`X New data is not a valid object at ${this.formatPath(pathPrefix)}. Got: ${JSON.stringify(newData)}`); return diffs; } for (const key in oldData) { const fullPath = pathPrefix ? `${pathPrefix}.${key}` : key; if (!(key in newData)) { diffs.push(`Missing key in new data: ${fullPath}`); continue; } if (typeof oldData[key] !== typeof newData[key]) { diffs.push(`Type mismatch at ${fullPath}: expected ${typeof oldData[key]}, got ${typeof newData[key]}`); continue; } if (typeof oldData[key] === 'object' && oldData[key] !== null) { diffs.push(...this.compare(oldData[key], newData[key], fullPath)); } else if (oldData[key] !== newData[key]) { if (this.strictValues) { diffs.push(`X Value mismatch at ${fullPath}: "${oldData[key]}" vs "${newData[key]}"`); } else { diffs.push(`IGNORED:: ! Value mismatch at ${fullPath}: "${oldData[key]}" vs "${newData[key]}"`); } } } return diffs; } /** * Formats a path for display. If the path is empty, returns a root symbol. * * @param path - The current nested key path. * @returns A formatted string path or `#` if root. */ formatPath(path) { return path || '#'; } } exports.BasicComparator = BasicComparator;