michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: http://creativecommons.org/publicdomain/zero/1.0/ */ michael@0: michael@0: /** michael@0: * Tests that values are correctly serialized and sent in enteredFrame michael@0: * and exitedFrame packets. michael@0: */ michael@0: michael@0: var gDebuggee; michael@0: var gClient; michael@0: var gTraceClient; michael@0: michael@0: function run_test() michael@0: { michael@0: initTestTracerServer(); michael@0: gDebuggee = addTestGlobal("test-tracer-actor"); michael@0: gClient = new DebuggerClient(DebuggerServer.connectPipe()); michael@0: gClient.connect(function() { michael@0: attachTestTab(gClient, "test-tracer-actor", function(aResponse, aTabClient) { michael@0: gClient.attachTracer(aResponse.traceActor, function(aResponse, aTraceClient) { michael@0: gTraceClient = aTraceClient; michael@0: test_enter_exit_frame(); michael@0: }); michael@0: }); michael@0: }); michael@0: do_test_pending(); michael@0: } michael@0: michael@0: function test_enter_exit_frame() michael@0: { michael@0: const traceStopped = promise.defer(); michael@0: michael@0: gClient.addListener("traces", (aEvent, { traces }) => { michael@0: for (let t of traces) { michael@0: check_trace(t); michael@0: if (t.sequence === 27) { michael@0: traceStopped.resolve(); michael@0: } michael@0: } michael@0: }); michael@0: michael@0: start_trace() michael@0: .then(eval_code) michael@0: .then(() => traceStopped.promise) michael@0: .then(stop_trace) michael@0: .then(function() { michael@0: finishClient(gClient); michael@0: }); michael@0: } michael@0: michael@0: function start_trace() michael@0: { michael@0: let deferred = promise.defer(); michael@0: gTraceClient.startTrace(["arguments", "return"], null, function() { deferred.resolve(); }); michael@0: return deferred.promise; michael@0: } michael@0: michael@0: function eval_code() michael@0: { michael@0: gDebuggee.eval("(" + function() { michael@0: function identity(x) { michael@0: return x; michael@0: } michael@0: michael@0: let circular = {}; michael@0: circular.self = circular; michael@0: michael@0: // Make sure there is only 3 properties per object because that is the value michael@0: // of MAX_PROPERTIES in the server. michael@0: let obj = { michael@0: num: 0, michael@0: str: "foo", michael@0: bool: false, michael@0: }; michael@0: let obj2 = { michael@0: undef: undefined, michael@0: nil: null, michael@0: inf: Infinity michael@0: }; michael@0: let obj3 = { michael@0: ninf: -Infinity, michael@0: nan: NaN, michael@0: nzero: -0 michael@0: }; michael@0: let obj4 = { michael@0: obj: circular, michael@0: arr: [1,2,3,4,5] michael@0: }; michael@0: michael@0: identity(); michael@0: identity(0); michael@0: identity(""); michael@0: identity(false); michael@0: identity(undefined); michael@0: identity(null); michael@0: identity(Infinity); michael@0: identity(-Infinity); michael@0: identity(NaN); michael@0: identity(-0); michael@0: identity(obj); michael@0: identity(obj2); michael@0: identity(obj3); michael@0: identity(obj4); michael@0: } + ")()"); michael@0: } michael@0: michael@0: function stop_trace() michael@0: { michael@0: let deferred = promise.defer(); michael@0: gTraceClient.stopTrace(null, function() { deferred.resolve(); }); michael@0: return deferred.promise; michael@0: } michael@0: michael@0: function check_trace(aTrace) michael@0: { michael@0: let value = (aTrace.type === "enteredFrame" && aTrace.arguments) michael@0: ? aTrace.arguments[0] michael@0: : aTrace.return; michael@0: switch(aTrace.sequence) { michael@0: case 2: michael@0: do_check_eq(typeof aTrace.arguments, "object"); michael@0: do_check_eq(aTrace.arguments.length, 0); michael@0: break; michael@0: case 3: michael@0: check_value(value, "object", "undefined"); michael@0: break; michael@0: case 4: michael@0: case 5: michael@0: check_value(value, "number", 0); michael@0: break; michael@0: case 6: michael@0: case 7: michael@0: check_value(value, "string", ""); michael@0: break; michael@0: case 8: michael@0: case 9: michael@0: check_value(value, "boolean", false); michael@0: break; michael@0: case 10: michael@0: case 11: michael@0: check_value(value, "object", "undefined"); michael@0: break; michael@0: case 12: michael@0: case 13: michael@0: check_value(value, "object", "null"); michael@0: break; michael@0: case 14: michael@0: case 15: michael@0: check_value(value, "object", "Infinity"); michael@0: break; michael@0: case 16: michael@0: case 17: michael@0: check_value(value, "object", "-Infinity"); michael@0: break; michael@0: case 18: michael@0: case 19: michael@0: check_value(value, "object", "NaN"); michael@0: break; michael@0: case 20: michael@0: case 21: michael@0: check_value(value, "object", "-0"); michael@0: break; michael@0: case 22: michael@0: case 23: michael@0: check_obj(aTrace.type, value); michael@0: break; michael@0: case 24: michael@0: case 25: michael@0: check_obj2(aTrace.type, value); michael@0: break; michael@0: case 26: michael@0: case 27: michael@0: check_obj3(aTrace.type, value); michael@0: break; michael@0: case 28: michael@0: case 29: michael@0: check_obj4(aTrace.type, value); michael@0: break; michael@0: } michael@0: } michael@0: michael@0: function check_value(aActual, aExpectedType, aExpectedValue) michael@0: { michael@0: do_check_eq(typeof aActual, aExpectedType); michael@0: do_check_eq(aExpectedType === "object" ? aActual.type : aActual, aExpectedValue); michael@0: } michael@0: michael@0: function check_obj(aType, aObj) { michael@0: do_check_eq(typeof aObj, "object"); michael@0: do_check_eq(typeof aObj.ownProperties, "object"); michael@0: michael@0: do_check_eq(typeof aObj.ownProperties.num, "object"); michael@0: do_check_eq(aObj.ownProperties.num.value, 0); michael@0: michael@0: do_check_eq(typeof aObj.ownProperties.str, "object"); michael@0: do_check_eq(aObj.ownProperties.str.value, "foo"); michael@0: michael@0: do_check_eq(typeof aObj.ownProperties.bool, "object"); michael@0: do_check_eq(aObj.ownProperties.bool.value, false); michael@0: } michael@0: michael@0: function check_obj2(aType, aObj) { michael@0: do_check_eq(typeof aObj.ownProperties.undef, "object"); michael@0: do_check_eq(typeof aObj.ownProperties.undef.value, "object"); michael@0: do_check_eq(aObj.ownProperties.undef.value.type, "undefined"); michael@0: michael@0: do_check_eq(typeof aObj.ownProperties.nil, "object"); michael@0: do_check_eq(typeof aObj.ownProperties.nil.value, "object"); michael@0: do_check_eq(aObj.ownProperties.nil.value.type, "null"); michael@0: michael@0: do_check_eq(typeof aObj.ownProperties.inf, "object"); michael@0: do_check_eq(typeof aObj.ownProperties.inf.value, "object"); michael@0: do_check_eq(aObj.ownProperties.inf.value.type, "Infinity"); michael@0: } michael@0: michael@0: function check_obj3(aType, aObj) { michael@0: do_check_eq(typeof aObj.ownProperties.ninf, "object"); michael@0: do_check_eq(typeof aObj.ownProperties.ninf.value, "object"); michael@0: do_check_eq(aObj.ownProperties.ninf.value.type, "-Infinity"); michael@0: michael@0: do_check_eq(typeof aObj.ownProperties.nan, "object"); michael@0: do_check_eq(typeof aObj.ownProperties.nan.value, "object"); michael@0: do_check_eq(aObj.ownProperties.nan.value.type, "NaN"); michael@0: michael@0: do_check_eq(typeof aObj.ownProperties.nzero, "object"); michael@0: do_check_eq(typeof aObj.ownProperties.nzero.value, "object"); michael@0: do_check_eq(aObj.ownProperties.nzero.value.type, "-0"); michael@0: } michael@0: michael@0: function check_obj4(aType, aObj) { michael@0: // Sub-objects aren't added. michael@0: do_check_eq(typeof aObj.ownProperties.obj, "undefined"); michael@0: do_check_eq(typeof aObj.ownProperties.arr, "undefined"); michael@0: }