mirror of
https://github.com/usebruno/bruno.git
synced 2025-01-03 04:29:09 +01:00
feat: integrated assert runtime for ui
This commit is contained in:
parent
34a2e23dc6
commit
8044286b80
@ -49,14 +49,6 @@ const AssertionOperator = ({ operator, onChange }) => {
|
|||||||
return 'equals';
|
return 'equals';
|
||||||
case 'neq':
|
case 'neq':
|
||||||
return 'notEquals';
|
return 'notEquals';
|
||||||
case 'gt':
|
|
||||||
return 'greaterThan';
|
|
||||||
case 'gte':
|
|
||||||
return 'greaterThanOrEqual';
|
|
||||||
case 'lt':
|
|
||||||
return 'lessThan';
|
|
||||||
case 'lte':
|
|
||||||
return 'lessThanOrEqual';
|
|
||||||
default:
|
default:
|
||||||
return operator;
|
return operator;
|
||||||
}
|
}
|
||||||
|
@ -94,8 +94,6 @@ const AssertionRow = ({
|
|||||||
operator,
|
operator,
|
||||||
value
|
value
|
||||||
} = parseAssertionOperator(assertion.value);
|
} = parseAssertionOperator(assertion.value);
|
||||||
console.log(operator);
|
|
||||||
console.log(value);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<tr key={assertion.uid}>
|
<tr key={assertion.uid}>
|
||||||
|
@ -7,10 +7,10 @@ const StyledWrapper = styled.div`
|
|||||||
|
|
||||||
.test-failure {
|
.test-failure {
|
||||||
color: ${(props) => props.theme.colors.text.danger};
|
color: ${(props) => props.theme.colors.text.danger};
|
||||||
|
}
|
||||||
|
|
||||||
.error-message {
|
.error-message {
|
||||||
color: ${(props) => props.theme.colors.text.muted};
|
color: ${(props) => props.theme.colors.text.muted};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import StyledWrapper from './StyledWrapper';
|
import StyledWrapper from './StyledWrapper';
|
||||||
|
|
||||||
const TestResults = ({ results }) => {
|
const TestResults = ({ results, assertionResults }) => {
|
||||||
if (!results || !results.length) {
|
results = results || [];
|
||||||
|
assertionResults = assertionResults || [];
|
||||||
|
if (!results.length && !assertionResults.length) {
|
||||||
return (
|
return (
|
||||||
<div className="px-3">
|
<div className="px-3">
|
||||||
No tests found
|
No tests found
|
||||||
@ -13,6 +15,9 @@ const TestResults = ({ results }) => {
|
|||||||
const passedTests = results.filter((result) => result.status === 'pass');
|
const passedTests = results.filter((result) => result.status === 'pass');
|
||||||
const failedTests = results.filter((result) => result.status === 'fail');
|
const failedTests = results.filter((result) => result.status === 'fail');
|
||||||
|
|
||||||
|
const passedAssertions = assertionResults.filter((result) => result.status === 'pass');
|
||||||
|
const failedAssertions = assertionResults.filter((result) => result.status === 'fail');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledWrapper className='flex flex-col px-3'>
|
<StyledWrapper className='flex flex-col px-3'>
|
||||||
<div className="py-2 font-medium test-summary">
|
<div className="py-2 font-medium test-summary">
|
||||||
@ -39,6 +44,31 @@ const TestResults = ({ results }) => {
|
|||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<div className="py-2 font-medium test-summary">
|
||||||
|
Assertions ({assertionResults.length}/{assertionResults.length}), Passed: {passedAssertions.length}, Failed: {failedAssertions.length}
|
||||||
|
</div>
|
||||||
|
<ul className="">
|
||||||
|
{assertionResults.map((result) => (
|
||||||
|
<li key={result.uid} className="py-1">
|
||||||
|
{result.status === 'pass' ? (
|
||||||
|
<span className="test-success">
|
||||||
|
✔ {result.lhsExpr}: {result.rhsExpr}
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<span className="test-failure">
|
||||||
|
✘ {result.lhsExpr}: {result.rhsExpr}
|
||||||
|
</span>
|
||||||
|
<br />
|
||||||
|
<span className="error-message pl-8">
|
||||||
|
{result.error}
|
||||||
|
</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
</StyledWrapper>
|
</StyledWrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,23 +1,31 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
const TestResultsLabel = ({ results }) => {
|
const TestResultsLabel = ({ results, assertionResults }) => {
|
||||||
if(!results || !results.length) {
|
results = results || [];
|
||||||
|
assertionResults = assertionResults || [];
|
||||||
|
if(!results.length && !assertionResults.length) {
|
||||||
return 'Tests';
|
return 'Tests';
|
||||||
}
|
}
|
||||||
|
|
||||||
const numberOfTests = results.length;
|
const numberOfTests = results.length;
|
||||||
const numberOfFailedTests = results.filter(result => result.status === 'fail').length;
|
const numberOfFailedTests = results.filter(result => result.status === 'fail').length;
|
||||||
|
|
||||||
|
const numberOfAssertions = assertionResults.length;
|
||||||
|
const numberOfFailedAssertions = assertionResults.filter(result => result.status === 'fail').length;
|
||||||
|
|
||||||
|
const totalNumberOfTests = numberOfTests + numberOfAssertions;
|
||||||
|
const totalNumberOfFailedTests = numberOfFailedTests + numberOfFailedAssertions;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex items-center'>
|
<div className='flex items-center'>
|
||||||
<div>Tests</div>
|
<div>Tests</div>
|
||||||
{numberOfFailedTests ? (
|
{totalNumberOfFailedTests ? (
|
||||||
<sup className='sups some-tests-failed ml-1 font-medium'>
|
<sup className='sups some-tests-failed ml-1 font-medium'>
|
||||||
{numberOfFailedTests}
|
{totalNumberOfFailedTests}
|
||||||
</sup>
|
</sup>
|
||||||
) : (
|
) : (
|
||||||
<sup className='sups all-tests-passed ml-1 font-medium'>
|
<sup className='sups all-tests-passed ml-1 font-medium'>
|
||||||
{numberOfTests}
|
{totalNumberOfTests}
|
||||||
</sup>
|
</sup>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -50,7 +50,7 @@ const ResponsePane = ({ rightPaneWidth, item, collection }) => {
|
|||||||
return <Timeline request={item.requestSent} response={item.response}/>;
|
return <Timeline request={item.requestSent} response={item.response}/>;
|
||||||
}
|
}
|
||||||
case 'tests': {
|
case 'tests': {
|
||||||
return <TestResults results={item.testResults} />;
|
return <TestResults results={item.testResults} assertionResults={item.assertionResults} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
@ -103,7 +103,7 @@ const ResponsePane = ({ rightPaneWidth, item, collection }) => {
|
|||||||
Timeline
|
Timeline
|
||||||
</div>
|
</div>
|
||||||
<div className={getTabClassname('tests')} role="tab" onClick={() => selectTab('tests')}>
|
<div className={getTabClassname('tests')} role="tab" onClick={() => selectTab('tests')}>
|
||||||
<TestResultsLabel results={item.testResults} />
|
<TestResultsLabel results={item.testResults} assertionResults={item.assertionResults} />
|
||||||
</div>
|
</div>
|
||||||
{!isLoading ? (
|
{!isLoading ? (
|
||||||
<div className="flex flex-grow justify-end items-center">
|
<div className="flex flex-grow justify-end items-center">
|
||||||
|
@ -50,6 +50,14 @@ export default function RunnerResults({collection}) {
|
|||||||
} else {
|
} else {
|
||||||
item.testStatus = 'pass';
|
item.testStatus = 'pass';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(item.assertionResults) {
|
||||||
|
const failed = item.assertionResults.filter((result) => result.status === 'fail');
|
||||||
|
|
||||||
|
item.assertionStatus = failed.length ? 'fail' : 'pass';
|
||||||
|
} else {
|
||||||
|
item.assertionStatus = 'pass';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -68,8 +76,12 @@ export default function RunnerResults({collection}) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const totalRequestsInCollection = getTotalRequestCountInCollection(collectionCopy);
|
const totalRequestsInCollection = getTotalRequestCountInCollection(collectionCopy);
|
||||||
const passedRequests = items.filter((item) => item.status !== "error" && item.testStatus === 'pass');
|
const passedRequests = items.filter((item) => {
|
||||||
const failedRequests = items.filter((item) => item.status !== "error" && item.testStatus === 'fail');
|
return item.status !== "error" && item.testStatus === 'pass' && item.assertionStatus === 'pass';
|
||||||
|
});
|
||||||
|
const failedRequests = items.filter((item) => {
|
||||||
|
return item.status !== "error" && item.testStatus === 'fail' || item.assertionStatus === 'fail';
|
||||||
|
});
|
||||||
|
|
||||||
if(!items || !items.length) {
|
if(!items || !items.length) {
|
||||||
return (
|
return (
|
||||||
@ -139,7 +151,7 @@ export default function RunnerResults({collection}) {
|
|||||||
|
|
||||||
<ul className="pl-8">
|
<ul className="pl-8">
|
||||||
{item.testResults ? item.testResults.map((result) => (
|
{item.testResults ? item.testResults.map((result) => (
|
||||||
<li key={result.uid} className="py-1">
|
<li key={result.uid}>
|
||||||
{result.status === 'pass' ? (
|
{result.status === 'pass' ? (
|
||||||
<span className="test-success flex items-center">
|
<span className="test-success flex items-center">
|
||||||
<IconCheck size={18} strokeWidth={2} className="mr-2"/>
|
<IconCheck size={18} strokeWidth={2} className="mr-2"/>
|
||||||
@ -158,6 +170,26 @@ export default function RunnerResults({collection}) {
|
|||||||
)}
|
)}
|
||||||
</li>
|
</li>
|
||||||
)): null}
|
)): null}
|
||||||
|
{item.assertionResults ? item.assertionResults.map((result) => (
|
||||||
|
<li key={result.uid}>
|
||||||
|
{result.status === 'pass' ? (
|
||||||
|
<span className="test-success flex items-center">
|
||||||
|
<IconCheck size={18} strokeWidth={2} className="mr-2"/>
|
||||||
|
{result.lhsExpr}: {result.rhsExpr}
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<span className="test-failure flex items-center">
|
||||||
|
<IconX size={18} strokeWidth={2} className="mr-2"/>
|
||||||
|
{result.lhsExpr}: {result.rhsExpr}
|
||||||
|
</span>
|
||||||
|
<span className="error-message pl-8 text-xs">
|
||||||
|
{result.error}
|
||||||
|
</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</li>
|
||||||
|
)): null}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -10,6 +10,7 @@ import {
|
|||||||
requestSentEvent,
|
requestSentEvent,
|
||||||
requestQueuedEvent,
|
requestQueuedEvent,
|
||||||
testResultsEvent,
|
testResultsEvent,
|
||||||
|
assertionResultsEvent,
|
||||||
scriptEnvironmentUpdateEvent,
|
scriptEnvironmentUpdateEvent,
|
||||||
collectionRenamedEvent,
|
collectionRenamedEvent,
|
||||||
runFolderEvent
|
runFolderEvent
|
||||||
@ -111,6 +112,10 @@ const useCollectionTreeSync = () => {
|
|||||||
dispatch(testResultsEvent(val));
|
dispatch(testResultsEvent(val));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const _assertionResults = (val) => {
|
||||||
|
dispatch(assertionResultsEvent(val));
|
||||||
|
};
|
||||||
|
|
||||||
const _collectionRenamed = (val) => {
|
const _collectionRenamed = (val) => {
|
||||||
dispatch(collectionRenamedEvent(val));
|
dispatch(collectionRenamedEvent(val));
|
||||||
};
|
};
|
||||||
@ -129,8 +134,9 @@ const useCollectionTreeSync = () => {
|
|||||||
const removeListener6 = ipcRenderer.on('main:script-environment-update', _scriptEnvironmentUpdate);
|
const removeListener6 = ipcRenderer.on('main:script-environment-update', _scriptEnvironmentUpdate);
|
||||||
const removeListener7 = ipcRenderer.on('main:http-request-queued', _httpRequestQueued);
|
const removeListener7 = ipcRenderer.on('main:http-request-queued', _httpRequestQueued);
|
||||||
const removeListener8 = ipcRenderer.on('main:test-results', _testResults);
|
const removeListener8 = ipcRenderer.on('main:test-results', _testResults);
|
||||||
const removeListener9 = ipcRenderer.on('main:collection-renamed', _collectionRenamed);
|
const removeListener9 = ipcRenderer.on('main:assertion-results', _assertionResults);
|
||||||
const removeListener10 = ipcRenderer.on('main:run-folder-event', _runFolderEvent);
|
const removeListener10 = ipcRenderer.on('main:collection-renamed', _collectionRenamed);
|
||||||
|
const removeListener11 = ipcRenderer.on('main:run-folder-event', _runFolderEvent);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
removeListener1();
|
removeListener1();
|
||||||
@ -143,6 +149,7 @@ const useCollectionTreeSync = () => {
|
|||||||
removeListener8();
|
removeListener8();
|
||||||
removeListener9();
|
removeListener9();
|
||||||
removeListener10();
|
removeListener10();
|
||||||
|
removeListener11();
|
||||||
};
|
};
|
||||||
}, [isElectron]);
|
}, [isElectron]);
|
||||||
};
|
};
|
||||||
|
@ -1022,6 +1022,19 @@ export const collectionsSlice = createSlice({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
assertionResultsEvent: (state, action) => {
|
||||||
|
const { itemUid, collectionUid, results } = action.payload;
|
||||||
|
const collection = findCollectionByUid(state.collections, collectionUid);
|
||||||
|
console.log(results);
|
||||||
|
|
||||||
|
if (collection) {
|
||||||
|
const item = findItemInCollection(collection, itemUid);
|
||||||
|
|
||||||
|
if (item) {
|
||||||
|
item.assertionResults = results;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
collectionRenamedEvent: (state, action) => {
|
collectionRenamedEvent: (state, action) => {
|
||||||
const { collectionPathname, newName } = action.payload;
|
const { collectionPathname, newName } = action.payload;
|
||||||
const collection = findCollectionByPathname(state.collections, collectionPathname);
|
const collection = findCollectionByPathname(state.collections, collectionPathname);
|
||||||
@ -1112,6 +1125,11 @@ export const collectionsSlice = createSlice({
|
|||||||
item.testResults = action.payload.testResults;
|
item.testResults = action.payload.testResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(type === 'assertion-results') {
|
||||||
|
const item = collection.runnerResult.items.find((i) => i.uid === request.uid);
|
||||||
|
item.assertionResults = action.payload.assertionResults;
|
||||||
|
}
|
||||||
|
|
||||||
if(type === 'error') {
|
if(type === 'error') {
|
||||||
const item = collection.runnerResult.items.find((i) => i.uid === request.uid);
|
const item = collection.runnerResult.items.find((i) => i.uid === request.uid);
|
||||||
item.error = action.payload.error;
|
item.error = action.payload.error;
|
||||||
@ -1187,6 +1205,7 @@ export const {
|
|||||||
collectionUnlinkDirectoryEvent,
|
collectionUnlinkDirectoryEvent,
|
||||||
collectionAddEnvFileEvent,
|
collectionAddEnvFileEvent,
|
||||||
testResultsEvent,
|
testResultsEvent,
|
||||||
|
assertionResultsEvent,
|
||||||
collectionRenamedEvent,
|
collectionRenamedEvent,
|
||||||
toggleRunnerView,
|
toggleRunnerView,
|
||||||
showRunnerView,
|
showRunnerView,
|
||||||
|
@ -167,6 +167,19 @@ const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// run assertions
|
||||||
|
const assertions = get(request, 'assertions');
|
||||||
|
if(assertions && assertions.length) {
|
||||||
|
const assertRuntime = new AssertRuntime();
|
||||||
|
const results = assertRuntime.runAssertions(assertions, request, response, envVars, collectionVariables, collectionPath);
|
||||||
|
|
||||||
|
mainWindow.webContents.send('main:assertion-results', {
|
||||||
|
results: results,
|
||||||
|
itemUid: item.uid,
|
||||||
|
collectionUid
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// run tests
|
// run tests
|
||||||
const testFile = get(item, 'request.tests');
|
const testFile = get(item, 'request.tests');
|
||||||
if(testFile && testFile.length) {
|
if(testFile && testFile.length) {
|
||||||
@ -359,7 +372,13 @@ const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
|
|||||||
const postResponseVars = get(request, 'vars.res', []);
|
const postResponseVars = get(request, 'vars.res', []);
|
||||||
if(postResponseVars && postResponseVars.length) {
|
if(postResponseVars && postResponseVars.length) {
|
||||||
const varsRuntime = new VarsRuntime();
|
const varsRuntime = new VarsRuntime();
|
||||||
varsRuntime.runPostResponseVars(postResponseVars, request, response, envVars, collectionVariables, collectionPath);
|
const result = varsRuntime.runPostResponseVars(postResponseVars, request, response, envVars, collectionVariables, collectionPath);
|
||||||
|
|
||||||
|
mainWindow.webContents.send('main:script-environment-update', {
|
||||||
|
envVariables: result.envVariables,
|
||||||
|
collectionVariables: result.collectionVariables,
|
||||||
|
collectionUid
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// run response script
|
// run response script
|
||||||
@ -375,6 +394,21 @@ const registerNetworkIpc = (mainWindow, watcher, lastOpenedCollections) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// run assertions
|
||||||
|
const assertions = get(item, 'request.assertions');
|
||||||
|
if(assertions && assertions.length) {
|
||||||
|
const assertRuntime = new AssertRuntime();
|
||||||
|
const results = assertRuntime.runAssertions(assertions, request, response, envVars, collectionVariables, collectionPath);
|
||||||
|
|
||||||
|
mainWindow.webContents.send('main:run-folder-event', {
|
||||||
|
type: 'assertion-results',
|
||||||
|
assertionResults: results,
|
||||||
|
itemUid: item.uid,
|
||||||
|
collectionUid
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// run tests
|
||||||
const testFile = get(item, 'request.tests');
|
const testFile = get(item, 'request.tests');
|
||||||
if(testFile && testFile.length) {
|
if(testFile && testFile.length) {
|
||||||
const testRuntime = new TestRuntime();
|
const testRuntime = new TestRuntime();
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const chai = require('chai');
|
const chai = require('chai');
|
||||||
|
const { nanoid } = require('nanoid');
|
||||||
const Bru = require('../bru');
|
const Bru = require('../bru');
|
||||||
const BrunoRequest = require('../bruno-request');
|
const BrunoRequest = require('../bruno-request');
|
||||||
const { evaluateJsExpression, createResponseParser } = require('../utils');
|
const { evaluateJsTemplateLiteral, evaluateJsExpression, createResponseParser } = require('../utils');
|
||||||
|
|
||||||
const { expect } = chai;
|
const { expect } = chai;
|
||||||
|
|
||||||
@ -51,9 +52,20 @@ const parseAssertionOperator = (str = '') => {
|
|||||||
'isDefined', 'isTruthy', 'isFalsy', 'isJson', 'isNumber', 'isString', 'isBoolean'
|
'isDefined', 'isTruthy', 'isFalsy', 'isJson', 'isNumber', 'isString', 'isBoolean'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const unaryOperators = [
|
||||||
|
'isEmpty', 'isNull', 'isUndefined', 'isDefined', 'isTruthy', 'isFalsy', 'isJson', 'isNumber', 'isString', 'isBoolean'
|
||||||
|
];
|
||||||
|
|
||||||
const [operator, ...rest] = str.trim().split(' ');
|
const [operator, ...rest] = str.trim().split(' ');
|
||||||
const value = rest.join(' ');
|
const value = rest.join(' ');
|
||||||
|
|
||||||
|
if(unaryOperators.includes(operator)) {
|
||||||
|
return {
|
||||||
|
operator,
|
||||||
|
value: ''
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if(operators.includes(operator)) {
|
if(operators.includes(operator)) {
|
||||||
return {
|
return {
|
||||||
operator,
|
operator,
|
||||||
@ -67,6 +79,45 @@ const parseAssertionOperator = (str = '') => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isUnaryOperator = (operator) => {
|
||||||
|
const unaryOperators = [
|
||||||
|
'isEmpty', 'isNull', 'isUndefined', 'isDefined', 'isTruthy', 'isFalsy', 'isJson', 'isNumber', 'isString', 'isBoolean'
|
||||||
|
];
|
||||||
|
|
||||||
|
return unaryOperators.includes(operator);
|
||||||
|
};
|
||||||
|
|
||||||
|
const evaluateRhsOperand = (rhsOperand, operator, context) => {
|
||||||
|
if(isUnaryOperator(operator)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// gracefulle allyow both a,b as well as [a, b]
|
||||||
|
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') {
|
||||||
|
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('/')) {
|
||||||
|
rhsOperand = rhsOperand.substring(1, rhsOperand.length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rhsOperand;
|
||||||
|
}
|
||||||
|
|
||||||
|
return evaluateJsTemplateLiteral(rhsOperand, context);
|
||||||
|
};
|
||||||
|
|
||||||
class AssertRuntime {
|
class AssertRuntime {
|
||||||
runAssertions(assertions, request, response, envVariables, collectionVariables, collectionPath) {
|
runAssertions(assertions, request, response, envVariables, collectionVariables, collectionPath) {
|
||||||
const enabledAssertions = _.filter(assertions, (a) => a.enabled);
|
const enabledAssertions = _.filter(assertions, (a) => a.enabled);
|
||||||
@ -103,7 +154,7 @@ class AssertRuntime {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const lhs = evaluateJsExpression(lhsExpr, context);
|
const lhs = evaluateJsExpression(lhsExpr, context);
|
||||||
const rhs = evaluateJsExpression(rhsOperand, context);
|
const rhs = evaluateRhsOperand(rhsOperand, operator, context);
|
||||||
|
|
||||||
switch(operator) {
|
switch(operator) {
|
||||||
case 'eq':
|
case 'eq':
|
||||||
@ -191,6 +242,7 @@ class AssertRuntime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assertionResults.push({
|
assertionResults.push({
|
||||||
|
uid: nanoid(),
|
||||||
lhsExpr,
|
lhsExpr,
|
||||||
rhsExpr,
|
rhsExpr,
|
||||||
rhsOperand,
|
rhsOperand,
|
||||||
@ -200,6 +252,7 @@ class AssertRuntime {
|
|||||||
}
|
}
|
||||||
catch (err) {
|
catch (err) {
|
||||||
assertionResults.push({
|
assertionResults.push({
|
||||||
|
uid: nanoid(),
|
||||||
lhsExpr,
|
lhsExpr,
|
||||||
rhsExpr,
|
rhsExpr,
|
||||||
rhsOperand,
|
rhsOperand,
|
||||||
|
Loading…
Reference in New Issue
Block a user