Update test framework: fix run_tests.py to support all test files, add auto-import-check for test files

This commit is contained in:
qiaoxinjiu
2026-05-09 15:11:30 +08:00
parent eb053a347f
commit eaba8328da
21739 changed files with 2236758 additions and 719 deletions

68
node_modules/bintrees/test/arrtree.js generated vendored Normal file
View File

@@ -0,0 +1,68 @@
// Not to be used in production!
// Only here to show how much faster bintrees are in the perf benchmarks.
function ArrTree(comparator) {
this._arr = [];
this._comparator = comparator;
}
// returns true if inserted, false if duplicate
ArrTree.prototype.insert = function(data) {
var elem_index = this._find_index(data);
if(elem_index >= 0) {
return false;
}
// recover the index data should have been inserted at and splice data in
this._arr.splice(~elem_index, 0, data);
return true;
};
// returns true if removed, false if not found
ArrTree.prototype.remove = function(data) {
var elem_index = this._find_index(data);
if(elem_index < 0) {
return false;
}
// array remains sorted after element has been removed
this._arr.splice(elem_index, 1);
return true;
};
ArrTree.prototype.find = function(data) {
var elem_index = this._find_index(data);
if(elem_index < 0) {
return null;
}
return this._arr[elem_index];
};
// returns the index if found,
// and the ones-complement of the index it should be inserted at if not
// NOTE: the ones-complement will always be < 0
ArrTree.prototype._find_index = function(data) {
var min_index = 0;
var max_index = this._arr.length - 1;
var current_index;
var current_element;
while(min_index <= max_index) {
current_index = (min_index + max_index) / 2 | 0;
current_element = this._arr[current_index];
if (this._comparator(current_element, data) < 0) {
min_index = current_index + 1;
}
else if(this._comparator(current_element, data) > 0) {
max_index = current_index - 1;
}
else {
return current_index;
}
}
return ~min_index;
}
module.exports = ArrTree;

52
node_modules/bintrees/test/loader.js generated vendored Normal file
View File

@@ -0,0 +1,52 @@
var fs = require('fs');
var _ = require('underscore');
function load(filename) {
var ret = [];
var nums = fs.readFileSync(filename, 'ascii').split('\n');
nums.forEach(function(s) {
if(s.length) {
var n = s*1;
ret.push(n);
}
});
return ret;
}
function get_inserts(tests) {
return _.select(tests, function(n) { return n > 0; });
}
function get_removes(tests) {
return _.select(tests, function(n) { return n < 0; });
}
function new_tree(tree_type) {
return new tree_type(function(a,b) { return a - b });
}
function build_tree(tree_type, inserts) {
var tree = new_tree(tree_type);
inserts.forEach(function(n) {
tree.insert(n);
});
return tree;
}
function load_tree(tree_type, filename) {
var tests = load(filename);
var inserts = get_inserts(tests);
return build_tree(tree_type, inserts);
}
module.exports = {
load: load,
get_inserts: get_inserts,
get_removes: get_removes,
new_tree: new_tree,
build_tree: build_tree,
load_tree: load_tree
};

200000
node_modules/bintrees/test/perf/100k generated vendored Normal file

File diff suppressed because it is too large Load Diff

113
node_modules/bintrees/test/perf_test.js generated vendored Normal file
View File

