cooky-cutter
Version:
Object factories for testing in TypeScript
46 lines (45 loc) • 2.24 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.DERIVE_FUNCTION_KEY = exports.derive = void 0;
const compute_1 = require("./compute");
const DERIVE_FUNCTION_KEY = "derived";
exports.DERIVE_FUNCTION_KEY = DERIVE_FUNCTION_KEY;
/**
* Compute a single value and assign it to the attribute based off any number
* of other attributes defined in the factory. This is useful for deriving a
* fields value off of other dynamic field(s) that are not known until a factory
* is invoked. A derived field can reference other derived fields, but they
* cannot be circularly referenced.
*
* @param fn a function to reduce all of the dependent keys into a single
* derived value. The return value will be assigned to the attribute.
* @param dependentKeys a list of all keys that the derive function is dependent
* on. If the key is not defined in this list, it is not guaranteed to be
* defined.
*/
function derive(fn, ...dependentKeys) {
const derivedFunction = function (result, values, invocations, path, override, computedKeys) {
// Construct the input object from all of the dependent values that are
// needed to derive the value.
const input = dependentKeys.reduce((input, key) => {
// Verify the derived value has been computed, otherwise compute any
// derived values before continuing.
if (!result.hasOwnProperty(key)) {
// Verify the field has not already been visited. If it has, there
// is a circular reference and it cannot be resolved.
if (path.indexOf(key) > -1) {
throw `${key} cannot circularly derive itself. Check along this path: ${path.join("->")}->${key}`;
}
compute_1.compute(key, values, result, invocations, [...path, key], override, computedKeys);
}
input[key] = result[key];
return input;
}, {});
return fn(input);
};
// Define a property to differentiate this function during the evaluation
// phase when the factory is later invoked.
derivedFunction.__cooky_cutter = DERIVE_FUNCTION_KEY;
return derivedFunction;
}
exports.derive = derive;