Skip to content

Commit

Permalink
Expands load function, experiments with loading assertions from tests.
Browse files Browse the repository at this point in the history
- Matches the behavior of `load` function in V8, SpiderMonkey, Rhino, etc.
- Converts a few tests to load `tools/assertions.js` rather than define
  the assertion helpers within the test scripts themselves. Also a bit
  of hoop-jumping to get compatibility with Node.js which doesn't
  include/expose V8's `load` but does have `require`.
- `load` works well when the script is run as a file, but there are
  still issues with using it from the REPL.
  • Loading branch information
ndreynolds committed Apr 11, 2013
1 parent d6f03f3 commit ab5382d
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 44 deletions.
3 changes: 1 addition & 2 deletions src/eval.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,7 @@ fh_var_dec_scan(js_val *ctx, ast_node *node)
// Declare the variable and possibly convert it to an assignment
if (node->type == NODE_VAR_DEC) {
fh_var_dec(ctx, node, true); // true to ignore rhs
// Signals that it has been hoisted
node->val = 1;
node->val = 1; // Signals that it has been hoisted
}

// Recurse sub nodes, will hit the whole tree.
Expand Down
21 changes: 14 additions & 7 deletions src/runtime/runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/

#include <math.h>
#include <unistd.h>
#include "runtime.h"
#include "lib/console.h"
#include "lib/Math.h"
Expand Down Expand Up @@ -94,16 +95,22 @@ global_gc(js_val *instance, js_args *args, eval_state *state)

// load(filename)
//
// Custom Flathead function. Execute the given file in the
// global scope. Parsing and evaluation occur at runtime.
// Execute the file with the given name in the global scope. Compatible
// with the function of the same name in V8, SpiderMonkey and Rhino.
js_val *
global_load(js_val *instance, js_args *args, eval_state *state)
{
js_val *name = TO_STR(ARG(args, 0));

FILE *file = fopen(name->string.ptr, "r");
fh_eval_file(file, fh->global, false);

unsigned int i;
js_val *name;
for (i = 0; i < ARGLEN(args); i++) {
name = TO_STR(ARG(args, i));
if (access(name->string.ptr, R_OK) == -1)
fh_error(state, E_ERROR, "File could not be read");

FILE *file = fopen(name->string.ptr, "r");
fh_eval_file(file, fh->global, false);
fclose(file);
}
return JSUNDEF();
}

Expand Down
19 changes: 1 addition & 18 deletions test/test_array_global.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,7 @@
// test_array_global.js
// --------------------

var assert = console.assert;

var assertEquals = function(a, b) {
if (a !== b)
console.log(a + ' !== ' + b);
assert(a === b);
};

var assertArrayEquals = function(a, b) {
assert(a.length === b.length);
for (var i = 0; i < a.length; i++) {
assert(a[i] === b[i]);
}
};

var test = function(name, f) {
f();
};
(this.load || require)((this.load ? 'test' : '.') + '/tools/assertions.js');


// ----------------------------------------------------------------------------
Expand Down
14 changes: 1 addition & 13 deletions test/test_math.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,13 @@
// ------------
// Tests for the Math global object, some adapted from v8's mjsunit.

var assert = console.assert;

var assertEquals = function(a, b) {
assert(a === b);
};

var assertClose = function(a, b, tolerance) {
assert(a < (b + tolerance));
assert(a > (b - tolerance));
};
(this.load || require)((this.load ? 'test' : '.') + '/tools/assertions.js');

var zero = function() {
var x = 0.5;
return (function() { return x - 0.5; }());
};

var test = function(name, f) {
f();
};

// ----------------------------------------------------------------------------
// Properties
Expand Down
6 changes: 3 additions & 3 deletions test/test_number_global.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ test('Properties', function() {
assert(Number.MAX_VALUE);
assert(Number.MIN_VALUE);
assert(isNaN(Number.NaN) && Number.NaN !== undefined);
assert(Number.NEGATIVE_INFINITY === -Infinity);
assert(Number.POSITIVE_INFINITY === Infinity);
assertEquals(-Infinity, Number.NEGATIVE_INFINITY);
assertEquals( Infinity, Number.POSITIVE_INFINITY);
});

// TODO: Harmony Number.isNaN & Number.isFinite ?
Expand All @@ -63,7 +63,7 @@ test('Number#toExponential([fracDigits])', function() {

num = 0.000414723723471;
// TODO: precision is off (though otherwise correct)
//assert(num.toExponential() === '4.14723723471e-4');
// assert(num.toExponential() === '4.14723723471e-4');
});

test('Number#toFixed([digits])', function() {
Expand Down
65 changes: 65 additions & 0 deletions test/tools/assertions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// assertions.js
// -------------

(function() {

// If this is a Node.js require, we need to set up the assertion helpers on
// the GLOBAL object for compatability with the other implementations that
// use `load` to evaluate this file.
var root = this.GLOBAL || this;

root.assert = console.assert;

root.assertTrue = function(a) { assert(a); };

root.assertFalse = function(a) { assert(!a); };

root.assertEquals = function(a, b) {
if (a !== b)
console.log(a + ' !== ' + b);
assert(a === b);
};

root.assertArrayEquals = function(a, b) {
assert(a.length === b.length);
for (var i = 0; i < a.length; i++) {
assert(a[i] === b[i]);
}
};

root.assertRegExpEquals = function(a, b) {
assertEquals(a.source, b.source);
assertEquals(a.global, b.global);
assertEquals(a.multiline, b.multiline);
assertEquals(a.ignoreCase, b.ignoreCase);
};

root.assertEmptyRegExp = function(r, cmp) {
// The value of the 'source' prop seems to be implementation-specific
// when the 'pattern' constructor argument is undefined.
//
// Either '(?:)' or '' is acceptable.
if (!(r.source === '(?:)' || r.source === ''))
assert(false);
assertEquals(r.global, cmp.global);
assertEquals(r.multiline, cmp.multiline);
assertEquals(r.ignoreCase, cmp.ignoreCase);
};

root.assertBetween = function(x, min, max) {
assert(x > min && x < max); // exclusive
};

root.assertClose = function(a, b, tolerance) {
assert(a < (b + tolerance));
assert(a > (b - tolerance));
};

// For now this is just a way to structure tests, but later it may be used to
// generate reports.
root.test = function(name, f) {
f();
};

root.assertionsLoaded = true;
})();
16 changes: 15 additions & 1 deletion test/tools/harness.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
// harness.js
// ----------
// Normalize testing between implementations.


// Define a basic console for implementations that do not provide one.

if (typeof console !== 'object') {
console = {

log: function() {
var args = Array.prototype.slice.call(arguments);
for (var i = 0; i < args.length; i++)
Expand All @@ -19,6 +23,16 @@ if (typeof console !== 'object') {
if (!assertion)
throw new Error("assertion failed");
}
};
}

// If this isn't available, the assertions.js script should be included as a
// command-line argument. Seems to be present in at least V8, SpiderMonkey and
// Rhino.

if (typeof load !== 'function') {
load = function(scriptName) {
if (!assertionsLoaded)
throw new Error("Missing assertion helpers. Include tools/assertions.js");
};
}
Empty file modified test/tools/runner.js
100755 → 100644
Empty file.

0 comments on commit ab5382d

Please sign in to comment.