UNPKG

google-closure-library

Version:
85 lines (77 loc) 2.24 kB
/** * @license * Copyright The Closure Library Authors. * SPDX-License-Identifier: Apache-2.0 */ /** * @fileoverview Testing utilities for generic objects. */ goog.module('goog.testing.objects'); goog.setTestOnly('goog.testing.objects'); const asserts = goog.require('goog.testing.asserts'); /** * Asserts that the given object has a transitive reference on the given value. * * This may be useful when writing tests to confirm that certain values'leaked'. */ function assertRetainsReference(/** !Object */ object, /** * */ value) { const path = searchForReference(object, value); if (!path) { asserts.raiseException( `The object does not transitively retain a reference to the given value`); } } /** * Asserts that the given object has no transitive reference on the given * value. * * This may be useful when writing tests to confirm that certain values aren't * 'leaked'. */ function assertDoesNotRetainReference(/** !Object */ object, /** * */ value) { const path = searchForReference(object, value); if (path) { asserts.raiseException( `expected there to be no retention path, found the value @ object['${ path.join('\'][\'')}']`); } } /** * Searches an object for a value and returns the path to it, or `null` if it * cannot be found. * * @param {!Object} object The object to search, recursively * @param {?} needle The value to search for * @return {?Array<string>} the path to the value, or `null` if there is no such * path */ function searchForReference(object, needle) { const /** !Set<!Object> */ visited = new Set(); const /** !Array<string> */ stack = []; /** @return {boolean} */ const doSearch = (/** !Object */ object, /** ? */ needle) => { if (object === needle) { return true; } if (!object || visited.has(object)) { return false; // cycle or null } visited.add(object); for (const key in object) { stack.push(key); if (doSearch(object[key], needle)) { return true; } stack.pop(); } return false; }; if (doSearch(object, needle)) { return stack; } return null; } exports = { assertDoesNotRetainReference, assertRetainsReference, };