UNPKG

cooky-cutter

Version:

Object factories for testing in TypeScript

72 lines (71 loc) 2.95 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.compute = void 0; const utils_1 = require("./utils"); const config_1 = require("./config"); // Given a key, the configuration object (with overrides already applied) and // the end result object, compute the current value for the given key and write // that value to the result object. Optionally track the path values are // computed along in cases where it's possible to define circular dependencies. function compute(key, values, result, invocations, path, override, computedKeys) { // If this key was already computed (according to the passed array) then skip // this computation. This likely was a result of a `derive` function requiring // this key to be computed to invoke the derived function because it was a // dependency. In these cases, avoid re-computing the value because often // the factories are not idempotent (eg: each call the invocation is // incremented) which can lead to unexpected inconsistencies. if (computedKeys.indexOf(key) >= 0) { return; } const value = values[key]; // In essence, this is "exhaustively" checking for each type of attribute that // can be defined for a given key. Unfortunately it's not truly exhaustive, // but would be great to update this to do true exhaustive type checking. if (utils_1.isDerivedFunction(value)) { result[key] = value(result, values, invocations, path, override, computedKeys); } else if (utils_1.isFactoryFunction(value)) { result[key] = value(); } else if (utils_1.isArrayFactoryFunction(value)) { result[key] = value(); } else if (utils_1.isAttributeFunction(value)) { result[key] = value(invocations); } else { if (!(key in override)) { warnAboutHardCodedValues(key, value); } result[key] = value; } // Mark this key has having it's value computed. computedKeys.push(key); } exports.compute = compute; /** * Explicitly setting an object or array as a value in a factory can lead to * really challenging and subtle bugs since they will be shared across all * instances of a factory. Check for objects and arrays and by default display * a warning. */ const warnAboutHardCodedValues = (key, value) => { let message; if (Array.isArray(value)) { message = `\`${key}\` contains a hard-coded array.`; } else if (typeof value === "object" && value !== null) { message = `\`${key}\` contains a hard-coded object.`; } const { errorOnHardCodedValues } = config_1.getConfig(); if (message) { message += ` It will be shared across all instances of this factory. Consider using a factory function.`; if (errorOnHardCodedValues) { console.trace(); throw message; } else { console.warn(message); } } };