diff --git a/packages/bruno-app/src/components/RequestPane/Assertions/AssertionOperator/index.js b/packages/bruno-app/src/components/RequestPane/Assertions/AssertionOperator/index.js
new file mode 100644
index 00000000..993eb791
--- /dev/null
+++ b/packages/bruno-app/src/components/RequestPane/Assertions/AssertionOperator/index.js
@@ -0,0 +1,76 @@
+import React from 'react';
+
+/**
+ * Assertion operators
+ *
+ * eq : equal to
+ * neq : not equal to
+ * gt : greater than
+ * gte : greater than or equal to
+ * lt : less than
+ * lte : less than or equal to
+ * in : in
+ * notIn : not in
+ * contains : contains
+ * notContains : not contains
+ * length : length
+ * matches : matches
+ * notMatches : not matches
+ * startsWith : starts with
+ * endsWith : ends with
+ * between : between
+ * isEmpty : is empty
+ * isNull : is null
+ * isUndefined : is undefined
+ * isDefined : is defined
+ * isTruthy : is truthy
+ * isFalsy : is falsy
+ * isJson : is json
+ * isNumber : is number
+ * isString : is string
+ * isBoolean : is boolean
+ */
+
+const AssertionOperator = ({ operator, onChange }) => {
+ 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'
+ ];
+
+ const handleChange = (e) => {
+ onChange(e.target.value);
+ };
+
+ const getLabel = (operator) => {
+ switch(operator) {
+ case 'eq':
+ return 'equals';
+ case 'neq':
+ return 'notEquals';
+ case 'gt':
+ return 'greaterThan';
+ case 'gte':
+ return 'greaterThanOrEqual';
+ case 'lt':
+ return 'lessThan';
+ case 'lte':
+ return 'lessThanOrEqual';
+ default:
+ return operator;
+ }
+ };
+
+ return (
+
+ );
+};
+
+export default AssertionOperator;
diff --git a/packages/bruno-app/src/components/RequestPane/Assertions/AssertionRow/index.js b/packages/bruno-app/src/components/RequestPane/Assertions/AssertionRow/index.js
new file mode 100644
index 00000000..bbf18ad0
--- /dev/null
+++ b/packages/bruno-app/src/components/RequestPane/Assertions/AssertionRow/index.js
@@ -0,0 +1,164 @@
+import React from 'react';
+import { IconTrash } from '@tabler/icons';
+import SingleLineEditor from 'components/SingleLineEditor';
+import AssertionOperator from '../AssertionOperator';
+import { useTheme } from 'providers/Theme';
+
+/**
+ * Assertion operators
+ *
+ * eq : equal to
+ * neq : not equal to
+ * gt : greater than
+ * gte : greater than or equal to
+ * lt : less than
+ * lte : less than or equal to
+ * in : in
+ * notIn : not in
+ * contains : contains
+ * notContains : not contains
+ * length : length
+ * matches : matches
+ * notMatches : not matches
+ * startsWith : starts with
+ * endsWith : ends with
+ * between : between
+ * isEmpty : is empty
+ * isNull : is null
+ * isUndefined : is undefined
+ * isDefined : is defined
+ * isTruthy : is truthy
+ * isFalsy : is falsy
+ * isJson : is json
+ * isNumber : is number
+ * isString : is string
+ * isBoolean : is boolean
+ */
+const parseAssertionOperator = (str = '') => {
+ if(!str || typeof str !== 'string' || !str.length) {
+ return {
+ operator: 'eq',
+ value: 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'
+ ];
+
+ const unaryOperators = [
+ 'isEmpty', 'isNull', 'isUndefined', 'isDefined', 'isTruthy', 'isFalsy', 'isJson', 'isNumber', 'isString', 'isBoolean'
+ ];
+
+ const [operator, ...rest] = str.trim().split(' ');
+ const value = rest.join(' ');
+
+ if(unaryOperators.includes(operator)) {
+ return {
+ operator,
+ value: ''
+ };
+ }
+
+ if(operators.includes(operator)) {
+ return {
+ operator,
+ value
+ };
+ }
+
+ return {
+ operator: 'eq',
+ value: str
+ };
+};
+
+const isUnaryOperator = (operator) => {
+ const unaryOperators = [
+ 'isEmpty', 'isNull', 'isUndefined', 'isDefined', 'isTruthy', 'isFalsy', 'isJson', 'isNumber', 'isString', 'isBoolean'
+ ];
+
+ return unaryOperators.includes(operator);
+};
+
+const AssertionRow = ({
+ item, collection, assertion, handleAssertionChange, handleRemoveAssertion,
+ onSave, handleRun
+}) => {
+ const { storedTheme } = useTheme();
+
+ const {
+ operator,
+ value
+ } = parseAssertionOperator(assertion.value);
+ console.log(operator);
+ console.log(value);
+
+ return (
+
+
+ handleAssertionChange(e, assertion, 'name')}
+ />
+ |
+
+ handleAssertionChange({
+ target: {
+ value: `${op} ${value}`
+ }
+ }, assertion, 'value')}
+ />
+ |
+
+ {!isUnaryOperator(operator) ? (
+ handleAssertionChange({
+ target: {
+ value: newValue
+ }
+ }, assertion, 'value')}
+ onRun={handleRun}
+ collection={collection}
+ />
+ ) : (
+
+ )}
+ |
+
+
+ handleAssertionChange(e, assertion, 'enabled')}
+ />
+
+
+ |
+
+ );
+};
+
+export default AssertionRow;
diff --git a/packages/bruno-app/src/components/RequestPane/Assert/StyledWrapper.js b/packages/bruno-app/src/components/RequestPane/Assertions/StyledWrapper.js
similarity index 97%
rename from packages/bruno-app/src/components/RequestPane/Assert/StyledWrapper.js
rename to packages/bruno-app/src/components/RequestPane/Assertions/StyledWrapper.js
index b7c95b47..7357a74b 100644
--- a/packages/bruno-app/src/components/RequestPane/Assert/StyledWrapper.js
+++ b/packages/bruno-app/src/components/RequestPane/Assertions/StyledWrapper.js
@@ -24,7 +24,7 @@ const Wrapper = styled.div`
width: 30%;
}
- &:nth-child(3) {
+ &:nth-child(4) {
width: 70px;
}
}
diff --git a/packages/bruno-app/src/components/RequestPane/Assert/index.js b/packages/bruno-app/src/components/RequestPane/Assertions/index.js
similarity index 52%
rename from packages/bruno-app/src/components/RequestPane/Assert/index.js
rename to packages/bruno-app/src/components/RequestPane/Assertions/index.js
index 256a77c9..1805a632 100644
--- a/packages/bruno-app/src/components/RequestPane/Assert/index.js
+++ b/packages/bruno-app/src/components/RequestPane/Assertions/index.js
@@ -1,17 +1,14 @@
import React from 'react';
import get from 'lodash/get';
import cloneDeep from 'lodash/cloneDeep';
-import { IconTrash } from '@tabler/icons';
import { useDispatch } from 'react-redux';
-import { useTheme } from 'providers/Theme';
import { addAssertion, updateAssertion, deleteAssertion } from 'providers/ReduxStore/slices/collections';
import { sendRequest, saveRequest } from 'providers/ReduxStore/slices/collections/actions';
-import SingleLineEditor from 'components/SingleLineEditor';
+import AssertionRow from './AssertionRow';
import StyledWrapper from './StyledWrapper';
const Assertions = ({ item, collection }) => {
const dispatch = useDispatch();
- const { storedTheme } = useTheme();
const assertions = item.draft ? get(item, 'draft.request.assertions') : get(item, 'request.assertions');
const handleAddAssertion = () => {
@@ -66,55 +63,25 @@ const Assertions = ({ item, collection }) => {
Expr |
+ Operator |
Value |
|
{assertions && assertions.length
- ? assertions.map((assertion, index) => {
+ ? assertions.map((assertion) => {
return (
-
-
- handleAssertionChange(e, assertion, 'name')}
- />
- |
-
- handleAssertionChange({
- target: {
- value: newValue
- }
- }, assertion, 'value')}
- onRun={handleRun}
- collection={collection}
- />
- |
-
-
- handleAssertionChange(e, assertion, 'enabled')}
- />
-
-
- |
-
+
);
})
: null}
diff --git a/packages/bruno-app/src/components/RequestPane/HttpRequestPane/index.js b/packages/bruno-app/src/components/RequestPane/HttpRequestPane/index.js
index 5ddf2393..55da6c9c 100644
--- a/packages/bruno-app/src/components/RequestPane/HttpRequestPane/index.js
+++ b/packages/bruno-app/src/components/RequestPane/HttpRequestPane/index.js
@@ -8,7 +8,7 @@ import RequestHeaders from 'components/RequestPane/RequestHeaders';
import RequestBody from 'components/RequestPane/RequestBody';
import RequestBodyMode from 'components/RequestPane/RequestBody/RequestBodyMode';
import Vars from 'components/RequestPane/Vars';
-import Assert from 'components/RequestPane/Assert';
+import Assertions from 'components/RequestPane/Assertions';
import Script from 'components/RequestPane/Script';
import Tests from 'components/RequestPane/Tests';
import StyledWrapper from './StyledWrapper';
@@ -42,7 +42,7 @@ const HttpRequestPane = ({ item, collection, leftPaneWidth }) => {
return ;
}
case 'assert': {
- return ;
+ return ;
}
case 'script': {
return ;
diff --git a/packages/bruno-js/src/runtime/assert-runtime.js b/packages/bruno-js/src/runtime/assert-runtime.js
index 44e916cf..89ccddfb 100644
--- a/packages/bruno-js/src/runtime/assert-runtime.js
+++ b/packages/bruno-js/src/runtime/assert-runtime.js
@@ -11,7 +11,6 @@ const { expect } = chai;
*
* eq : equal to
* neq : not equal to
- * like : like
* gt : greater than
* gte : greater than or equal to
* lt : less than
@@ -20,7 +19,6 @@ const { expect } = chai;
* notIn : not in
* contains : contains
* notContains : not contains
- * count : count
* length : length
* matches : matches
* notMatches : not matches
@@ -47,8 +45,8 @@ const parseAssertionOperator = (str = '') => {
}
const operators = [
- 'eq', 'neq', 'like', 'gt', 'gte', 'lt', 'lte', 'in', 'notIn',
- 'contains', 'notContains', 'count', 'length', 'matches', 'notMatches',
+ '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'
];
@@ -114,9 +112,6 @@ class AssertRuntime {
case 'neq':
expect(lhs).to.not.equal(rhs);
break;
- case 'like':
- expect(lhs).to.match(new RegExp(rhs));
- break;
case 'gt':
expect(lhs).to.be.greaterThan(rhs);
break;
@@ -141,9 +136,6 @@ class AssertRuntime {
case 'notContains':
expect(lhs).to.not.include(rhs);
break;
- case 'count':
- expect(lhs).to.have.lengthOf(rhs);
- break;
case 'length':
expect(lhs).to.have.lengthOf(rhs);
break;
@@ -160,7 +152,7 @@ class AssertRuntime {
expect(lhs).to.endWith(rhs);
break;
case 'between':
- const [min, max] = value.split(' ');
+ const [min, max] = value.split(',');
expect(lhs).to.be.within(min, max);
break;
case 'isEmpty':