@contract-case/case-core
Version:
Core functionality for the ContractCase contract testing suite
147 lines (144 loc) • 7.14 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.writeContract = void 0;
const mkdirp_1 = require("mkdirp");
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const case_plugin_base_1 = require("@contract-case/case-plugin-base");
const contextValidator_1 = require("./contextValidator");
const filename_1 = require("./filename");
const contractReader_1 = require("../contractReader");
const contractNormaliser_1 = require("./contractNormaliser");
const contractHasher_1 = require("./contractHasher");
const createDirectory = (pathToFile, context) => {
const dirName = path.dirname(pathToFile);
if (!fs.existsSync(dirName)) {
context.logger.maintainerDebug(`Creating directory ${dirName}`);
try {
mkdirp_1.mkdirp.sync(dirName);
}
catch (e) {
throw new case_plugin_base_1.CaseConfigurationError(`Failed trying to create contract directory '${dirName}': ${e.message}`, context, 'DISK_IO_PROBLEM');
}
}
};
const advice = (context) => {
if (context['_case:currentRun:context:adviceOverrides'] &&
context['_case:currentRun:context:adviceOverrides']['OVERWRITE_CONTRACTS_NEEDED'] != null) {
return `\n ${context['_case:currentRun:context:adviceOverrides']['OVERWRITE_CONTRACTS_NEEDED'].replaceAll('\n', '\n ')}\n`;
}
return `\n
Please re-run your tests with one of:
* The configuration property changedContracts is set to 'OVERWRITE'
* The environment variable CASE_changedContracts=OVERWRITE\n`;
};
const actuallyWriteContract = (pathToFile, contract, context) => {
if (fs.existsSync(pathToFile)) {
const existingContract = (0, contractReader_1.readContract)(pathToFile);
if (context['_case:currentRun:context:changedContracts'] === 'FAIL') {
if (!(0, contractNormaliser_1.contractsEqual)(existingContract, contract, context)) {
throw new case_plugin_base_1.CaseConfigurationError(`
The existing contract in file:
${pathToFile}
didn't match the new contract being written.
${advice(context)}
If you see this on consecutive runs, please check
that your contract doesn't contain randomness
during contract definition\n\n`, 'DONT_ADD_LOCATION', 'OVERWRITE_CONTRACTS_NEEDED');
}
context.logger.debug(`No need to overwrite contract '${pathToFile}', as it is identical to this one`);
return pathToFile;
}
}
if (context['_case:currentRun:context:changedContracts'] === 'FAIL' &&
!context['_case:currentRun:context:overwriteFile']) {
throw new case_plugin_base_1.CaseConfigurationError(`
Tried to write a new contract to
${pathToFile}
But it didn't exist. This isn't allowed with changedContracts set to fail.
While ContractCase is running in snapshot test mode, it's a failure to
create new contracts. You'll need to re-run your tests with one of:
* The configuration property changedContracts is set to 'OVERWRITE'
* The environment variable CASE_changedContracts=OVERWRITE
`, 'DONT_ADD_LOCATION', 'OVERWRITE_CONTRACTS_NEEDED');
}
createDirectory(pathToFile, context);
context.logger.maintainerDebug(`Writing contract to '${pathToFile}'`);
fs.writeFileSync(pathToFile, JSON.stringify({
...contract,
metadata: {
...contract.metadata,
_case: {
// eslint-disable-next-line no-underscore-dangle
...contract.metadata._case,
hash: (0, contractHasher_1.hashContract)(contract),
},
},
}, undefined, 2));
return pathToFile;
};
const internalWriteContract = (contract, context) => {
if (!(0, contextValidator_1.isHasContractFileConfig)(context)) {
throw new case_plugin_base_1.CaseConfigurationError('Unable to write contract without required configuration options set. See the error logs for more information.', context, case_plugin_base_1.ErrorCodes.configuration.INVALID_CONFIG);
}
if (context['_case:currentRun:context:contractFilename'] !== undefined &&
context['_case:currentRun:context:contractDir'] !==
context['_case:currentRun:context:defaultConfig']['contractDir']) {
context.logger.warn('Both contractFilename and contractDir have been specified, but you should only set one of these when writing a contract.');
context.logger.warn(`Ignoring contractDir setting, and writing to file at: ${context['_case:currentRun:context:contractFilename']}`);
}
const initialContract = context['_case:currentRun:context:contractFilename'] === undefined &&
context['_case:currentRun:context:contractsToWrite'].includes('main')
? [
// If we haven't been given an explicit filename,
// we also write the main contract too
actuallyWriteContract((0, filename_1.generateMainContractPath)(contract, context), contract, context),
]
: [];
const hashedContract = context['_case:currentRun:context:contractsToWrite'].includes('hash')
? [
actuallyWriteContract((0, filename_1.generateFileName)(contract, context), contract, context),
]
: [];
return {
consumerSlug: (0, filename_1.consumerSlug)(contract),
providerSlug: (0, filename_1.providerSlug)(contract),
contractPaths: [...initialContract, ...hashedContract],
};
};
const writeContract = (contract, context) => internalWriteContract((0, contractNormaliser_1.stripForWriting)(contract), context);
exports.writeContract = writeContract;
//# sourceMappingURL=contractFileWriter.js.map