Skip to content

Commit

Permalink
do not allow empty math and arguments for defineFunction
Browse files Browse the repository at this point in the history
  • Loading branch information
metelkin committed Jun 4, 2024
1 parent 8696891 commit b264c1c
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 26 deletions.
2 changes: 1 addition & 1 deletion cases/24-define-function/platform.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"builderVersion": "^0.7.0",
"builderVersion": "*",
"id": "template",
"notes": "platform notes",
"version": "v0.1.0",
Expand Down
4 changes: 4 additions & 0 deletions cases/24-define-function/src/index.heta
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
math: f4(x)^2
};

// throws error
#defineFunction f6 {
};

/*
// ref to wrong function
#defineFunction f7 {
Expand Down
9 changes: 3 additions & 6 deletions src/container/core-items.json
Original file line number Diff line number Diff line change
Expand Up @@ -224,12 +224,10 @@
"arguments": ["x", "y"]
},
{
"id": "max", "action": "defineFunction",
"arguments": ["x"]
"id": "max", "action": "defineFunction"
},
{
"id": "min", "action": "defineFunction",
"arguments": ["x"]
"id": "min", "action": "defineFunction"
},
{
"id": "factorial", "action": "defineFunction",
Expand Down Expand Up @@ -306,7 +304,6 @@
},

{
"id": "piecewise", "action": "defineFunction",
"arguments": ["x"]
"id": "piecewise", "action": "defineFunction"
}
]
10 changes: 7 additions & 3 deletions src/core/function-def.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ class FunctionDef extends Top {
let valid = FunctionDef.isValid(q, logger);
if (!valid) { this.errored = true; return; }

// undefined arguments means it can be anything (for core elements)
// undefined arguments means it can vary (for core elements)
if (q.arguments) {
this.arguments = q.arguments;
} else if (q.math) {
let msg = `The FunctionDef ${q.id} with "math" property must have "arguments".`;
} else if (!isCore) {
let msg = `The #defineFunction ${q.id} must have "arguments".`;
logger && logger.error(msg, {type: 'ValidationError'});
this.errored = true;
}
Expand Down Expand Up @@ -83,6 +83,10 @@ class FunctionDef extends Top {
logger && logger.error(msg, {type: 'ValidationError'});
this.errored = true;
}
} else if (!isCore) {
let msg = `The #defineFunction ${q.id} must have "math".`;
logger && logger.error(msg, {type: 'ValidationError'});
this.errored = true;
}
}
get className(){
Expand Down
31 changes: 18 additions & 13 deletions src/module-system/sbml-parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,29 +196,34 @@ function unitDefinitionToUnits(x){
/*
transform SBML-like function definition to Heta-like unit array
*/
function functionDefinitionToQ(x){
function functionDefinitionToQ(x) {

let q = {
action: 'defineFunction',
id: x.attributes.id
};

let mathElement = x.elements?.find((y) => y.name === 'math');
let lambdaElement = mathElement?.elements?.find((y) => y.name === 'lambda');

if (!mathElement || !lambdaElement ) {
throw new HetaLevelError(`Heta does not support empty <math> or <lambda> "${q.id}" elements in FunctionDefinition,`);
}

// get argument ids
let args = lambdaElement.elements && lambdaElement.elements
.filter((y) => y.name === 'bvar')
q.args = lambdaElement.elements
?.filter((y) => y.name === 'bvar')
.map((y) => y.elements && y.elements.find((z) => z.name === 'ci'))
.map((y) => y.elements && y.elements.find((z) => z.type === 'text'))
.map((y) => y.text.trim());

// get expression
let notBvarElement = lambdaElement.elements
&& lambdaElement.elements.find((y) => y.name !== 'bvar');
let math = _toMathExpr(notBvarElement);
let notBvarElement = lambdaElement.elements
?.find((y) => y.name !== 'bvar');
q.math = _toMathExpr(notBvarElement);

return {
action: 'defineFunction',
id: x.attributes.id,
arguments: args,
math: math
};

return q;
}

/*
Expand Down Expand Up @@ -657,7 +662,7 @@ function eventToQ(x){
}
// assignments
let assignments = x.elements?.find((y) => y.name === 'listOfEventAssignments');
if (assignments.elements !== undefined) {
if (assignments?.elements !== undefined) {
assignments.elements
.filter((y) => y.name === 'eventAssignment')
.forEach((y) => {
Expand Down
7 changes: 4 additions & 3 deletions test/core/function-def.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@ describe('Unit test for FunctionDef', () => {
simple._container.logger.resetErrors();
});

it('defineFunction without math is ok.', () => {
it('defineFunction without math is not ok.', () => {
let simple = new p.classes.FunctionDef({
id: 'ud1',
arguments: ['x']
});
expect(simple._container.logger).to.has.property('hasErrors', false);
expect(simple._container.logger).to.has.property('hasErrors', true);
simple._container.logger.resetErrors();
});

it('Error: wrong input 1 (bad arguments).', () => {
Expand Down Expand Up @@ -99,7 +100,7 @@ describe('Testing loading FunctionDef', () => {

it('Load FunctionDef', () => {
p.loadMany(input0);
expect(p.functionDefStorage.size - counter).to.be.eq(4);
expect(p.functionDefStorage.size - counter).to.be.eq(3);
//console.log([...p.functionDefStorage])
p.logger.resetErrors();
});
Expand Down

0 comments on commit b264c1c

Please sign in to comment.