@@ -0,0 +1,113 @@
var fs = require('fs');
var loader = require('./loader');
var NUM_TIMES = 10;
var BASE_DIR = __dirname + '/perf';
var TREES = ['../test/arrtree', 'rbtree', 'bintree'];
function mean(arr) {
var sum = 0;
arr.forEach(function(n) {
sum += n;
});
return sum/arr.length;
}
function timeit(f) {
var diffs = [];
for(var i=0; i < NUM_TIMES; i++) {
var start = Date.now();
f();
var end = Date.now();
var diff = (end - start)/1000;
diffs.push(diff);
}
return diffs;
}
function print_times(arr) {
console.log('Mean: ', mean(arr));
}
function build(tree_class, test_path) {
var tests = loader.load(test_path);
var inserts = loader.get_inserts(tests);
console.log('build tree...');
print_times(timeit(function(){
loader.build_tree(tree_class, inserts);
}));
}
function build_destroy(tree_class, test_path) {
var tests = loader.load(test_path);
var inserts = loader.get_inserts(tests);
var removes = loader.get_removes(tests);
console.log('build/destroy tree...');
print_times(timeit(function() {
var tree = loader.build_tree(tree_class, inserts);
removes.forEach(function(n) {
tree.remove(n);
});
}));
}
function find(tree_class, test_path) {
var tests = loader.load(test_path);
var inserts = loader.get_inserts(tests);
var tree = loader.build_tree(tree_class, inserts);
console.log('find all nodes...');
print_times(timeit(function() {
inserts.forEach(function(n) {
tree.find(n);
});
}));
}
function interleaved(tree_class, test_path) {
var tests = loader.load(test_path);
console.log('interleaved build/destroy...');
print_times(timeit(function() {
var tree = new tree_class(function(a,b) { return a - b });
tests.forEach(function(n) {
if(n > 0)
tree.insert(n);
else
tree.remove(n);
});
}));
}
var tests = fs.readdirSync(BASE_DIR);
var test_funcs = {};
TREES.forEach(function(tree) {
var tree_class = require('../lib/' + tree);
tests.forEach(function(test) {
var test_path = BASE_DIR + "/" + test;
test_funcs[tree + "_" + test + "_build"] = function(assert) {
build(tree_class, test_path);
assert.done();
};
test_funcs[tree + "_" + test + "_build_destroy"] = function(assert) {
build_destroy(tree_class, test_path);
assert.done();
};
test_funcs[tree + "_" + test + "_find"] = function(assert) {
find(tree_class, test_path);
assert.done();
};
test_funcs[tree + "_" + test + "_interleaved"] = function(assert) {
interleaved(tree_class, test_path);
assert.done();
};
});
});
exports.performance = test_funcs;

20000
node_modules/bintrees/test/samples/10k generated vendored Normal file

File diff suppressed because it is too large Load Diff

38
node_modules/bintrees/test/scripts/gen_test.js generated vendored Normal file
View File

@@ -0,0 +1,38 @@
// generates a test case to STDOUT
var no_dups = false; // set to true if you don't want duplicate inserts
var num_inserts = 100000;
function randInt(start, end) {
return Math.floor(Math.random()*(end-start + 1)) + start;
}
function get_node_to_remove() {
var idx = randInt(0, added.length - 1);
return added.splice(idx, 1)[0];
}
var nums = [];
var added = [];
var ahash = {};
for(var i=0; i < num_inserts; i++) {
do {
var n = randInt(1, 1000000000);
} while(no_dups && ahash[n]);
added.push(n);
nums.push(n);
if(no_dups)
ahash[n] = true;
if(Math.random() < .3) {
// remove a node
nums.push(-get_node_to_remove());
}
}
// remove the rest, randomly
while(added.length > 0)
nums.push(-get_node_to_remove());
console.log(nums.join('\n'));

322
node_modules/bintrees/test/test_api.js generated vendored Normal file
View File

