Skip to content

Commit

Permalink
348 refactor pactum events (#368)
Browse files Browse the repository at this point in the history
* chore: rename events to pactumEvents

* feat: utils findFile clone and sleep

* chore: expect to allow normal assertions
  • Loading branch information
ASaiAnudeep authored Jul 25, 2024
1 parent a9fe231 commit 29e8337
Show file tree
Hide file tree
Showing 15 changed files with 130 additions and 45 deletions.
7 changes: 6 additions & 1 deletion src/exports/events.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,9 @@ export const EVENT_TYPES: {
AFTER_RESPONSE: 'AFTER_RESPONSE';
};

export const events: EventEmitter;
export const pactumEvents: EventEmitter;

/**
* @deprecated
*/
export const events: EventEmitter;
6 changes: 6 additions & 0 deletions src/exports/events.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
const { EventEmitter } = require('events');

/**
* @deprecated
*/
const events = new EventEmitter();

const pactumEvents = new EventEmitter();

const EVENT_TYPES = {
BEFORE_REQUEST: "BEFORE_REQUEST",
AFTER_RESPONSE: "AFTER_RESPONSE",
}

module.exports = {
events,
pactumEvents,
EVENT_TYPES
}
7 changes: 6 additions & 1 deletion src/exports/expect.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const ExpectModel = require('../models/expect');
const utils = require('../helpers/utils');
const http = require('http');

class Have {

Expand Down Expand Up @@ -143,7 +144,11 @@ class Expect {
}

function expect(response, spec) {
return new Expect(response, spec);
if (response instanceof http.IncomingMessage) {
return new Expect(response, spec);
}
const res = { json: response };
return new Expect(res, spec);
}

module.exports = expect;
15 changes: 15 additions & 0 deletions src/exports/utils.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export function clone<T>(input: T): T;

/**
* sleeps for a certain amount of time
* @param {number} ms the amount of time to sleep in milliseconds
* @returns
*/
export function sleep(ms: number): Promise<void>;

/**
* find a file recursively in a directory
* @param name the name of the file
* @param dir the directory to search in. Defaults to config.data.dir
*/
export function findFile(name: string, dir?: string): string;
35 changes: 35 additions & 0 deletions src/exports/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const { findFileRecursively } = require("../helpers/file.utils");
const config = require("../config");
const { klona } = require("klona");

const utils = {

clone(value) {
return klona(value);
},

/**
* sleeps for a certain amount of time
* @param {number} ms the amount of time to sleep in milliseconds
* @returns
*/
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
},

/**
* finds a file recursively in a directory
* @param {string} name
* @param {string} dir
* @returns
*/
findFile(name, dir = config.data.dir) {
const result = findFileRecursively(name, dir);
if (result) {
return result;
}
throw new Error(`File Not Found - '${name}'`);
}
}

module.exports = utils;
10 changes: 5 additions & 5 deletions src/helpers/dataProcessor.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const override = require('deep-override');
const jq = require('json-query');
const { klona } = require("klona");

const { clone } = require('../exports/utils');
const stash = require('../exports/stash');
const handler = require('../exports/handler');
const log = require('../plugins/logger');
Expand All @@ -17,7 +17,7 @@ const dataProcessor = {
processMaps() {
if (!config.data.ref.map.processed) {
const orgMap = stash.getDataMap();
this.map = klona(orgMap);
this.map = clone(orgMap);
this.map = this.processDataRefs(this.map);
config.data.ref.map.processed = true;
if (Object.keys(this.map).length > 0) {
Expand All @@ -29,7 +29,7 @@ const dataProcessor = {
processTemplates() {
if (!config.data.template.processed) {
const orgTemplate = stash.getDataTemplate();
this.template = klona(orgTemplate);
this.template = clone(orgTemplate);
this.template = this.processDataTemplates(this.template);
config.data.template.processed = true;
if (Object.keys(this.template).length > 0) {
Expand Down Expand Up @@ -58,7 +58,7 @@ const dataProcessor = {
if (templateName) {
const templateValue = this.template[templateName];
if (templateValue) {
data = klona(templateValue);
data = clone(templateValue);
data = this.processDataTemplates(data);
if (overrides) {
override(data, overrides);
Expand Down Expand Up @@ -134,7 +134,7 @@ const dataProcessor = {

getOverrides(data) {
if (config.data.template.direct_override) {
const cloned_data = klona(data);
const cloned_data = clone(data);
delete cloned_data['@DATA:TEMPLATE@'];
delete cloned_data['@REMOVES@'];
return cloned_data;
Expand Down
17 changes: 3 additions & 14 deletions src/helpers/file.utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,8 @@ function saveSnapshot(name, data) {
fs.writeFileSync(`${snapshotDir}/${snapshotFile}`, JSON.stringify(data, null, 2));
}

/**
*
* @param {string} name
*/
function findFile(name, dir = config.data.dir) {
const result = _findFile(name, dir);
if (result) {
return result;
}
throw new Error(`File Not Found - '${name}'`);
}

function _findFile(name, dir = config.data.dir) {
function findFileRecursively(name, dir = config.data.dir) {
if (fs.existsSync(name)) {
return fs.readFileSync(name);
}
Expand All @@ -55,7 +44,7 @@ function _findFile(name, dir = config.data.dir) {
const dirPath = path.resolve(dir, file);
const stats = fs.statSync(dirPath);
if (stats.isDirectory()) {
const result = _findFile(name, dirPath);
const result = findFileRecursively(name, dirPath);
if (result) {
return result;
}
Expand All @@ -67,5 +56,5 @@ function _findFile(name, dir = config.data.dir) {
module.exports = {
getSnapshotFile,
saveSnapshot,
findFile
findFileRecursively
};
1 change: 1 addition & 0 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export * as response from './exports/response';
export * as settings from './exports/settings';
export * as stash from './exports/stash';
export * as state from './exports/state';
export * as utils from './exports/utils';

export interface SpecOptions {
memo?: any
Expand Down
6 changes: 3 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ require('./plugins/json.match').setAdapter(require('./adapters/json.match'));
require('./plugins/json.like').setAdapter(require('./adapters/json.like'));
require('./plugins/form.data').setAdapter(require('./adapters/form.data'));

const { klona } = require('klona')

const Spec = require('./models/Spec');
const Fuzz = require('./models/Fuzz');
const E2E = require('./models/E2E');
Expand All @@ -22,6 +20,7 @@ const stash = require('./exports/stash');
const expect = require('./exports/expect');
const reporter = require('./exports/reporter');
const events = require('./exports/events');
const utils = require('./exports/utils');

const processor = require('./helpers/dataProcessor');

Expand All @@ -43,6 +42,7 @@ const pactum = {
expect,
reporter,
events,
utils,

spec(name, data, opts) {
return new Spec(name, data, opts);
Expand All @@ -68,7 +68,7 @@ const pactum = {
},

clone(value) {
return klona(value);
return utils.clone(value);
},

parse,
Expand Down
8 changes: 4 additions & 4 deletions src/models/Interaction.model.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const { setMatchingRules, getValue } = require('pactum-matchers').utils;
const processor = require('../helpers/dataProcessor');
const helper = require('../helpers/helper');
const { PactumInteractionError } = require('../helpers/errors');
const { klona: clone } = require('klona');
const { clone } = require('../exports/utils');
const ALLOWED_REQUEST_METHODS = new Set([
'GET',
'POST',
Expand Down Expand Up @@ -122,7 +122,7 @@ class InteractionRequest {
}
if (request.cookies && typeof request.cookies === 'object') {
const cookie = lc.serialize(request.cookies);
if(!this.headers) {
if (!this.headers) {
this.headers = {};
}
this.headers['cookie'] = cookie;
Expand Down Expand Up @@ -169,9 +169,9 @@ class InteractionResponse {
this.headers = getValue(response.headers);
setMatchingRules(this.matchingRules, response.body, '$.body');
this.body = getValue(response.body);
if(response.cookies) {
if (response.cookies) {
const cookie = lc.serialize(response.cookies);
if(!this.headers) {
if (!this.headers) {
this.headers = {};
}
this.headers['set-cookie'] = cookie;
Expand Down
18 changes: 9 additions & 9 deletions src/models/Spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const responseExpect = require('../exports/expect');
const hr = require('../helpers/handler.runner');
const rlc = require('../helpers/reporter.lifeCycle');
const config = require('../config');
const { findFile } = require('../helpers/file.utils');
const { findFile } = require('../exports/utils');
const stash = require('../exports/stash');
const { memorize_spec, is_spec_memoized } = require('../helpers/memo');

Expand Down Expand Up @@ -45,7 +45,7 @@ class Spec {
this._opts.handler_name = name;
this._expect.setDefaultResponseExpectations();
}

sleep(ms) {
this._sleep = ms;
return this;
Expand Down Expand Up @@ -209,7 +209,7 @@ class Spec {

withJson(json) {
if (typeof json === 'string') {
json = get_json_from_template_or_file(json);
json = getJsonFromTemplateOrFile(json);
} else if (typeof json !== 'object') {
throw new PactumRequestError(`Invalid json in request - ${json}`);
}
Expand Down Expand Up @@ -400,13 +400,13 @@ class Spec {
}

expectJson(path, value) {
typeof value === 'undefined' ? this._expect.json.push(get_json_from_template_or_file(path)) : this._expect.jsonQuery.push({ path, value });
typeof value === 'undefined' ? this._expect.json.push(getJsonFromTemplateOrFile(path)) : this._expect.jsonQuery.push({ path, value });
return this;
}
expectJsonAt(...args) { return this.expectJson(...args); }

expectJsonLike(path, value) {
typeof value === 'undefined' ? this._expect.jsonLike.push(get_json_from_template_or_file(path)) : this._expect.jsonQueryLike.push({ path, value });
typeof value === 'undefined' ? this._expect.jsonLike.push(getJsonFromTemplateOrFile(path)) : this._expect.jsonQueryLike.push({ path, value });
return this;
}
expectJsonLikeAt(...args) { return this.expectJsonLike(...args); }
Expand All @@ -416,7 +416,7 @@ class Spec {
this._expect.jsonSchemaQuery.push({ path, value, options });
} else {
if (typeof value === 'undefined') {
this._expect.jsonSchema.push({ value: get_json_from_template_or_file(path) });
this._expect.jsonSchema.push({ value: getJsonFromTemplateOrFile(path) });
} else {
if (typeof path === 'object' && typeof value === 'object') {
this._expect.jsonSchema.push({ value: path, options: value });
Expand All @@ -430,13 +430,13 @@ class Spec {
expectJsonSchemaAt(...args) { return this.expectJsonSchema(...args); }

expectJsonMatch(path, value) {
typeof value === 'undefined' ? this._expect.jsonMatch.push(get_json_from_template_or_file(path)) : this._expect.jsonMatchQuery.push({ path, value });
typeof value === 'undefined' ? this._expect.jsonMatch.push(getJsonFromTemplateOrFile(path)) : this._expect.jsonMatchQuery.push({ path, value });
return this;
}
expectJsonMatchAt(...args) { return this.expectJsonMatch(...args); }

expectJsonMatchStrict(path, value) {
typeof value === 'undefined' ? this._expect.jsonMatchStrict.push(get_json_from_template_or_file(path)) : this._expect.jsonMatchStrictQuery.push({ path, value });
typeof value === 'undefined' ? this._expect.jsonMatchStrict.push(getJsonFromTemplateOrFile(path)) : this._expect.jsonMatchStrictQuery.push({ path, value });
return this;
}
expectJsonMatchStrictAt(...args) { return this.expectJsonMatchStrict(...args); }
Expand Down Expand Up @@ -572,7 +572,7 @@ function validateRequestUrl(request, url) {
}
}

function get_json_from_template_or_file(path) {
function getJsonFromTemplateOrFile(path) {
if (typeof path === 'string') {
if (stash.getDataTemplate()[path]) {
return { '@DATA:TEMPLATE@': path };
Expand Down
4 changes: 3 additions & 1 deletion src/models/Tosser.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const mock = require('../exports/mock');
const request = require('../exports/request');
const config = require('../config');
const hr = require('../helpers/handler.runner');
const { events, EVENT_TYPES } = require('../exports/events');
const { events, pactumEvents, EVENT_TYPES } = require('../exports/events');

class Tosser {

Expand Down Expand Up @@ -257,6 +257,7 @@ async function getResponse(tosser) {
const requestStartTime = Date.now();
try {
events.emit(EVENT_TYPES.BEFORE_REQUEST, request);
pactumEvents.emit(EVENT_TYPES.BEFORE_REQUEST, { request });
log.debug(`${request.method} ${request.url}`);
res = await phin(request);
res.buffer = res.body;
Expand All @@ -274,6 +275,7 @@ async function getResponse(tosser) {
} finally {
res.responseTime = Date.now() - requestStartTime;
events.emit(EVENT_TYPES.AFTER_RESPONSE, res);
pactumEvents.emit(EVENT_TYPES.AFTER_RESPONSE, { request, response: res });
}
return res;
}
Expand Down
4 changes: 2 additions & 2 deletions src/models/expect.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
const assert = require('assert');
const jqy = require('json-query');
const lc = require('lightcookie');
const { klona: clone } = require('klona');

const config = require('../config');
const utils = require('../helpers/utils');
Expand All @@ -10,6 +9,7 @@ const file = require('../helpers/file.utils');
const log = require('../plugins/logger');
const processor = require('../helpers/dataProcessor');
const handler = require('../exports/handler');
const { clone } = require('../exports/utils');
const jsv = require('../plugins/json.schema');
const jmv = require('../plugins/json.match');
const jlv = require('../plugins/json.like');
Expand Down Expand Up @@ -348,7 +348,7 @@ class Expect {
}
if (value) {
const current_rules = jmv.getMatchingRules(value, '$.body');
let errors = jmv.validate(actual, jmv.getRawValue(value), current_rules, '$.body');
let errors = jmv.validate(actual, jmv.getRawValue(value), current_rules, '$.body');
if (errors) {
this.fail(errors.replace('$.body', '$'));
}
Expand Down
Loading

0 comments on commit 29e8337

Please sign in to comment.