tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_params.js (14167B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 function TestParams() {
      6 }
      7 
      8 /* For once I'm happy that JS is weakly typed. */
      9 function f(a, b) {
     10    var rv = b.value;
     11    b.value = a;
     12    return rv;
     13 };
     14 
     15 /* Implementation for size_is and iid_is methods. */
     16 function f_is(aIs, a, bIs, b, rvIs) {
     17 
     18    // Set up the return value and its 'is' parameter.
     19    var rv = b.value;
     20    rvIs.value = bIs.value;
     21 
     22    // Set up b and its 'is' parameter.
     23    b.value = a;
     24    bIs.value = aIs;
     25 
     26    return rv;
     27 }
     28 
     29 function f_size_and_iid(aSize, aIID, a, bSize, bIID, b, rvSize, rvIID) {
     30 
     31    // Copy the iids.
     32    rvIID.value = bIID.value;
     33    bIID.value = aIID;
     34 
     35    // Now that we've reduced the problem to one dependent variable, use f_is.
     36    return f_is(aSize, a, bSize, b, rvSize);
     37 }
     38 
     39 TestParams.prototype = {
     40  QueryInterface: ChromeUtils.generateQI(["nsIXPCTestParams"]),
     41 
     42  /* nsIXPCTestParams */
     43  testBoolean: f,
     44  testOctet: f,
     45  testShort: f,
     46  testLong: f,
     47  testLongLong: f,
     48  testUnsignedShort: f,
     49  testUnsignedLong: f,
     50  testUnsignedLongLong: f,
     51  testFloat: f,
     52  testDouble: f,
     53  testChar: f,
     54  testString: f,
     55  testWchar: f,
     56  testWstring: f,
     57  testAString: f,
     58  testAUTF8String: f,
     59  testACString: f,
     60  testJsval: f,
     61  testShortSequence: f,
     62  testDoubleSequence: f,
     63  testAStringSequence: f,
     64  testACStringSequence: f,
     65  testInterfaceSequence: f,
     66  testJsvalSequence: f,
     67  testInterfaceIsSequence: f_is,
     68  testOptionalSequence: function (arr) { return arr; },
     69  testShortArray: f_is,
     70  testDoubleArray: f_is,
     71  testStringArray: f_is,
     72  testByteArrayOptionalLength(arr) { return arr.length; },
     73  testWstringArray: f_is,
     74  testInterfaceArray: f_is,
     75  testJsvalArray: f_is,
     76  testSizedString: f_is,
     77  testSizedWstring: f_is,
     78  testInterfaceIs: f_is,
     79  testInterfaceIsArray: f_size_and_iid,
     80  testOutAString: function(o) { o.value = "out"; },
     81  testStringArrayOptionalSize: function(arr, size) {
     82    if (arr.length != size) { throw "bad size passed to test method"; }
     83    var rv = "";
     84    arr.forEach((x) => rv += x);
     85    return rv;
     86  },
     87  testOmittedOptionalOut(jsObj, o) {
     88    if (typeof o != "object" || o.value !== undefined) {
     89      throw new Components.Exception(
     90        "unexpected value",
     91        Cr.NS_ERROR_ILLEGAL_VALUE
     92      );
     93    }
     94    o.value = Cc["@mozilla.org/network/io-service;1"]
     95      .getService(Ci.nsIIOService)
     96      .newURI("http://example.com/");
     97  },
     98  testNaN: NaN,
     99 };
    100 
    101 function TestInterfaceA() {}
    102 TestInterfaceA.prototype = {
    103  QueryInterface: ChromeUtils.generateQI(["nsIXPCTestInterfaceA"]),
    104 
    105  /* nsIXPCTestInterfaceA */
    106  name: "TestInterfaceADefaultName"
    107 };
    108 
    109 function TestInterfaceB() {}
    110 TestInterfaceB.prototype = {
    111  QueryInterface: ChromeUtils.generateQI(["nsIXPCTestInterfaceB"]),
    112 
    113  /* nsIXPCTestInterfaceA */
    114  name: "TestInterfaceADefaultName"
    115 };
    116 
    117 function run_test() {
    118 
    119  // Load the component manifests.
    120  registerXPCTestComponents();
    121 
    122  // Test for each component.
    123  test_component(Cc["@mozilla.org/js/xpc/test/native/Params;1"].createInstance());
    124  test_component(xpcWrap(new TestParams()));
    125 }
    126 
    127 function test_component(obj) {
    128  var o = obj.QueryInterface(Ci.nsIXPCTestParams);
    129 
    130  // Possible comparator functions.
    131  var standardComparator = function(a,b) {return a == b;};
    132  var dotEqualsComparator = function(a,b) {return a.equals(b); }
    133  var fuzzComparator = function(a,b) {return Math.abs(a - b) < 0.1;};
    134  var interfaceComparator = function(a,b) {return a.name == b.name; }
    135  var arrayComparator = function(innerComparator) {
    136    return function(a,b) {
    137      if (a.length != b.length)
    138        return false;
    139      for (var i = 0; i < a.length; ++i)
    140        if (!innerComparator(a[i], b[i]))
    141          return false;
    142      return true;
    143    };
    144  };
    145 
    146  // Helper test function - takes the name of test method and two values of
    147  // the given type.
    148  //
    149  // The optional comparator argument can be used for alternative notions of
    150  // equality. The comparator should return true on equality.
    151  function doTest(name, val1, val2, comparator) {
    152    if (!comparator)
    153      comparator = standardComparator;
    154    var a = val1;
    155    var b = {value: val2};
    156    var rv = o[name].call(o, a, b);
    157    Assert.ok(comparator(rv, val2));
    158    Assert.ok(comparator(val1, b.value));
    159  };
    160 
    161  function doIsTest(name, val1, val1Is, val2, val2Is, valComparator, isComparator) {
    162    if (!isComparator)
    163      isComparator = standardComparator;
    164    var a = val1;
    165    var aIs = val1Is;
    166    var b = {value: val2};
    167    var bIs = {value: val2Is};
    168    var rvIs = {};
    169    var rv = o[name].call(o, aIs, a, bIs, b, rvIs);
    170    Assert.ok(valComparator(rv, val2));
    171    Assert.ok(isComparator(rvIs.value, val2Is));
    172    Assert.ok(valComparator(val1, b.value));
    173    Assert.ok(isComparator(val1Is, bIs.value));
    174  }
    175 
    176  // Special-purpose function for testing arrays of iid_is interfaces, where we
    177  // have 2 distinct sets of dependent parameters.
    178  function doIs2Test(name, val1, val1Size, val1IID, val2, val2Size, val2IID) {
    179    var a = val1;
    180    var aSize = val1Size;
    181    var aIID = val1IID;
    182    var b = {value: val2};
    183    var bSize = {value: val2Size};
    184    var bIID = {value: val2IID};
    185    var rvSize = {};
    186    var rvIID = {};
    187    var rv = o[name].call(o, aSize, aIID, a, bSize, bIID, b, rvSize, rvIID);
    188    Assert.ok(arrayComparator(interfaceComparator)(rv, val2));
    189    Assert.ok(standardComparator(rvSize.value, val2Size));
    190    Assert.ok(dotEqualsComparator(rvIID.value, val2IID));
    191    Assert.ok(arrayComparator(interfaceComparator)(val1, b.value));
    192    Assert.ok(standardComparator(val1Size, bSize.value));
    193    Assert.ok(dotEqualsComparator(val1IID, bIID.value));
    194  }
    195 
    196  // Check that the given call (type mismatch) results in an exception being thrown.
    197  function doTypedArrayMismatchTest(name, val1, val1Size, val2, val2Size) {
    198    var comparator = arrayComparator(standardComparator);
    199    var error = false;
    200    try {
    201      doIsTest(name, val1, val1Size, val2, val2Size, comparator);
    202      
    203      // An exception was not thrown as would have been expected.
    204      Assert.ok(false);
    205    }
    206    catch (e) {
    207      // An exception was thrown as expected.
    208      Assert.ok(true);
    209    }
    210  }
    211 
    212  // Workaround for bug 687612 (inout parameters broken for dipper types).
    213  // We do a simple test of copying a into b, and ignore the rv.
    214  function doTestWorkaround(name, val1) {
    215    var a = val1;
    216    var b = {value: ""};
    217    o[name].call(o, a, b);
    218    Assert.equal(val1, b.value);
    219  }
    220 
    221  // Test all the different types
    222  doTest("testBoolean", true, false);
    223  doTest("testOctet", 4, 156);
    224  doTest("testShort", -456, 1299);
    225  doTest("testLong", 50060, -12121212);
    226  doTest("testLongLong", 12345, -10000000000);
    227  doTest("testUnsignedShort", 1532, 65000);
    228  doTest("testUnsignedLong", 0, 4000000000);
    229  doTest("testUnsignedLongLong", 215435, 3453492580348535809);
    230  doTest("testFloat", 4.9, -11.2, fuzzComparator);
    231  doTest("testDouble", -80.5, 15000.2, fuzzComparator);
    232  doTest("testChar", "a", "2");
    233  doTest("testString", "someString", "another string");
    234  doTest("testWstring", "Why wasnt this", "turned on before? ಠ_ಠ");
    235  doTest("testWchar", "z", "ア");
    236  doTestWorkaround("testAString", "Frosty the ☃ ;-)");
    237  doTestWorkaround("testAUTF8String", "We deliver 〠!");
    238  doTestWorkaround("testACString", "Just a regular C string.");
    239  doTest("testJsval", {aprop: 12, bprop: "str"}, 4.22);
    240 
    241  // Test out dipper parameters, since they're special and we can't really test
    242  // inouts.
    243  let outAString = {};
    244  o.testOutAString(outAString);
    245  Assert.equal(outAString.value, "out");
    246  try { o.testOutAString(undefined); } catch (e) {} // Don't crash
    247  try { o.testOutAString(null); } catch (e) {} // Don't crash
    248  try { o.testOutAString("string"); } catch (e) {} // Don't crash
    249 
    250  // Helpers to instantiate various test XPCOM objects.
    251  var numAsMade = 0;
    252  function makeA() {
    253    var a = xpcWrap(new TestInterfaceA(), Ci.nsIXPCTestInterfaceA);
    254    a.name = 'testA' + numAsMade++;
    255    return a;
    256  };
    257  var numBsMade = 0;
    258  function makeB() {
    259    var b = xpcWrap(new TestInterfaceB(), Ci.nsIXPCTestInterfaceB);
    260    b.name = 'testB' + numBsMade++;
    261    return b;
    262  };
    263 
    264  // Test arrays.
    265  doIsTest("testShortArray", [2, 4, 6], 3, [1, 3, 5, 7], 4, arrayComparator(standardComparator));
    266  doIsTest("testDoubleArray", [-10, -0.5], 2, [1, 3, 1e11, -8e-5 ], 4, arrayComparator(fuzzComparator));
    267 
    268  doIsTest("testStringArray", ["mary", "hat", "hey", "lid", "tell", "lam"], 6,
    269                              ["ids", "fleas", "woes", "wide", "has", "know", "!"], 7, arrayComparator(standardComparator));
    270  doIsTest("testWstringArray", ["沒有語言", "的偉大嗎?]"], 2,
    271                               ["we", "are", "being", "sooo", "international", "right", "now"], 7, arrayComparator(standardComparator));
    272  doIsTest("testInterfaceArray", [makeA(), makeA()], 2,
    273                                 [makeA(), makeA(), makeA(), makeA(), makeA(), makeA()], 6, arrayComparator(interfaceComparator));
    274  doIsTest("testJsvalArray", [{ cheese: 'whiz', apple: 8 }, [1, 5, '3'], /regex/], 3,
    275                             ['apple', 2.2e10, 3.3e30, { only: "wheedle", except: {} }], 4, arrayComparator(standardComparator));
    276 
    277  // Test typed arrays and ArrayBuffer aliasing.
    278  var arrayBuffer = new ArrayBuffer(16);
    279  var int16Array = new Int16Array(arrayBuffer, 2, 3);
    280  int16Array.set([-32768, 0, 32767]);
    281  doIsTest("testShortArray", int16Array, 3, new Int16Array([1773, -32768, 32767, 7]), 4, arrayComparator(standardComparator));
    282  doIsTest("testDoubleArray", new Float64Array([-10, -0.5]), 2, new Float64Array([0, 3.2, 1.0e10, -8.33 ]), 4, arrayComparator(fuzzComparator));
    283 
    284  // Test sized strings.
    285  var ssTests = ["Tis not possible, I muttered", "give me back my free hardcore!", "quoth the server:", "4〠4"];
    286  doIsTest("testSizedString", ssTests[0], ssTests[0].length, ssTests[1], ssTests[1].length, standardComparator);
    287  doIsTest("testSizedWstring", ssTests[2], ssTests[2].length, ssTests[3], ssTests[3].length, standardComparator);
    288 
    289  // Test iid_is.
    290  doIsTest("testInterfaceIs", makeA(), Ci['nsIXPCTestInterfaceA'],
    291                              makeB(), Ci['nsIXPCTestInterfaceB'],
    292                              interfaceComparator, dotEqualsComparator);
    293 
    294  // Test arrays of iids.
    295  doIs2Test("testInterfaceIsArray", [makeA(), makeA(), makeA(), makeA(), makeA()], 5, Ci['nsIXPCTestInterfaceA'],
    296                                    [makeB(), makeB(), makeB()], 3, Ci['nsIXPCTestInterfaceB']);
    297 
    298  // Test optional array size.
    299  Assert.equal(o.testStringArrayOptionalSize(["some", "string", "array"]), "somestringarray");
    300 
    301  // Test incorrect (too big) array size parameter; this should throw NOT_ENOUGH_ELEMENTS.
    302  doTypedArrayMismatchTest("testShortArray", new Int16Array([-3, 7, 4]), 4,
    303                                             new Int16Array([1, -32, 6]), 3);
    304 
    305  // Test type mismatch (int16 <-> uint16); this should throw BAD_CONVERT_JS.
    306  doTypedArrayMismatchTest("testShortArray", new Uint16Array([0, 7, 4, 3]), 4,
    307                                             new Uint16Array([1, 5, 6]), 3);
    308 
    309  // Test Sequence<T> types.
    310  doTest("testShortSequence", [2, 4, 6], [1, 3, 5, 7], arrayComparator(standardComparator));
    311  doTest("testDoubleSequence", [-10, -0.5], [1, 3, 1e11, -8e-5 ], arrayComparator(fuzzComparator));
    312  doTest("testACStringSequence", ["mary", "hat", "hey", "lid", "tell", "lam"],
    313                                 ["ids", "fleas", "woes", "wide", "has", "know", "!"],
    314                                 arrayComparator(standardComparator));
    315  doTest("testAStringSequence", ["沒有語言", "的偉大嗎?]"],
    316                                ["we", "are", "being", "sooo", "international", "right", "now"],
    317                                arrayComparator(standardComparator));
    318 
    319  doTest("testInterfaceSequence", [makeA(), makeA()],
    320                                  [makeA(), makeA(), makeA(), makeA(), makeA(), makeA()], arrayComparator(interfaceComparator));
    321 
    322  doTest("testJsvalSequence", [{ cheese: 'whiz', apple: 8 }, [1, 5, '3'], /regex/],
    323                              ['apple', 2.2e10, 3.3e30, { only: "wheedle", except: {} }], arrayComparator(standardComparator));
    324 
    325  doIsTest("testInterfaceIsSequence", [makeA(), makeA(), makeA(), makeA(), makeA()], Ci['nsIXPCTestInterfaceA'],
    326                                      [makeB(), makeB(), makeB()], Ci['nsIXPCTestInterfaceB'],
    327                                      arrayComparator(interfaceComparator), dotEqualsComparator);
    328 
    329  var ret = o.testOptionalSequence();
    330  Assert.ok(Array.isArray(ret));
    331  Assert.equal(ret.length, 0);
    332 
    333  ret = o.testOptionalSequence([]);
    334  Assert.ok(Array.isArray(ret));
    335  Assert.equal(ret.length, 0);
    336 
    337  ret = o.testOptionalSequence([1, 2, 3]);
    338  Assert.ok(Array.isArray(ret));
    339  Assert.equal(ret.length, 3);
    340 
    341  let jsObj = new TestParams();
    342  o.testOmittedOptionalOut(jsObj);
    343  ret = {};
    344  o.testOmittedOptionalOut(jsObj, ret);
    345  Assert.equal(ret.value.spec, "http://example.com/")
    346 
    347  // Tests for large ArrayBuffers.
    348  var ab = null;
    349  try {
    350    ab = new ArrayBuffer(4.5 * 1024 * 1024 * 1024); // 4.5 GB.
    351  } catch (e) {
    352    // Large ArrayBuffers not available (32-bit or disabled).
    353  }
    354  if (ab) {
    355    var uint8 = new Uint8Array(ab);
    356 
    357    // Test length check in JSArray2Native.
    358    var ex = null;
    359    try {
    360      o.testOptionalSequence(uint8);
    361    } catch (e) {
    362      ex = e;
    363    }
    364    Assert.ok(ex.message.includes("Could not convert JavaScript argument arg 0"));
    365 
    366    // Test length check for optional length argument in GetArraySizeFromParam.
    367    ex = null;
    368    try {
    369      o.testByteArrayOptionalLength(uint8);
    370    } catch (e) {
    371      ex = e;
    372    }
    373    Assert.ok(ex.message.includes("Cannot convert JavaScript object into an array"));
    374 
    375    // Smaller array views on the buffer are fine.
    376    uint8 = new Uint8Array(ab, ab.byteLength - 3);
    377    uint8[0] = 123;
    378    Assert.equal(uint8.byteLength, 3);
    379    Assert.equal(o.testOptionalSequence(uint8).toString(), "123,0,0");
    380    Assert.equal(o.testByteArrayOptionalLength(uint8), 3);
    381  }
    382 
    383  Assert.ok(isNaN(o.testNaN), "Should handle returning NaNs");
    384 }