@@ -0,0 +1,322 @@
var _ = require('underscore');
var loader = require('./loader');
var SAMPLE_FILE = __dirname + '/samples/10k';
var TREES = ['rbtree', 'bintree'];
function clear(assert, tree_class) {
var inserts = loader.get_inserts(loader.load(SAMPLE_FILE));
var tree = loader.build_tree(tree_class, inserts);
tree.clear();
inserts.forEach(function(data) {
assert.equal(tree.find(data), null);
});
}
function dup(assert, tree_class) {
var tree = loader.new_tree(tree_class);
assert.ok(tree.insert(100));
assert.ok(tree.insert(101));
assert.ok(!tree.insert(101));
assert.ok(!tree.insert(100));
tree.remove(100);
assert.ok(!tree.insert(101));
assert.ok(tree.insert(100));
assert.ok(!tree.insert(100));
}
function nonexist(assert, tree_class) {
var tree = loader.new_tree(tree_class);
assert.ok(!tree.remove(100));
tree.insert(100);
assert.ok(!tree.remove(101));
assert.ok(tree.remove(100));
}
function minmax(assert, tree_class) {
var tree = loader.new_tree(tree_class);
assert.equal(tree.min(), null);
assert.equal(tree.max(), null);
var inserts = loader.get_inserts(loader.load(SAMPLE_FILE));
tree = loader.build_tree(tree_class, inserts);
assert.equal(tree.min(), _.min(inserts));
assert.equal(tree.max(), _.max(inserts));
}
function forward_it(assert, tree_class) {
var inserts = loader.get_inserts(loader.load(SAMPLE_FILE));
var tree = loader.build_tree(tree_class, inserts);
var items = [];
var it=tree.iterator(), data;
while((data = it.next()) !== null) {
items.push(data);
}
inserts.sort(function(a,b) { return a - b; });
assert.deepEqual(items, inserts);
items = [];
tree.each(function(data) {
items.push(data);
});
assert.deepEqual(items, inserts);
}
function forward_it_break(assert, tree_class) {
var inserts = loader.get_inserts(loader.load(SAMPLE_FILE));
var tree = loader.build_tree(tree_class, inserts);
var items = [];
var it=tree.iterator(), data;
while((data = it.next()) !== null) {
items.push(data);
}
inserts.sort(function(a,b) { return a - b; });
assert.deepEqual(items, inserts);
items = [];
var i = 0;
tree.each(function(data) {
items.push(data);
if (i === 3) {
return false;
}
i++;
});
assert.equal(items.length, 4);
}
function reverse_it(assert, tree_class) {
var inserts = loader.get_inserts(loader.load(SAMPLE_FILE));
var tree = loader.build_tree(tree_class, inserts);
var items = [];
var it=tree.iterator(), data;
while((data = it.prev()) !== null) {
items.push(data);
}
inserts.sort(function(a,b) { return b - a; });
assert.deepEqual(items, inserts);
items = [];
tree.reach(function(data) {
items.push(data);
});
assert.deepEqual(items, inserts);
}
function reverse_it_break(assert, tree_class) {
var inserts = loader.get_inserts(loader.load(SAMPLE_FILE));
var tree = loader.build_tree(tree_class, inserts);
var items = [];
var it=tree.iterator(), data;
while((data = it.prev()) !== null) {
items.push(data);
}
inserts.sort(function(a,b) { return b - a; });
assert.deepEqual(items, inserts);
items = [];
var i = 0;
tree.reach(function(data) {
items.push(data);
if (i === 3) {
return false;
}
i++;
});
assert.equal(items.length, 4);
}
function switch_it(assert, tree_class) {
var inserts = loader.get_inserts(loader.load(SAMPLE_FILE));
var tree = loader.build_tree(tree_class, inserts);
inserts.sort(function(a,b) { return a - b; });
function do_switch(after) {
var items = [];
var it = tree.iterator();
for(var i = 0; i < after; i++) {
items.push(it.next());
}
while((data = it.prev()) !== null) {
items.push(data);
}
var forward = inserts.slice(0, after);
var reverse = inserts.slice(0, after - 1).reverse();
var all = forward.concat(reverse);
assert.deepEqual(items, all);
}
do_switch(1);
do_switch(10);
do_switch(1000);
do_switch(9000);
}
function empty_it(assert, tree_class) {
var tree = loader.new_tree(tree_class);
var it = tree.iterator();
assert.equal(it.next(), null);
it = tree.iterator();
assert.equal(it.prev(), null);
}
function lower_bound(assert, tree_class) {
var inserts = loader.get_inserts(loader.load(SAMPLE_FILE));
var tree = loader.build_tree(tree_class, inserts);
inserts.sort(function(a,b) { return a - b; });
for(var i=1; i<inserts.length-1; ++i) {
var item = inserts[i];
var iter = tree.lowerBound(item);
assert.equal(iter.data(), item);
assert.equal(iter.prev(), inserts[i-1]);
iter.next();
assert.equal(iter.next(), inserts[i+1]);
var prev = tree.lowerBound(item - 0.1);
assert.equal(prev.data(), inserts[i]);
var next = tree.lowerBound(item + 0.1);
assert.equal(next.data(), inserts[i+1]);
}
// test edges
var iter = tree.lowerBound(-1);
assert.equal(iter.data(), inserts[0]);
var last = inserts[inserts.length - 1];
iter = tree.lowerBound(last);
assert.equal(iter.data(), last);
iter = tree.lowerBound(last + 1);
assert.equal(iter.data(), null);
}
function upper_bound(assert, tree_class) {
var inserts = loader.get_inserts(loader.load(SAMPLE_FILE));
var tree = loader.build_tree(tree_class, inserts);
inserts.sort(function(a,b) { return a - b; });
for(var i=0; i<inserts.length-2; ++i) {
var item = inserts[i];
var iter = tree.upperBound(item);
assert.equal(iter.data(), inserts[i+1]);
assert.equal(iter.prev(), inserts[i]);
iter.next();
assert.equal(iter.next(), inserts[i+2]);
var prev = tree.upperBound(item - 0.1);
assert.equal(prev.data(), inserts[i]);
var next = tree.upperBound(item + 0.1);
assert.equal(next.data(), inserts[i+1]);
}
// test edges
var iter = tree.upperBound(-1);
assert.equal(iter.data(), inserts[0]);
var last = inserts[inserts.length - 1];
iter = tree.upperBound(last);
assert.equal(iter.data(), null);
iter = tree.upperBound(last + 1);
assert.equal(iter.data(), null);
// test empty
var empty = new tree_class(function(a,b) { return a.val - b.val });
var iter = empty.upperBound({val:0});
assert.equal(iter.data(), null);
}
function find(assert, tree_class) {
var inserts = loader.get_inserts(loader.load(SAMPLE_FILE));
var tree = loader.build_tree(tree_class, inserts);
for(var i=1; i<inserts.length-1; ++i) {
var item = inserts[i];
assert.equal(tree.find(item), item);
assert.equal(tree.find(item + 0.1), null);
}
}
function find_iter(assert, tree_class) {
var inserts = loader.get_inserts(loader.load(SAMPLE_FILE));
var tree = loader.build_tree(tree_class, inserts);
inserts.sort(function(a,b) { return a - b; });
for(var i=1; i<inserts.length-1; ++i) {
var item = inserts[i];
var iter = tree.findIter(item);
assert.equal(iter.data(), item);
assert.equal(iter.prev(), inserts[i-1]);
iter.next();
assert.equal(iter.next(), inserts[i+1]);
assert.equal(tree.findIter(item + 0.1), null);
}
}
var TESTS = {
clear: clear,
dup: dup,
nonexist: nonexist,
minmax: minmax,
forward_it: forward_it,
forward_it_break: forward_it_break,
reverse_it: reverse_it,
reverse_it_break: reverse_it_break,
switch_it: switch_it,
empty_it: empty_it,
lower_bound: lower_bound,
upper_bound: upper_bound,
find: find,
find_iter: find_iter
};
var test_funcs = {};
TREES.forEach(function(tree) {
var tree_class = require('../lib/' + tree);
for(var test in TESTS) {
(function(test) {
test_funcs[tree + "_" + test] = function(assert) {
TESTS[test](assert, tree_class);
assert.done();
}
})(test);
}
});
exports.api = test_funcs;

