Skip to content

Commit

Permalink
update tests
Browse files Browse the repository at this point in the history
  • Loading branch information
christianp committed Dec 3, 2024
1 parent 2e1caec commit 02b8244
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 20 deletions.
42 changes: 33 additions & 9 deletions tests/jme-runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -11204,7 +11204,12 @@ Scope.prototype = /** @lends Numbas.jme.Scope.prototype */ {
} else {
var nlambda = new types.TLambda();
nlambda.names = tok.names;
nlambda.set_expr(jme.substituteTree(tok.expr, scope, true, false));
nlambda.make_signature();
var nscope = new Numbas.jme.Scope([scope]);
nlambda.all_names.forEach(function(name) {
nscope.deleteVariable(name);
});
nlambda.set_expr(jme.substituteTree(tok.expr, nscope, true, false));
return nlambda;
}

Expand Down Expand Up @@ -12128,13 +12133,7 @@ TLambda.prototype = {
this.names = names;
},

/** Set the body of this function. The argument names must already have been set.
*
* @param {Numbas.jme.tree} expr
*/
set_expr: function(expr) {
const lambda = this;
this.expr = expr;
make_signature: function(expr) {
var all_names = [];

/** Make the signature for the given argument.
Expand All @@ -12159,6 +12158,19 @@ TLambda.prototype = {

this.all_names = all_names;

return signature;
},

/** Set the body of this function. The argument names must already have been set.
*
* @param {Numbas.jme.tree} expr
*/
set_expr: function(expr) {
const lambda = this;
this.expr = expr;

const signature = this.make_signature();

this.fn = new jme.funcObj('', signature, '?', null, {
evaluate: function(args, scope) {
var nscope = new jme.Scope([scope]);
Expand Down Expand Up @@ -12805,7 +12817,11 @@ var findvars = jme.findvars = function(tree,boundvars,scope) {
return [];
}
} else {
return jme.findvars_args(tree.args, boundvars, scope);
var argvars = jme.findvars_args(tree.args, boundvars, scope);
if(tree.tok.type == 'function' && scope.getFunction(tree.tok.name).length == 0) {
argvars.push(tree.tok.name);
}
return argvars;
}
}

Expand Down Expand Up @@ -17052,6 +17068,13 @@ newBuiltin('numerical_compare',[TExpression,TExpression],TBool,null,{
}
});

newBuiltin('debug_log', ['?','?'], '?', null, {
evaluate: function(args, scope) {
console.log('DEBUG ' + args[1].value + ':', Numbas.jme.unwrapValue(args[0]));
return args[0];
}
}, {unwrapValues: false});

newBuiltin('scope_case_sensitive', ['?',TBool], '?', null, {
evaluate: function(args,scope) {
var caseSensitive = args.length>1 ? scope.evaluate(args[1]).value : true;
Expand Down Expand Up @@ -20273,6 +20296,7 @@ jme.variables.note_script_constructor = function(construct_scope, process_result
*/
function Script(source, base, scope) {
this.source = source;
scope = construct_scope(scope);
try {
var notes = source.split(/\n(\s*\n)+/);
var ntodo = {};
Expand Down
17 changes: 17 additions & 0 deletions tests/jme/doc-tests.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -5694,5 +5694,22 @@ export default
"examples": []
}
]
},
{
"name": "Debugging tools",
"fns": [
{
"name": "debug_log",
"keywords": [
"debug",
"log"
],
"noexamples": true,
"calling_patterns": [
"debug_log(x, label)"
],
"examples": []
}
]
}
]
6 changes: 4 additions & 2 deletions tests/jme/jme-tests.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ Numbas.queueScript('jme_tests',['qunit','jme','jme-rules','jme-display','jme-cal
deepCloseEqual(assert, Numbas.jme.findvars(Numbas.jme.compile('let([q,w],[2,3],x,z,x+y+q+w)')),['y','z'],'findvars on let with a sequence of names');
deepCloseEqual(assert, Numbas.jme.findvars(Numbas.jme.compile('x -> x+z')),['z'],'findvars on lambda');
deepCloseEqual(assert, Numbas.jme.findvars(Numbas.jme.compile('[x,[y,z]] -> x+y+z+w')),['w'],'findvars on lambda with destructuring');
deepCloseEqual(assert, Numbas.jme.findvars(Numbas.jme.compile('undefined_function(x)')),['x', 'undefined_function'],'Undefined function names are presumed to be missing variables.');
});

QUnit.test('findvars in HTML',function(assert) {
Expand All @@ -101,7 +102,7 @@ Numbas.queueScript('jme_tests',['qunit','jme','jme-rules','jme-display','jme-cal
d.innerHTML = '<p>$\\var{x} + \\simplify{f(y)-{y}}$</p><div eval-style="s">{f(c)}</div>';
var vars = s.findvars(d);
vars.sort();
deepCloseEqual(assert, vars,['c','s','x','y']);
deepCloseEqual(assert, vars,['c','f','s','x','y']);
});

QUnit.test('util',function(assert) {
Expand Down Expand Up @@ -775,6 +776,7 @@ Numbas.queueScript('jme_tests',['qunit','jme','jme-rules','jme-display','jme-cal
['let(f, x -> 2x, f(3))', 6, 'referring to an anonymous function as a variable'],
['let(z, 2, f, x -> x+z, f(1))', 3, 'using an external variable in an anonymous function'],
['let(z, 2, f, x -> x+z, let(z, 3, f(1)))', 3, 'external variables are bound at the point the anonymous function is defined'],
['let(z, 2, f, z -> z, f(1) + f(1))', 2, 'Named arguments are removed from the scope when constructing an anonymous function'],
['let(f, n -> 2i for: i of: 1..n, map(f(j),j,1..5))', [[2],[2,4],[2,4,6],[2,4,6,8],[2,4,6,8,10]], 'variables are kept free inside list comprehensions'],
];
tests.forEach(([expr, value, note]) => {
Expand Down Expand Up @@ -1588,7 +1590,7 @@ Numbas.queueScript('jme_tests',['qunit','jme','jme-rules','jme-display','jme-cal
outtype: 'number',
parameters: [{type: 'number', name: 'x'}]
});
deepCloseEqual(assert, Numbas.jme.findvars(Numbas.jme.compile('issue781(z)')),['z'],'Default findVars behaviour on custom javascript function');
deepCloseEqual(assert, Numbas.jme.findvars(Numbas.jme.compile('issue781(z)')),['z', 'issue781'],'Default findVars behaviour on custom javascript function');
});

QUnit.test('Rulesets',function(assert) {
Expand Down
42 changes: 33 additions & 9 deletions tests/numbas-runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -10795,7 +10795,12 @@ Scope.prototype = /** @lends Numbas.jme.Scope.prototype */ {
} else {
var nlambda = new types.TLambda();
nlambda.names = tok.names;
nlambda.set_expr(jme.substituteTree(tok.expr, scope, true, false));
nlambda.make_signature();
var nscope = new Numbas.jme.Scope([scope]);
nlambda.all_names.forEach(function(name) {
nscope.deleteVariable(name);
});
nlambda.set_expr(jme.substituteTree(tok.expr, nscope, true, false));
return nlambda;
}

Expand Down Expand Up @@ -11719,13 +11724,7 @@ TLambda.prototype = {
this.names = names;
},

/** Set the body of this function. The argument names must already have been set.
*
* @param {Numbas.jme.tree} expr
*/
set_expr: function(expr) {
const lambda = this;
this.expr = expr;
make_signature: function(expr) {
var all_names = [];

/** Make the signature for the given argument.
Expand All @@ -11750,6 +11749,19 @@ TLambda.prototype = {

this.all_names = all_names;

return signature;
},

/** Set the body of this function. The argument names must already have been set.
*
* @param {Numbas.jme.tree} expr
*/
set_expr: function(expr) {
const lambda = this;
this.expr = expr;

const signature = this.make_signature();

this.fn = new jme.funcObj('', signature, '?', null, {
evaluate: function(args, scope) {
var nscope = new jme.Scope([scope]);
Expand Down Expand Up @@ -12396,7 +12408,11 @@ var findvars = jme.findvars = function(tree,boundvars,scope) {
return [];
}
} else {
return jme.findvars_args(tree.args, boundvars, scope);
var argvars = jme.findvars_args(tree.args, boundvars, scope);
if(tree.tok.type == 'function' && scope.getFunction(tree.tok.name).length == 0) {
argvars.push(tree.tok.name);
}
return argvars;
}
}

Expand Down Expand Up @@ -16643,6 +16659,13 @@ newBuiltin('numerical_compare',[TExpression,TExpression],TBool,null,{
}
});

newBuiltin('debug_log', ['?','?'], '?', null, {
evaluate: function(args, scope) {
console.log('DEBUG ' + args[1].value + ':', Numbas.jme.unwrapValue(args[0]));
return args[0];
}
}, {unwrapValues: false});

newBuiltin('scope_case_sensitive', ['?',TBool], '?', null, {
evaluate: function(args,scope) {
var caseSensitive = args.length>1 ? scope.evaluate(args[1]).value : true;
Expand Down Expand Up @@ -19864,6 +19887,7 @@ jme.variables.note_script_constructor = function(construct_scope, process_result
*/
function Script(source, base, scope) {
this.source = source;
scope = construct_scope(scope);
try {
var notes = source.split(/\n(\s*\n)+/);
var ntodo = {};
Expand Down

0 comments on commit 02b8244

Please sign in to comment.