gecko-dev/js/ipc/tests/unit/test_cpow.js

278 строки
7.5 KiB
JavaScript
Исходник Обычный вид История

2010-01-22 05:25:21 +03:00
function run_test() {
run_test_in_child("cpow_child.js", run_actual_tests);
}
function run_actual_tests() {
var obj = getChildGlobalObject();
test_properties(obj.data);
test_delete(obj.data);
test_toString(obj.data);
test_inheritance(obj.data.derived);
test_constructor(obj.data.constructor,
obj.Function,
obj.Object,
obj.Date);
test_instanceof(obj.A, obj.B);
test_enumeration(obj.A, obj.B);
test_Array(obj.Array);
test_Function(obj.Function);
test_exceptions(obj.pitch, obj.Object);
test_generators(obj.Function);
test_Iterator(obj.data, obj.Iterator, obj.StopIteration);
test_getters_setters(obj.get_set, obj.Function);
test_forbidden_things(obj);
do_test_finished();
}
function test_properties(data) {
do_check_true("answer" in data);
do_check_false("cnefhasefho" in data.nested);
do_check_eq(data.answer, 42);
do_check_eq(data.nested.objects.work,
"yes they do");
do_check_eq(data.asodfijasdiofj, void(0));
do_check_eq(data.arr.length, 4);
do_check_eq(data.arr[4], void(0));
do_check_eq(data.arr[0], "zeroeth");
do_check_eq(data.arr[1].foo, "bar");
do_check_true(2 in data.arr);
do_check_eq(data.arr[2], data.arr[2]); // ensure reuse
do_check_true(data.arr[2]() === data);
do_check_eq(data.arr[2]().arr[0], "zeroeth");
do_check_true("call" in data.arr[2]);
do_check_eq(data.arr[3], "last");
}
function test_delete(data) {
do_check_eq(data.derived.try_to_delete, "just try");
do_check_true(delete data.derived.try_to_delete);
do_check_eq(data.derived.try_to_delete, "bwahaha");
do_check_true(delete data.derived.try_to_delete);
do_check_eq(data.derived.try_to_delete, "bwahaha");
}
function test_toString(data) {
do_check_eq(data.toString(), "CPOW");
do_check_eq(data + "asdf", "CPOWasdf");
do_check_eq(new String(data), "CPOW");
}
function test_inheritance(derived) {
do_check_true("inherited" in derived);
do_check_false(derived.hasOwnProperty("inherited"));
var base = derived.__proto__;
do_check_true(base.hasOwnProperty("inherited"));
do_check_eq(derived.inherited, "inherited");
do_check_eq(derived.method(), "called");
do_check_eq(base.method, derived.method);
do_check_true(base.method === derived.method);
}
function test_constructor(ctor,
ChildFunction,
ChildObject,
ChildDate) {
var obj = new ctor(42);
obj.check(obj);
// Re-run test_inheritance, creating locally everything that
// test_inheritance expects to be created in the child process:
var empty = new ChildFunction(),
proto = new ChildObject();
proto.inherited = "inherited";
proto.method = new ChildFunction("return 'called'");
empty.prototype = proto;
test_inheritance(new empty);
var cd = new ChildDate,
tolerance_ms = 20000; // Ridiculously large to accommodate gcZeal delays.
do_check_eq(Math.max(Math.abs(cd.getTime() - new Date),
tolerance_ms),
tolerance_ms);
do_check_true(cd instanceof ChildDate);
}
function test_enumeration(A, B) {
function check(obj, nk, s) {
var keys = [];
for (var k in obj)
keys[keys.length] = k;
do_check_eq(keys.length, nk);
do_check_eq(keys.sort().join("~"), s);
}
check(new B, 3, "a~b~c");
check(B.prototype, 2, "a~b");
B.prototype = A.prototype;
A.prototype = new B;
check(new A, 3, "a~b~c");
check(new B, 2, "b~c");
// Put things back the way they were, mostly:
A.prototype = B.prototype;
B.prototype = new A;
}
function test_instanceof(A, B) {
var a = new A, b = new B;
do_check_true(a instanceof A);
do_check_false(a instanceof B);
do_check_true(b instanceof A);
do_check_true(b instanceof B);
}
function test_Array(ChildArray) {
do_check_true(!!ChildArray);
var arr = new ChildArray(1, new ChildArray(2, 3), 4);
do_check_eq(arr.length, 3);
do_check_eq(arr.slice(1).shift()[1], 3);
arr[2] = arr[1];
do_check_eq(arr.pop()[0], 2);
}
function test_Function(ChildFunction) {
var succ = new ChildFunction("x", "return x + 1");
do_check_eq(succ(succ(3)), 5);
do_check_eq(succ + "", "" + new Function("x", "return x + 1"));
}
function test_exceptions(pitch, ChildObject) {
try {
throw "parent-only";
} catch (x) {
do_check_eq(x, "parent-only");
}
var ball = new ChildObject(),
thrown = false;
ball.sport = "baseball";
try {
pitch(ball);
do_throw("Should have thrown.");
} catch (x) {
thrown = true;
do_check_eq(x.sport, "baseball");
do_check_eq(x, ball);
do_check_true(x === ball);
}
do_check_true(thrown);
}
function test_generators(ChildFunction) {
// Run the test with own Function just to keep sane:
if (ChildFunction != Function)
test_generators(Function);
var count = 0, sum = 0,
genFn = new ChildFunction("for(var i = 1; i < 4; i++) yield i");
var gen = genFn();
do try { sum += gen.next(); }
catch (x) { break; }
while ((count += 1));
do_check_eq(count, 3);
do_check_eq(sum, 6);
try {
for (var n in genFn()) {
count += 1;
sum += n;
}
} catch (x) {}
do_check_eq(count, 6);
do_check_eq(sum, 12);
}
function test_Iterator(data, ChildIterator, ChildStopIteration) {
do_check_true(data && ChildIterator && true);
var copy = {},
thrown = null;
try {
for (var kv in ChildIterator(data)) {
do_check_true(kv[0] in data);
do_check_eq(data[kv[0]], kv[1]);
copy[kv[0]] = kv[1];
}
// XXX I shouldn't have to be catching this, should I?
} catch (x) { thrown = x; }
do_check_true(thrown != null);
do_check_true(thrown instanceof ChildStopIteration);
do_check_eq(copy + "", "CPOW");
}
function test_getters_setters(get_set, ChildFunction) {
do_check_eq(get_set.foo, 42);
var thrown = null;
try { get_set.bar = get_set.foo_throws; }
catch (x) { thrown = x; }
do_check_true(thrown != null);
do_check_eq(thrown, "BAM");
do_check_false("bar" in get_set);
get_set.two = 2222;
get_set.one = 1;
do_check_eq(get_set.two, 2);
var getter = new ChildFunction("return 'you got me'");
get_set.__defineGetter__("defined_getter", getter);
do_check_eq(get_set.defined_getter, "you got me");
do_check_eq(get_set.__lookupGetter__("defined_getter"),
getter);
var setter = new ChildFunction("val", "this.side_effect = val");
get_set.__defineSetter__("defined_setter", setter);
get_set.side_effect = "can't touch this";
get_set.defined_setter = "you set me";
do_check_eq(get_set.side_effect, "you set me");
do_check_eq(get_set.__lookupSetter__("defined_setter"),
setter);
}
function test_forbidden_things(child) {
var x_count = 0;
do_check_eq(child.type(42), "number");
try {
child.type(function(){});
do_throw("Should not have been able to pass a parent-created " +
"function to the child");
} catch (x) {
print(x);
x_count += 1;
}
try {
child.type({});
do_throw("Should not have been able to pass a parent-created " +
"object to the child");
} catch (x) {
print(x);
x_count += 1;
}
try {
child.type.prop = {};
do_throw("Should not have been able to set a property of a child " +
"object to a parent-created object value");
} catch (x) {
print(x);
x_count += 1;
}
try {
child.type.prop = function(){};
do_throw("Should not have been able to set a property of a child " +
"object to a parent-created function value");
} catch (x) {
print(x);
x_count += 1;
}
do_check_eq(x_count, 4);
}