mirror of
https://github.com/usebruno/bruno.git
synced 2024-11-21 23:43:15 +01:00
chore(#197): ran prettier on packages/bruno-js
This commit is contained in:
parent
a53dd76854
commit
5af2f68252
@ -1,4 +1,3 @@
|
||||
|
||||
class Bru {
|
||||
constructor(envVariables, collectionVariables) {
|
||||
this.envVariables = envVariables;
|
||||
@ -18,20 +17,20 @@ class Bru {
|
||||
}
|
||||
|
||||
setEnvVar(key, value) {
|
||||
if(!key) {
|
||||
if (!key) {
|
||||
throw new Error('Key is required');
|
||||
}
|
||||
|
||||
// gracefully ignore if key is not present in environment
|
||||
if(!this.envVariables.hasOwnProperty(key)) {
|
||||
return;
|
||||
if (!this.envVariables.hasOwnProperty(key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.envVariables[key] = value;
|
||||
}
|
||||
|
||||
setVar(key, value) {
|
||||
if(!key) {
|
||||
if (!key) {
|
||||
throw new Error('Key is required');
|
||||
}
|
||||
|
||||
|
@ -48,4 +48,4 @@ class BrunoRequest {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = BrunoRequest;
|
||||
module.exports = BrunoRequest;
|
||||
|
@ -12,7 +12,7 @@ class BrunoResponse {
|
||||
}
|
||||
|
||||
getHeader(name) {
|
||||
return (this.res && this.res.headers) ? this.res.headers[name] : null;
|
||||
return this.res && this.res.headers ? this.res.headers[name] : null;
|
||||
}
|
||||
|
||||
getHeaders() {
|
||||
|
@ -12,11 +12,7 @@ chai.use(function (chai, utils) {
|
||||
const obj = this._obj;
|
||||
const isJson = typeof obj === 'object' && obj !== null && !Array.isArray(obj) && obj.constructor === Object;
|
||||
|
||||
this.assert(
|
||||
isJson,
|
||||
`expected ${utils.inspect(obj)} to be JSON`,
|
||||
`expected ${utils.inspect(obj)} not to be JSON`
|
||||
);
|
||||
this.assert(isJson, `expected ${utils.inspect(obj)} to be JSON`, `expected ${utils.inspect(obj)} not to be JSON`);
|
||||
});
|
||||
});
|
||||
|
||||
@ -25,7 +21,7 @@ chai.use(function (chai, utils) {
|
||||
chai.Assertion.addMethod('match', function (regex) {
|
||||
const obj = this._obj;
|
||||
let match = false;
|
||||
if(obj === undefined) {
|
||||
if (obj === undefined) {
|
||||
match = false;
|
||||
} else {
|
||||
match = regex.test(obj);
|
||||
@ -41,7 +37,7 @@ chai.use(function (chai, utils) {
|
||||
|
||||
/**
|
||||
* Assertion operators
|
||||
*
|
||||
*
|
||||
* eq : equal to
|
||||
* neq : not equal to
|
||||
* gt : greater than
|
||||
@ -70,7 +66,7 @@ chai.use(function (chai, utils) {
|
||||
* isBoolean : is boolean
|
||||
*/
|
||||
const parseAssertionOperator = (str = '') => {
|
||||
if(!str || typeof str !== 'string' || !str.length) {
|
||||
if (!str || typeof str !== 'string' || !str.length) {
|
||||
return {
|
||||
operator: 'eq',
|
||||
value: str
|
||||
@ -78,27 +74,58 @@ const parseAssertionOperator = (str = '') => {
|
||||
}
|
||||
|
||||
const operators = [
|
||||
'eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'in', 'notIn',
|
||||
'contains', 'notContains', 'length', 'matches', 'notMatches',
|
||||
'startsWith', 'endsWith', 'between', 'isEmpty', 'isNull', 'isUndefined',
|
||||
'isDefined', 'isTruthy', 'isFalsy', 'isJson', 'isNumber', 'isString', 'isBoolean'
|
||||
'eq',
|
||||
'neq',
|
||||
'gt',
|
||||
'gte',
|
||||
'lt',
|
||||
'lte',
|
||||
'in',
|
||||
'notIn',
|
||||
'contains',
|
||||
'notContains',
|
||||
'length',
|
||||
'matches',
|
||||
'notMatches',
|
||||
'startsWith',
|
||||
'endsWith',
|
||||
'between',
|
||||
'isEmpty',
|
||||
'isNull',
|
||||
'isUndefined',
|
||||
'isDefined',
|
||||
'isTruthy',
|
||||
'isFalsy',
|
||||
'isJson',
|
||||
'isNumber',
|
||||
'isString',
|
||||
'isBoolean'
|
||||
];
|
||||
|
||||
const unaryOperators = [
|
||||
'isEmpty', 'isNull', 'isUndefined', 'isDefined', 'isTruthy', 'isFalsy', 'isJson', 'isNumber', 'isString', 'isBoolean'
|
||||
'isEmpty',
|
||||
'isNull',
|
||||
'isUndefined',
|
||||
'isDefined',
|
||||
'isTruthy',
|
||||
'isFalsy',
|
||||
'isJson',
|
||||
'isNumber',
|
||||
'isString',
|
||||
'isBoolean'
|
||||
];
|
||||
|
||||
const [operator, ...rest] = str.trim().split(' ');
|
||||
const value = rest.join(' ');
|
||||
|
||||
if(unaryOperators.includes(operator)) {
|
||||
if (unaryOperators.includes(operator)) {
|
||||
return {
|
||||
operator,
|
||||
value: ''
|
||||
};
|
||||
}
|
||||
|
||||
if(operators.includes(operator)) {
|
||||
if (operators.includes(operator)) {
|
||||
return {
|
||||
operator,
|
||||
value
|
||||
@ -113,34 +140,43 @@ const parseAssertionOperator = (str = '') => {
|
||||
|
||||
const isUnaryOperator = (operator) => {
|
||||
const unaryOperators = [
|
||||
'isEmpty', 'isNull', 'isUndefined', 'isDefined', 'isTruthy', 'isFalsy', 'isJson', 'isNumber', 'isString', 'isBoolean'
|
||||
'isEmpty',
|
||||
'isNull',
|
||||
'isUndefined',
|
||||
'isDefined',
|
||||
'isTruthy',
|
||||
'isFalsy',
|
||||
'isJson',
|
||||
'isNumber',
|
||||
'isString',
|
||||
'isBoolean'
|
||||
];
|
||||
|
||||
return unaryOperators.includes(operator);
|
||||
};
|
||||
|
||||
const evaluateRhsOperand = (rhsOperand, operator, context) => {
|
||||
if(isUnaryOperator(operator)) {
|
||||
if (isUnaryOperator(operator)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// gracefully allow both a,b as well as [a, b]
|
||||
if(operator === 'in' || operator === 'notIn') {
|
||||
if(rhsOperand.startsWith('[') && rhsOperand.endsWith(']')) {
|
||||
if (operator === 'in' || operator === 'notIn') {
|
||||
if (rhsOperand.startsWith('[') && rhsOperand.endsWith(']')) {
|
||||
rhsOperand = rhsOperand.substring(1, rhsOperand.length - 1);
|
||||
}
|
||||
|
||||
return rhsOperand.split(',').map((v) => evaluateJsTemplateLiteral(v.trim(), context));
|
||||
}
|
||||
|
||||
if(operator === 'between') {
|
||||
if (operator === 'between') {
|
||||
const [lhs, rhs] = rhsOperand.split(',').map((v) => evaluateJsTemplateLiteral(v.trim(), context));
|
||||
return [lhs, rhs];
|
||||
}
|
||||
|
||||
// gracefully allow both ^[a-Z] as well as /^[a-Z]/
|
||||
if(operator === 'matches' || operator === 'notMatches') {
|
||||
if(rhsOperand.startsWith('/') && rhsOperand.endsWith('/')) {
|
||||
if (operator === 'matches' || operator === 'notMatches') {
|
||||
if (rhsOperand.startsWith('/') && rhsOperand.endsWith('/')) {
|
||||
rhsOperand = rhsOperand.substring(1, rhsOperand.length - 1);
|
||||
}
|
||||
|
||||
@ -153,7 +189,7 @@ const evaluateRhsOperand = (rhsOperand, operator, context) => {
|
||||
class AssertRuntime {
|
||||
runAssertions(assertions, request, response, envVariables, collectionVariables, collectionPath) {
|
||||
const enabledAssertions = _.filter(assertions, (a) => a.enabled);
|
||||
if(!enabledAssertions.length) {
|
||||
if (!enabledAssertions.length) {
|
||||
return [];
|
||||
}
|
||||
|
||||
@ -171,7 +207,7 @@ class AssertRuntime {
|
||||
...envVariables,
|
||||
...collectionVariables,
|
||||
...bruContext
|
||||
}
|
||||
};
|
||||
|
||||
const assertionResults = [];
|
||||
|
||||
@ -179,16 +215,13 @@ class AssertRuntime {
|
||||
for (const v of enabledAssertions) {
|
||||
const lhsExpr = v.name;
|
||||
const rhsExpr = v.value;
|
||||
const {
|
||||
operator,
|
||||
value: rhsOperand
|
||||
} = parseAssertionOperator(rhsExpr);
|
||||
const { operator, value: rhsOperand } = parseAssertionOperator(rhsExpr);
|
||||
|
||||
try {
|
||||
const lhs = evaluateJsExpression(lhsExpr, context);
|
||||
const rhs = evaluateRhsOperand(rhsOperand, operator, context);
|
||||
|
||||
switch(operator) {
|
||||
switch (operator) {
|
||||
case 'eq':
|
||||
expect(lhs).to.equal(rhs);
|
||||
break;
|
||||
@ -281,8 +314,7 @@ class AssertRuntime {
|
||||
operator,
|
||||
status: 'pass'
|
||||
});
|
||||
}
|
||||
catch (err) {
|
||||
} catch (err) {
|
||||
assertionResults.push({
|
||||
uid: nanoid(),
|
||||
lhsExpr,
|
||||
|
@ -23,10 +23,9 @@ const fetch = require('node-fetch');
|
||||
const CryptoJS = require('crypto-js');
|
||||
|
||||
class ScriptRuntime {
|
||||
constructor() {
|
||||
}
|
||||
constructor() {}
|
||||
|
||||
async runRequestScript(script, request, envVariables, collectionVariables, collectionPath, onConsoleLog){
|
||||
async runRequestScript(script, request, envVariables, collectionVariables, collectionPath, onConsoleLog) {
|
||||
const bru = new Bru(envVariables, collectionVariables);
|
||||
const req = new BrunoRequest(request);
|
||||
|
||||
@ -35,18 +34,18 @@ class ScriptRuntime {
|
||||
req
|
||||
};
|
||||
|
||||
if(onConsoleLog && typeof onConsoleLog === 'function') {
|
||||
if (onConsoleLog && typeof onConsoleLog === 'function') {
|
||||
const customLogger = (type) => {
|
||||
return (...args) => {
|
||||
onConsoleLog(type, args);
|
||||
}
|
||||
};
|
||||
};
|
||||
context.console = {
|
||||
log: customLogger('log'),
|
||||
info: customLogger('info'),
|
||||
warn: customLogger('warn'),
|
||||
error: customLogger('error')
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const vm = new NodeVM({
|
||||
@ -78,7 +77,7 @@ class ScriptRuntime {
|
||||
}
|
||||
}
|
||||
});
|
||||
const asyncVM = vm.run(`module.exports = async () => { ${script} }`, path.join(collectionPath, 'vm.js'));
|
||||
const asyncVM = vm.run(`module.exports = async () => { ${script} }`, path.join(collectionPath, 'vm.js'));
|
||||
await asyncVM();
|
||||
return {
|
||||
request,
|
||||
@ -87,7 +86,7 @@ class ScriptRuntime {
|
||||
};
|
||||
}
|
||||
|
||||
async runResponseScript(script, request, response, envVariables, collectionVariables, collectionPath, onConsoleLog){
|
||||
async runResponseScript(script, request, response, envVariables, collectionVariables, collectionPath, onConsoleLog) {
|
||||
const bru = new Bru(envVariables, collectionVariables);
|
||||
const req = new BrunoRequest(request);
|
||||
const res = new BrunoResponse(response);
|
||||
@ -98,18 +97,18 @@ class ScriptRuntime {
|
||||
res
|
||||
};
|
||||
|
||||
if(onConsoleLog && typeof onConsoleLog === 'function') {
|
||||
if (onConsoleLog && typeof onConsoleLog === 'function') {
|
||||
const customLogger = (type) => {
|
||||
return (...args) => {
|
||||
onConsoleLog(type, args);
|
||||
}
|
||||
};
|
||||
};
|
||||
context.console = {
|
||||
log: customLogger('log'),
|
||||
info: customLogger('info'),
|
||||
warn: customLogger('warn'),
|
||||
error: customLogger('error')
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const vm = new NodeVM({
|
||||
@ -132,7 +131,7 @@ class ScriptRuntime {
|
||||
}
|
||||
});
|
||||
|
||||
const asyncVM = vm.run(`module.exports = async () => { ${script} }`, path.join(collectionPath, 'vm.js'));
|
||||
const asyncVM = vm.run(`module.exports = async () => { ${script} }`, path.join(collectionPath, 'vm.js'));
|
||||
await asyncVM();
|
||||
|
||||
return {
|
||||
|
@ -1,5 +1,5 @@
|
||||
const { NodeVM } = require('vm2');
|
||||
const chai = require('chai');
|
||||
const chai = require('chai');
|
||||
const path = require('path');
|
||||
const Bru = require('../bru');
|
||||
const BrunoRequest = require('../bruno-request');
|
||||
@ -17,10 +17,9 @@ const nanoid = require('nanoid');
|
||||
const CryptoJS = require('crypto-js');
|
||||
|
||||
class TestRuntime {
|
||||
constructor() {
|
||||
}
|
||||
constructor() {}
|
||||
|
||||
runTests(testsFile, request, response, envVariables, collectionVariables, collectionPath, onConsoleLog){
|
||||
runTests(testsFile, request, response, envVariables, collectionVariables, collectionPath, onConsoleLog) {
|
||||
const bru = new Bru(envVariables, collectionVariables);
|
||||
const req = new BrunoRequest(request);
|
||||
const res = new BrunoResponse(response);
|
||||
@ -28,7 +27,7 @@ class TestRuntime {
|
||||
const __brunoTestResults = new TestResults();
|
||||
const test = Test(__brunoTestResults, chai);
|
||||
|
||||
if(!testsFile || !testsFile.length) {
|
||||
if (!testsFile || !testsFile.length) {
|
||||
return {
|
||||
request,
|
||||
envVariables,
|
||||
@ -47,18 +46,18 @@ class TestRuntime {
|
||||
__brunoTestResults: __brunoTestResults
|
||||
};
|
||||
|
||||
if(onConsoleLog && typeof onConsoleLog === 'function') {
|
||||
if (onConsoleLog && typeof onConsoleLog === 'function') {
|
||||
const customLogger = (type) => {
|
||||
return (...args) => {
|
||||
onConsoleLog(type, args);
|
||||
}
|
||||
};
|
||||
};
|
||||
context.console = {
|
||||
log: customLogger('log'),
|
||||
info: customLogger('info'),
|
||||
warn: customLogger('warn'),
|
||||
error: customLogger('error')
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const vm = new NodeVM({
|
||||
|
@ -6,7 +6,7 @@ const { evaluateJsTemplateLiteral, evaluateJsExpression, createResponseParser }
|
||||
class VarsRuntime {
|
||||
runPreRequestVars(vars, request, envVariables, collectionVariables, collectionPath) {
|
||||
const enabledVars = _.filter(vars, (v) => v.enabled);
|
||||
if(!enabledVars.length) {
|
||||
if (!enabledVars.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ class VarsRuntime {
|
||||
...envVariables,
|
||||
...collectionVariables,
|
||||
...bruContext
|
||||
}
|
||||
};
|
||||
|
||||
_.each(enabledVars, (v) => {
|
||||
const value = evaluateJsTemplateLiteral(v.value, context);
|
||||
@ -36,7 +36,7 @@ class VarsRuntime {
|
||||
|
||||
runPostResponseVars(vars, request, response, envVariables, collectionVariables, collectionPath) {
|
||||
const enabledVars = _.filter(vars, (v) => v.enabled);
|
||||
if(!enabledVars.length) {
|
||||
if (!enabledVars.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -54,7 +54,7 @@ class VarsRuntime {
|
||||
...envVariables,
|
||||
...collectionVariables,
|
||||
...bruContext
|
||||
}
|
||||
};
|
||||
|
||||
_.each(enabledVars, (v) => {
|
||||
const value = evaluateJsExpression(v.value, context);
|
||||
|
@ -1,14 +1,14 @@
|
||||
const Test = (__brunoTestResults, chai) => (description, callback) => {
|
||||
try {
|
||||
callback();
|
||||
__brunoTestResults.addResult({ description, status: "pass" });
|
||||
__brunoTestResults.addResult({ description, status: 'pass' });
|
||||
} catch (error) {
|
||||
console.log(chai.AssertionError);
|
||||
if (error instanceof chai.AssertionError) {
|
||||
const { message, actual, expected } = error;
|
||||
__brunoTestResults.addResult({
|
||||
description,
|
||||
status: "fail",
|
||||
status: 'fail',
|
||||
error: message,
|
||||
actual,
|
||||
expected
|
||||
@ -16,12 +16,12 @@ const Test = (__brunoTestResults, chai) => (description, callback) => {
|
||||
} else {
|
||||
__brunoTestResults.addResult({
|
||||
description,
|
||||
status: "fail",
|
||||
status: 'fail',
|
||||
error: error.message || 'An unexpected error occurred.'
|
||||
});
|
||||
}
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = Test;
|
||||
module.exports = Test;
|
||||
|
@ -1,21 +1,23 @@
|
||||
const jsonQuery = require('json-query');
|
||||
const { get } = require("@usebruno/query");
|
||||
const { get } = require('@usebruno/query');
|
||||
|
||||
const JS_KEYWORDS = `
|
||||
break case catch class const continue debugger default delete do
|
||||
else export extends false finally for function if import in instanceof
|
||||
new null return super switch this throw true try typeof var void while with
|
||||
undefined let static yield arguments of
|
||||
`.split(/\s+/).filter(word => word.length > 0);
|
||||
`
|
||||
.split(/\s+/)
|
||||
.filter((word) => word.length > 0);
|
||||
|
||||
/**
|
||||
* Creates a function from a Javascript expression
|
||||
*
|
||||
*
|
||||
* When the function is called, the variables used in this expression are picked up from the context
|
||||
*
|
||||
*
|
||||
* ```js
|
||||
* res.data.pets.map(pet => pet.name.toUpperCase())
|
||||
*
|
||||
*
|
||||
* function(context) {
|
||||
* const { res, pet } = context;
|
||||
* return res.data.pets.map(pet => pet.name.toUpperCase())
|
||||
@ -29,25 +31,23 @@ const compileJsExpression = (expr) => {
|
||||
// get valid js identifiers (foo, bar)
|
||||
const vars = new Set(
|
||||
matches
|
||||
.filter(match => /^[a-zA-Z$_]/.test(match)) // starts with valid js identifier (foo.bar)
|
||||
.map(match => match.split('.')[0]) // top level identifier (foo)
|
||||
.filter(name => !JS_KEYWORDS.includes(name)) // exclude js keywords
|
||||
.filter((match) => /^[a-zA-Z$_]/.test(match)) // starts with valid js identifier (foo.bar)
|
||||
.map((match) => match.split('.')[0]) // top level identifier (foo)
|
||||
.filter((name) => !JS_KEYWORDS.includes(name)) // exclude js keywords
|
||||
);
|
||||
|
||||
// globals such as Math
|
||||
const globals = [...vars].filter(name => name in globalThis);
|
||||
const globals = [...vars].filter((name) => name in globalThis);
|
||||
|
||||
const code = {
|
||||
vars: [...vars].join(", "),
|
||||
vars: [...vars].join(', '),
|
||||
// pick global from context or globalThis
|
||||
globals: globals
|
||||
.map(name => ` ${name} = ${name} ?? globalThis.${name};`)
|
||||
.join('')
|
||||
globals: globals.map((name) => ` ${name} = ${name} ?? globalThis.${name};`).join('')
|
||||
};
|
||||
|
||||
const body = `let { ${code.vars} } = context; ${code.globals}; return ${expr}`;
|
||||
|
||||
return new Function("context", body);
|
||||
return new Function('context', body);
|
||||
};
|
||||
|
||||
const internalExpressionCache = new Map();
|
||||
@ -55,47 +55,47 @@ const internalExpressionCache = new Map();
|
||||
const evaluateJsExpression = (expression, context) => {
|
||||
let fn = internalExpressionCache.get(expression);
|
||||
if (fn == null) {
|
||||
internalExpressionCache.set(expression, fn = compileJsExpression(expression));
|
||||
internalExpressionCache.set(expression, (fn = compileJsExpression(expression)));
|
||||
}
|
||||
return fn(context);
|
||||
};
|
||||
|
||||
const evaluateJsTemplateLiteral = (templateLiteral, context) => {
|
||||
if(!templateLiteral || !templateLiteral.length || typeof templateLiteral !== 'string') {
|
||||
if (!templateLiteral || !templateLiteral.length || typeof templateLiteral !== 'string') {
|
||||
return templateLiteral;
|
||||
}
|
||||
|
||||
templateLiteral = templateLiteral.trim();
|
||||
|
||||
if(templateLiteral === 'true') {
|
||||
if (templateLiteral === 'true') {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(templateLiteral === 'false') {
|
||||
if (templateLiteral === 'false') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(templateLiteral === 'null') {
|
||||
if (templateLiteral === 'null') {
|
||||
return null;
|
||||
}
|
||||
|
||||
if(templateLiteral === 'undefined') {
|
||||
if (templateLiteral === 'undefined') {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if(templateLiteral.startsWith('"') && templateLiteral.endsWith('"')) {
|
||||
if (templateLiteral.startsWith('"') && templateLiteral.endsWith('"')) {
|
||||
return templateLiteral.slice(1, -1);
|
||||
}
|
||||
|
||||
if(templateLiteral.startsWith("'") && templateLiteral.endsWith("'")) {
|
||||
if (templateLiteral.startsWith("'") && templateLiteral.endsWith("'")) {
|
||||
return templateLiteral.slice(1, -1);
|
||||
}
|
||||
|
||||
if(!isNaN(templateLiteral)) {
|
||||
if (!isNaN(templateLiteral)) {
|
||||
return Number(templateLiteral);
|
||||
}
|
||||
|
||||
templateLiteral = "`" + templateLiteral + "`";
|
||||
templateLiteral = '`' + templateLiteral + '`';
|
||||
|
||||
return evaluateJsExpression(templateLiteral, context);
|
||||
};
|
||||
@ -123,4 +123,4 @@ module.exports = {
|
||||
evaluateJsTemplateLiteral,
|
||||
createResponseParser,
|
||||
internalExpressionCache
|
||||
};
|
||||
};
|
||||
|
@ -1,35 +1,35 @@
|
||||
const { describe, it, expect } = require("@jest/globals");
|
||||
const { evaluateJsExpression, internalExpressionCache: cache, createResponseParser } = require("../src/utils");
|
||||
const { describe, it, expect } = require('@jest/globals');
|
||||
const { evaluateJsExpression, internalExpressionCache: cache, createResponseParser } = require('../src/utils');
|
||||
|
||||
describe("utils", () => {
|
||||
describe("expression evaluation", () => {
|
||||
describe('utils', () => {
|
||||
describe('expression evaluation', () => {
|
||||
const context = {
|
||||
res: {
|
||||
data: { pets: ["bruno", "max"] }
|
||||
data: { pets: ['bruno', 'max'] }
|
||||
}
|
||||
};
|
||||
|
||||
beforeEach(() => cache.clear());
|
||||
afterEach(() => cache.clear());
|
||||
|
||||
it("should evaluate expression", () => {
|
||||
it('should evaluate expression', () => {
|
||||
let result;
|
||||
|
||||
result = evaluateJsExpression("res.data.pets", context);
|
||||
expect(result).toEqual(["bruno", "max"]);
|
||||
result = evaluateJsExpression('res.data.pets', context);
|
||||
expect(result).toEqual(['bruno', 'max']);
|
||||
|
||||
result = evaluateJsExpression("res.data.pets[0].toUpperCase()", context);
|
||||
expect(result).toEqual("BRUNO");
|
||||
result = evaluateJsExpression('res.data.pets[0].toUpperCase()', context);
|
||||
expect(result).toEqual('BRUNO');
|
||||
});
|
||||
|
||||
it("should cache expression", () => {
|
||||
it('should cache expression', () => {
|
||||
expect(cache.size).toBe(0);
|
||||
evaluateJsExpression("res.data.pets", context);
|
||||
evaluateJsExpression('res.data.pets', context);
|
||||
expect(cache.size).toBe(1);
|
||||
});
|
||||
|
||||
it("should use cached expression", () => {
|
||||
const expr = "res.data.pets";
|
||||
it('should use cached expression', () => {
|
||||
const expr = 'res.data.pets';
|
||||
|
||||
evaluateJsExpression(expr, context);
|
||||
|
||||
@ -42,79 +42,79 @@ describe("utils", () => {
|
||||
expect(cache.get(expr)).toBe(fn);
|
||||
});
|
||||
|
||||
it("should identify top level variables", () => {
|
||||
const expr = "res.data.pets[0].toUpperCase()";
|
||||
it('should identify top level variables', () => {
|
||||
const expr = 'res.data.pets[0].toUpperCase()';
|
||||
evaluateJsExpression(expr, context);
|
||||
expect(cache.get(expr).toString()).toContain("let { res } = context;");
|
||||
expect(cache.get(expr).toString()).toContain('let { res } = context;');
|
||||
});
|
||||
|
||||
it("should not duplicate variables", () => {
|
||||
const expr = "res.data.pets[0] + res.data.pets[1]";
|
||||
it('should not duplicate variables', () => {
|
||||
const expr = 'res.data.pets[0] + res.data.pets[1]';
|
||||
evaluateJsExpression(expr, context);
|
||||
expect(cache.get(expr).toString()).toContain("let { res } = context;");
|
||||
expect(cache.get(expr).toString()).toContain('let { res } = context;');
|
||||
});
|
||||
|
||||
it("should exclude js keywords like true false from vars", () => {
|
||||
const expr = "res.data.pets.length > 0 ? true : false";
|
||||
it('should exclude js keywords like true false from vars', () => {
|
||||
const expr = 'res.data.pets.length > 0 ? true : false';
|
||||
evaluateJsExpression(expr, context);
|
||||
expect(cache.get(expr).toString()).toContain("let { res } = context;");
|
||||
expect(cache.get(expr).toString()).toContain('let { res } = context;');
|
||||
});
|
||||
|
||||
it("should exclude numbers from vars", () => {
|
||||
const expr = "res.data.pets.length + 10";
|
||||
it('should exclude numbers from vars', () => {
|
||||
const expr = 'res.data.pets.length + 10';
|
||||
evaluateJsExpression(expr, context);
|
||||
expect(cache.get(expr).toString()).toContain("let { res } = context;");
|
||||
expect(cache.get(expr).toString()).toContain('let { res } = context;');
|
||||
});
|
||||
|
||||
it("should pick variables from complex expressions", () => {
|
||||
const expr = "res.data.pets.map(pet => pet.length)";
|
||||
it('should pick variables from complex expressions', () => {
|
||||
const expr = 'res.data.pets.map(pet => pet.length)';
|
||||
const result = evaluateJsExpression(expr, context);
|
||||
expect(result).toEqual([5, 3]);
|
||||
expect(cache.get(expr).toString()).toContain("let { res, pet } = context;");
|
||||
expect(cache.get(expr).toString()).toContain('let { res, pet } = context;');
|
||||
});
|
||||
|
||||
it("should be ok picking extra vars from strings", () => {
|
||||
it('should be ok picking extra vars from strings', () => {
|
||||
const expr = "'hello' + ' ' + res.data.pets[0]";
|
||||
const result = evaluateJsExpression(expr, context);
|
||||
expect(result).toBe("hello bruno");
|
||||
expect(result).toBe('hello bruno');
|
||||
// extra var hello is harmless
|
||||
expect(cache.get(expr).toString()).toContain("let { hello, res } = context;");
|
||||
expect(cache.get(expr).toString()).toContain('let { hello, res } = context;');
|
||||
});
|
||||
|
||||
it("should evaluate expressions referencing globals", () => {
|
||||
const startTime = new Date("2022-02-01").getTime();
|
||||
const currentTime = new Date("2022-02-02").getTime();
|
||||
it('should evaluate expressions referencing globals', () => {
|
||||
const startTime = new Date('2022-02-01').getTime();
|
||||
const currentTime = new Date('2022-02-02').getTime();
|
||||
|
||||
jest.useFakeTimers({ now: currentTime });
|
||||
|
||||
const expr = "Math.max(Date.now(), startTime)";
|
||||
const expr = 'Math.max(Date.now(), startTime)';
|
||||
const result = evaluateJsExpression(expr, { startTime });
|
||||
|
||||
expect(result).toBe(currentTime);
|
||||
|
||||
expect(cache.get(expr).toString()).toContain("Math = Math ?? globalThis.Math;");
|
||||
expect(cache.get(expr).toString()).toContain("Date = Date ?? globalThis.Date;");
|
||||
expect(cache.get(expr).toString()).toContain('Math = Math ?? globalThis.Math;');
|
||||
expect(cache.get(expr).toString()).toContain('Date = Date ?? globalThis.Date;');
|
||||
});
|
||||
|
||||
it("should use global overridden in context", () => {
|
||||
const startTime = new Date("2022-02-01").getTime();
|
||||
const currentTime = new Date("2022-02-02").getTime();
|
||||
it('should use global overridden in context', () => {
|
||||
const startTime = new Date('2022-02-01').getTime();
|
||||
const currentTime = new Date('2022-02-02').getTime();
|
||||
|
||||
jest.useFakeTimers({ now: currentTime });
|
||||
|
||||
const context = {
|
||||
Date: { now: () => new Date("2022-01-31").getTime() },
|
||||
Date: { now: () => new Date('2022-01-31').getTime() },
|
||||
startTime
|
||||
};
|
||||
|
||||
const expr = "Math.max(Date.now(), startTime)";
|
||||
const expr = 'Math.max(Date.now(), startTime)';
|
||||
const result = evaluateJsExpression(expr, context);
|
||||
|
||||
expect(result).toBe(startTime);
|
||||
});
|
||||
});
|
||||
|
||||
describe("response parser", () => {
|
||||
describe('response parser', () => {
|
||||
const res = createResponseParser({
|
||||
status: 200,
|
||||
data: {
|
||||
@ -127,13 +127,13 @@ describe("utils", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("should default to bruno query", () => {
|
||||
const value = res("..items[?].amount[0]", i => i.amount > 10);
|
||||
it('should default to bruno query', () => {
|
||||
const value = res('..items[?].amount[0]', (i) => i.amount > 10);
|
||||
expect(value).toBe(20);
|
||||
});
|
||||
|
||||
it("should allow json-query", () => {
|
||||
const value = res.jq("order.items[amount > 10].amount");
|
||||
it('should allow json-query', () => {
|
||||
const value = res.jq('order.items[amount > 10].amount');
|
||||
expect(value).toBe(20);
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user