Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Common add assert() function #898

Merged
6 changes: 6 additions & 0 deletions .changeset/ninety-paws-own.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@openfn/language-common': minor
---

Added an 'assert' function that throws an error when an expression or function
resolves to false
53 changes: 53 additions & 0 deletions packages/common/ast.json
Original file line number Diff line number Diff line change
Expand Up @@ -1544,6 +1544,59 @@
},
"valid": false
},
{
"name": "assert",
"params": [
"expression",
"errorMessage"
],
"docs": {
"description": "An assert function that throws an error when an expression or function resolves to false.\nOtherwise, it returns true.",
"tags": [
{
"title": "public",
"description": null,
"type": null
},
{
"title": "function",
"description": null,
"name": null
},
{
"title": "example",
"description": "assert('a' === 'b', '\"a\" is not equal to \"b\"')"
},
{
"title": "param",
"description": "The expression or function to be evaluated.",
"type": {
"type": "NameExpression",
"name": "any"
},
"name": "expression"
},
{
"title": "param",
"description": "The error message thrown in case of a failed state.",
"type": {
"type": "NameExpression",
"name": "string"
},
"name": "errorMessage"
},
{
"title": "returns",
"description": "Always returns true if the assertion passes.",
"type": {
"type": "NameExpression",
"name": "boolean"
}
}
]
},
"valid": true
},
{
"name": "map",
"params": [
Expand Down
23 changes: 23 additions & 0 deletions packages/common/src/Adaptor.js
Original file line number Diff line number Diff line change
Expand Up @@ -903,3 +903,26 @@ export function cursor(value, options = {}) {
return state;
};
}

/**
* An assert function that throws an error when an expression or function resolves to false.
* Otherwise, it returns true.
* @public
* @function
* @example
* assert('a' === 'b', '"a" is not equal to "b"')
* @param {any} expression - The expression or function to be evaluated.
* @param {string} errorMessage - The error message thrown in case of a failed state.
* @returns {operation}
*/
export function assert (expression, errorMessage) {
return state => {
const [resolvedValue] = newExpandReferences(state,expression);

if(!resolvedValue){
throw new Error(errorMessage || `assertion statement failed with ${resolvedValue}`);
}

return state;
}
}
58 changes: 58 additions & 0 deletions packages/common/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
splitKeys,
toArray,
validate,
assert as assertCommon
} from '../src/Adaptor';
import { startOfToday } from 'date-fns';

Expand Down Expand Up @@ -1046,3 +1047,60 @@ describe('group', () => {
expect(result.data).eql({ a: [{ x: 'a', y: { z: 'a' } }] });
});
});

describe("assert", () => {
PiusKariuki marked this conversation as resolved.
Show resolved Hide resolved
it("throws an error when a function returns false", () => {
let error;

const testFunction = function(){
return "a" === "b"
}

const errorMessage = "a is not equal to b";

try {
assertCommon(testFunction, errorMessage)({});
} catch(e) {
error = e
}

assert.equal(error.message, errorMessage)
})

it("throws an error when an expression evaluates to false", () => {
let error;
const errorMessage = "a is not equal to b";

try {
assertCommon(("a"==="b"), errorMessage)({});
} catch(e) {
error = e
}

assert.equal(error.message, errorMessage)
});

it("returns true when an expression evaluates to true", () => {
const state = { name: "Jane" }
const result = assertCommon(("a"==="a"), "a is not equal to a")(state);
assert.equal(result, state);
});

it("returns true when an argument is neither an expression nor a function", () => {
const state = { name: "Jane" }
const result = assertCommon(("a"), "a is not equal to b")(state);
assert.equal(result, state);
});

it("falls back to the generic message if no 'errorMessage' argument is passed", () => {
let error;

try {
assertCommon(("a" === "b"))({});
} catch (e) {
error = e;
}

assert.equal(error.message, `assertion statement failed with false`);
});
});