addon-sdk/source/lib/sdk/test.js

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 "use strict";
michael@0 6
michael@0 7 module.metadata = {
michael@0 8 "stability": "unstable"
michael@0 9 };
michael@0 10
michael@0 11 const { Cu } = require("chrome");
michael@0 12 const { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
michael@0 13 const { defer } = require("sdk/core/promise");
michael@0 14 const BaseAssert = require("sdk/test/assert").Assert;
michael@0 15 const { isFunction, isObject } = require("sdk/lang/type");
michael@0 16
michael@0 17 exports.Assert = BaseAssert;
michael@0 18
michael@0 19 function extend(target) {
michael@0 20 let descriptor = {}
michael@0 21 Array.slice(arguments, 1).forEach(function(source) {
michael@0 22 Object.getOwnPropertyNames(source).forEach(function onEach(name) {
michael@0 23 descriptor[name] = Object.getOwnPropertyDescriptor(source, name);
michael@0 24 });
michael@0 25 });
michael@0 26 return Object.create(target, descriptor);
michael@0 27 }
michael@0 28
michael@0 29 /**
michael@0 30 * Function takes test `suite` object in CommonJS format and defines all of the
michael@0 31 * tests from that suite and nested suites in a jetpack format on a given
michael@0 32 * `target` object. Optionally third argument `prefix` can be passed to prefix
michael@0 33 * all the test names.
michael@0 34 */
michael@0 35 function defineTestSuite(target, suite, prefix) {
michael@0 36 prefix = prefix || "";
michael@0 37 // If suite defines `Assert` that's what `assert` object have to be created
michael@0 38 // from and passed to a test function (This allows custom assertion functions)
michael@0 39 // See for details: http://wiki.commonjs.org/wiki/Unit_Testing/1.1
michael@0 40 let Assert = suite.Assert || BaseAssert;
michael@0 41 // Going through each item in the test suite and wrapping it into a
michael@0 42 // Jetpack test format.
michael@0 43 Object.keys(suite).forEach(function(key) {
michael@0 44 // If name starts with test then it's a test function or suite.
michael@0 45 if (key.indexOf("test") === 0) {
michael@0 46 let test = suite[key];
michael@0 47
michael@0 48 // For each test function so we create a wrapper test function in a
michael@0 49 // jetpack format and copy that to a `target` exports.
michael@0 50 if (isFunction(test)) {
michael@0 51
michael@0 52 // Since names of the test may match across suites we use full object
michael@0 53 // path as a name to avoid overriding same function.
michael@0 54 target[prefix + key] = function(options) {
michael@0 55
michael@0 56 // Creating `assert` functions for this test.
michael@0 57 let assert = Assert(options);
michael@0 58 assert.end = () => options.done();
michael@0 59
michael@0 60 // If test function is a generator use a task JS to allow yield-ing
michael@0 61 // style test runs.
michael@0 62 if (test.isGenerator && test.isGenerator()) {
michael@0 63 options.waitUntilDone();
michael@0 64 Task.spawn(test.bind(null, assert)).
michael@0 65 then(null, assert.fail).
michael@0 66 then(assert.end);
michael@0 67 }
michael@0 68
michael@0 69 // If CommonJS test function expects more than one argument
michael@0 70 // it means that test is async and second argument is a callback
michael@0 71 // to notify that test is finished.
michael@0 72 else if (1 < test.length) {
michael@0 73
michael@0 74 // Letting test runner know that test is executed async and
michael@0 75 // creating a callback function that CommonJS tests will call
michael@0 76 // once it's done.
michael@0 77 options.waitUntilDone();
michael@0 78 test(assert, function() {
michael@0 79 options.done();
michael@0 80 });
michael@0 81 }
michael@0 82
michael@0 83 // Otherwise CommonJS test is synchronous so we call it only with
michael@0 84 // one argument.
michael@0 85 else {
michael@0 86 test(assert);
michael@0 87 }
michael@0 88 }
michael@0 89 }
michael@0 90
michael@0 91 // If it's an object then it's a test suite containing test function
michael@0 92 // and / or nested test suites. In that case we just extend prefix used
michael@0 93 // and call this function to copy and wrap tests from nested suite.
michael@0 94 else if (isObject(test)) {
michael@0 95 // We need to clone `tests` instead of modifying it, since it's very
michael@0 96 // likely that it is frozen (usually test suites imported modules).
michael@0 97 test = extend(Object.prototype, test, {
michael@0 98 Assert: test.Assert || Assert
michael@0 99 });
michael@0 100 defineTestSuite(target, test, prefix + key + ".");
michael@0 101 }
michael@0 102 }
michael@0 103 });
michael@0 104 }
michael@0 105
michael@0 106 /**
michael@0 107 * This function is a CommonJS test runner function, but since Jetpack test
michael@0 108 * runner and test format is different from CommonJS this function shims given
michael@0 109 * `exports` with all its tests into a Jetpack test format so that the built-in
michael@0 110 * test runner will be able to run CommonJS test without manual changes.
michael@0 111 */
michael@0 112 exports.run = function run(exports) {
michael@0 113
michael@0 114 // We can't leave old properties on exports since those are test in a CommonJS
michael@0 115 // format that why we move everything to a new `suite` object.
michael@0 116 let suite = {};
michael@0 117 Object.keys(exports).forEach(function(key) {
michael@0 118 suite[key] = exports[key];
michael@0 119 delete exports[key];
michael@0 120 });
michael@0 121
michael@0 122 // Now we wrap all the CommonJS tests to a Jetpack format and define
michael@0 123 // those to a given `exports` object since that where jetpack test runner
michael@0 124 // will look for them.
michael@0 125 defineTestSuite(exports, suite);
michael@0 126 };

mercurial