117
node_modules/bintrees/test/test_correctness.js generated vendored Normal file
View File

@@ -0,0 +1,117 @@
var fs = require('fs');
var assert = require('assert');
var loader = require('./loader');
var BASE_DIR = __dirname + '/samples';
var TREES = ['rbtree', 'bintree'];
function bt_assert(root, comparator) {
if(root === null) {
return true;
}
else {
var ln = root.left;
var rn = root.right;
// invalid binary search tree
assert.equal((ln !== null && comparator(ln.data, root.data) >= 0) ||
(rn !== null && comparator(rn.data, root.data) <= 0),
false,
"binary tree violation");
return bt_assert(ln, comparator) && bt_assert(rn, comparator);
}
}
function is_red(node) {
return node !== null && node.red;
}
function rb_assert(root, comparator) {
if(root === null) {
return 1;
}
else {
var ln = root.left;
var rn = root.right;
// red violation
if(is_red(root)) {
assert.equal(is_red(ln) || is_red(rn), false, "red violation");
}
var lh = rb_assert(ln, comparator);
var rh = rb_assert(rn, comparator);
// invalid binary search tree
assert.equal((ln !== null && comparator(ln.data, root.data) >= 0) ||
(rn !== null && comparator(rn.data, root.data) <= 0),
false,
"binary tree violation");
// black height mismatch
assert.equal(lh !== 0 && rh !== 0 && lh !== rh, false, "black violation");
// count black links
if(lh !== 0 && rh !== 0) {
return is_red(root) ? lh : lh + 1;
}
else {
return 0;
}
}
}
var assert_func = {
rbtree: rb_assert,
bintree: bt_assert
};
function tree_assert(tree_name) {
return function(tree) {
return assert_func[tree_name](tree._root, tree._comparator) !== 0;
}
}
function run_test(assert, tree_assert, tree_class, test_path) {
var tree = loader.new_tree(tree_class);
var tests = loader.load(test_path);
var elems = 0;
tests.forEach(function(n) {
if(n > 0) {
// insert
assert.ok(tree.insert(n));
assert.equal(tree.find(n), n);
elems++;
}
else {
// remove
n = -n;
assert.ok(tree.remove(n));
assert.equal(tree.find(n), null);
elems--;
}
assert.equal(tree.size, elems);
assert.ok(tree_assert(tree));
});
}
var tests = fs.readdirSync(BASE_DIR);
var test_funcs = {};
TREES.forEach(function(tree) {
var tree_class = require('../lib/' + tree);
tests.forEach(function(test) {
var test_path = BASE_DIR + "/" + test;
test_funcs[tree + "_" + test] = function(assert) {
run_test(assert, tree_assert(tree), tree_class, test_path);
assert.done();
};
});
});
exports.correctness = test_funcs;