зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1493104 - Add unit test for AddonAwareADBScanner;r=ladybenko,daisuke
--HG-- extra : rebase_source : b508f59719bea9fc9b827155f8b872052fa69469
This commit is contained in:
Родитель
f1a644359d
Коммит
b05e78acd6
|
@ -22,14 +22,25 @@ loader.lazyRequireGetter(this, "ADBScanner", "devtools/shared/adb/adb-scanner",
|
||||||
* - event "runtime-list-updated"
|
* - event "runtime-list-updated"
|
||||||
*/
|
*/
|
||||||
class AddonAwareADBScanner extends EventEmitter {
|
class AddonAwareADBScanner extends EventEmitter {
|
||||||
constructor() {
|
/**
|
||||||
|
* Parameters are provided only to allow tests to replace actual implementations with
|
||||||
|
* mocks.
|
||||||
|
*
|
||||||
|
* @param {ADBScanner} scanner
|
||||||
|
* Only provided in tests for mocks
|
||||||
|
* @param {ADBAddon} addon
|
||||||
|
* Only provided in tests for mocks
|
||||||
|
*/
|
||||||
|
constructor(scanner = new ADBScanner(), addon = adbAddon) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this._onScannerListUpdated = this._onScannerListUpdated.bind(this);
|
this._onScannerListUpdated = this._onScannerListUpdated.bind(this);
|
||||||
this._onAddonUpdate = this._onAddonUpdate.bind(this);
|
this._onAddonUpdate = this._onAddonUpdate.bind(this);
|
||||||
|
|
||||||
this._scanner = new ADBScanner();
|
this._scanner = scanner;
|
||||||
this._scanner.on("runtime-list-updated", this._onScannerListUpdated);
|
this._scanner.on("runtime-list-updated", this._onScannerListUpdated);
|
||||||
|
|
||||||
|
this._addon = addon;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,21 +48,21 @@ class AddonAwareADBScanner extends EventEmitter {
|
||||||
* only works if the addon is installed.
|
* only works if the addon is installed.
|
||||||
*/
|
*/
|
||||||
enable() {
|
enable() {
|
||||||
if (adbAddon.status === "installed") {
|
if (this._addon.status === "installed") {
|
||||||
this._scanner.enable();
|
this._scanner.enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove any previous listener, to make sure we only add one listener if enable() is
|
// Remove any previous listener, to make sure we only add one listener if enable() is
|
||||||
// called several times.
|
// called several times.
|
||||||
adbAddon.off("update", this._onAddonUpdate);
|
this._addon.off("update", this._onAddonUpdate);
|
||||||
|
|
||||||
adbAddon.on("update", this._onAddonUpdate);
|
this._addon.on("update", this._onAddonUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
disable() {
|
disable() {
|
||||||
this._scanner.disable();
|
this._scanner.disable();
|
||||||
|
|
||||||
adbAddon.off("update", this._onAddonUpdate);
|
this._addon.off("update", this._onAddonUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,7 +84,7 @@ class AddonAwareADBScanner extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
_onAddonUpdate() {
|
_onAddonUpdate() {
|
||||||
if (adbAddon.status === "installed") {
|
if (this._addon.status === "installed") {
|
||||||
this._scanner.enable();
|
this._scanner.enable();
|
||||||
} else {
|
} else {
|
||||||
this._scanner.disable();
|
this._scanner.disable();
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const EventEmitter = require("devtools/shared/event-emitter");
|
const EventEmitter = require("devtools/shared/event-emitter");
|
||||||
|
|
|
@ -0,0 +1,221 @@
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const EventEmitter = require("devtools/shared/event-emitter");
|
||||||
|
const { AddonAwareADBScanner } = require("devtools/shared/adb/addon-aware-adb-scanner");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For the scanner mock, we create an object with spies for each of the public methods
|
||||||
|
* used by the AddonAwareADBScanner, and the ability to emit events.
|
||||||
|
*/
|
||||||
|
function prepareMockScanner() {
|
||||||
|
const mockScanner = {
|
||||||
|
enable: sinon.spy(),
|
||||||
|
disable: sinon.spy(),
|
||||||
|
scan: sinon.spy(),
|
||||||
|
listRuntimes: sinon.spy()
|
||||||
|
};
|
||||||
|
EventEmitter.decorate(mockScanner);
|
||||||
|
return mockScanner;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For the addon mock, we simply need an object that is able to emit events and has a
|
||||||
|
* status.
|
||||||
|
*/
|
||||||
|
function prepareMockAddon() {
|
||||||
|
const mockAddon = {
|
||||||
|
status: "unknown",
|
||||||
|
};
|
||||||
|
EventEmitter.decorate(mockAddon);
|
||||||
|
return mockAddon;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare all mocks needed for the scanner tests.
|
||||||
|
*/
|
||||||
|
function prepareMocks() {
|
||||||
|
const mockScanner = prepareMockScanner();
|
||||||
|
const mockAddon = prepareMockAddon();
|
||||||
|
const addonAwareAdbScanner = new AddonAwareADBScanner(mockScanner, mockAddon);
|
||||||
|
return { addonAwareAdbScanner, mockAddon, mockScanner };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test covers basic usage of enable() on the AddonAwareADBScanner, and checks the
|
||||||
|
* different behaviors based on the addon status.
|
||||||
|
*/
|
||||||
|
add_task(async function testCallingEnable() {
|
||||||
|
const { mockScanner, mockAddon, addonAwareAdbScanner } = prepareMocks();
|
||||||
|
|
||||||
|
// Check that enable() is not called if the addon is uninstalled
|
||||||
|
mockAddon.status = "uninstalled";
|
||||||
|
addonAwareAdbScanner.enable();
|
||||||
|
ok(mockScanner.enable.notCalled, "enable() was not called");
|
||||||
|
mockScanner.enable.reset();
|
||||||
|
|
||||||
|
// Check that enable() is called if the addon is installed
|
||||||
|
mockAddon.status = "installed";
|
||||||
|
addonAwareAdbScanner.enable();
|
||||||
|
ok(mockScanner.enable.called, "enable() was called");
|
||||||
|
mockScanner.enable.reset();
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test checks that enable()/disable() methods from the internal ADBScanner are
|
||||||
|
* called when the addon is installed or uninstalled.
|
||||||
|
*/
|
||||||
|
add_task(async function testUpdatingAddonEnablesDisablesScanner() {
|
||||||
|
const { mockScanner, mockAddon, addonAwareAdbScanner } = prepareMocks();
|
||||||
|
|
||||||
|
// Enable the addon aware scanner
|
||||||
|
addonAwareAdbScanner.enable();
|
||||||
|
ok(mockScanner.enable.notCalled, "enable() was not called initially");
|
||||||
|
|
||||||
|
// Check that enable() is called automatically when the addon is installed
|
||||||
|
mockAddon.status = "installed";
|
||||||
|
mockAddon.emit("update");
|
||||||
|
ok(mockScanner.enable.called, "enable() was called when installing the addon");
|
||||||
|
ok(mockScanner.disable.notCalled, "disable() was not called when installing the addon");
|
||||||
|
mockScanner.enable.reset();
|
||||||
|
mockScanner.disable.reset();
|
||||||
|
|
||||||
|
// Check that disabled() is called automatically when the addon is uninstalled
|
||||||
|
mockAddon.status = "uninstalled";
|
||||||
|
mockAddon.emit("update");
|
||||||
|
ok(mockScanner.enable.notCalled, "enable() was not called when uninstalling the addon");
|
||||||
|
ok(mockScanner.disable.called, "disable() was called when uninstalling the addon");
|
||||||
|
mockScanner.enable.reset();
|
||||||
|
mockScanner.disable.reset();
|
||||||
|
|
||||||
|
// Check that enable() is called again when the addon is reinstalled
|
||||||
|
mockAddon.status = "installed";
|
||||||
|
mockAddon.emit("update");
|
||||||
|
ok(mockScanner.enable.called, "enable() was called when installing the addon");
|
||||||
|
ok(mockScanner.disable.notCalled, "disable() was not called when installing the addon");
|
||||||
|
mockScanner.enable.reset();
|
||||||
|
mockScanner.disable.reset();
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test checks that disable() is forwarded from the AddonAwareADBScanner to the real
|
||||||
|
* scanner even if the addon is uninstalled. We might miss the addon uninstall
|
||||||
|
* notification, so it is safer to always proceed with disabling.
|
||||||
|
*/
|
||||||
|
add_task(async function testScannerIsDisabledWhenMissingAddonUpdate() {
|
||||||
|
const { mockScanner, mockAddon, addonAwareAdbScanner } = prepareMocks();
|
||||||
|
|
||||||
|
// Enable the addon aware scanner
|
||||||
|
mockAddon.status = "installed";
|
||||||
|
addonAwareAdbScanner.enable();
|
||||||
|
ok(mockScanner.enable.called, "enable() was called initially");
|
||||||
|
mockScanner.enable.reset();
|
||||||
|
|
||||||
|
// Uninstall the addon without firing any event
|
||||||
|
mockAddon.status = "uninstalled";
|
||||||
|
|
||||||
|
// Programmatically call disable, check that the scanner's disable is called even though
|
||||||
|
// the addon was uninstalled.
|
||||||
|
addonAwareAdbScanner.disable();
|
||||||
|
ok(mockScanner.disable.called, "disable() was called when uninstalling the addon");
|
||||||
|
mockScanner.disable.reset();
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test checks that when the AddonAwareADBScanner is disabled, then enable/disable
|
||||||
|
* are not called on the inner scanner when the addon status changes.
|
||||||
|
*/
|
||||||
|
add_task(async function testInnerEnableIsNotCalledIfNotStarted() {
|
||||||
|
const { mockScanner, mockAddon, addonAwareAdbScanner } = prepareMocks();
|
||||||
|
|
||||||
|
// Check that enable() is not called on the inner scanner when the addon is installed
|
||||||
|
// if the AddonAwareADBScanner was not enabled
|
||||||
|
mockAddon.status = "installed";
|
||||||
|
mockAddon.emit("update");
|
||||||
|
ok(mockScanner.enable.notCalled, "enable() was not called");
|
||||||
|
|
||||||
|
// Same for disable() and "uninstall"
|
||||||
|
mockAddon.status = "uninstalled";
|
||||||
|
mockAddon.emit("update");
|
||||||
|
ok(mockScanner.disable.notCalled, "disable() was not called");
|
||||||
|
|
||||||
|
// Enable the addon aware scanner
|
||||||
|
addonAwareAdbScanner.enable();
|
||||||
|
ok(mockScanner.enable.notCalled, "enable() was not called");
|
||||||
|
ok(mockScanner.disable.notCalled, "disable() was not called");
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test checks that when the AddonAwareADBScanner is disabled, installing the addon
|
||||||
|
* no longer enables the internal ADBScanner.
|
||||||
|
*/
|
||||||
|
add_task(async function testEnableIsNoLongerCalledAfterDisabling() {
|
||||||
|
const { mockScanner, mockAddon, addonAwareAdbScanner } = prepareMocks();
|
||||||
|
|
||||||
|
// Start with the addon installed
|
||||||
|
mockAddon.status = "installed";
|
||||||
|
addonAwareAdbScanner.enable();
|
||||||
|
ok(mockScanner.enable.called, "enable() was called since addon was already installed");
|
||||||
|
mockScanner.enable.reset();
|
||||||
|
|
||||||
|
// Here we call enable again to check that we will not add too many events.
|
||||||
|
// A single call to disable() should stop all listeners, even if we called enable()
|
||||||
|
// several times.
|
||||||
|
addonAwareAdbScanner.enable();
|
||||||
|
ok(mockScanner.enable.called, "enable() was called again");
|
||||||
|
mockScanner.enable.reset();
|
||||||
|
|
||||||
|
// Disable the scanner
|
||||||
|
addonAwareAdbScanner.disable();
|
||||||
|
ok(mockScanner.disable.called, "disable() was called");
|
||||||
|
mockScanner.disable.reset();
|
||||||
|
|
||||||
|
// Emit an addon update event
|
||||||
|
mockAddon.emit("update");
|
||||||
|
ok(mockScanner.enable.notCalled,
|
||||||
|
"enable() is not called since the main scanner is disabled");
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic check that the "runtime-list-updated" event is forwarded.
|
||||||
|
*/
|
||||||
|
add_task(async function testListUpdatedEventForwarding() {
|
||||||
|
const { mockScanner, addonAwareAdbScanner } = prepareMocks();
|
||||||
|
|
||||||
|
const spy = sinon.spy();
|
||||||
|
addonAwareAdbScanner.on("runtime-list-updated", spy);
|
||||||
|
mockScanner.emit("runtime-list-updated");
|
||||||
|
ok(spy.called, "The runtime-list-updated event was forwarded from ADBScanner");
|
||||||
|
addonAwareAdbScanner.off("runtime-list-updated", spy);
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic check that calls to scan() are forwarded.
|
||||||
|
*/
|
||||||
|
add_task(async function testScanCallForwarding() {
|
||||||
|
const { mockScanner, addonAwareAdbScanner } = prepareMocks();
|
||||||
|
|
||||||
|
ok(mockScanner.scan.notCalled, "ADBScanner scan() is not called initially");
|
||||||
|
|
||||||
|
addonAwareAdbScanner.scan();
|
||||||
|
mockScanner.emit("runtime-list-updated");
|
||||||
|
ok(mockScanner.scan.called, "ADBScanner scan() was called");
|
||||||
|
mockScanner.scan.reset();
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic check that calls to scan() are forwarded.
|
||||||
|
*/
|
||||||
|
add_task(async function testListRuntimesCallForwarding() {
|
||||||
|
const { mockScanner, addonAwareAdbScanner } = prepareMocks();
|
||||||
|
|
||||||
|
ok(mockScanner.listRuntimes.notCalled,
|
||||||
|
"ADBScanner listRuntimes() is not called initially");
|
||||||
|
|
||||||
|
addonAwareAdbScanner.listRuntimes();
|
||||||
|
mockScanner.emit("runtime-list-updated");
|
||||||
|
ok(mockScanner.listRuntimes.called, "ADBScanner listRuntimes() was called");
|
||||||
|
mockScanner.scan.reset();
|
||||||
|
});
|
|
@ -6,3 +6,12 @@
|
||||||
/* eslint no-unused-vars: [2, {"vars": "local"}] */
|
/* eslint no-unused-vars: [2, {"vars": "local"}] */
|
||||||
|
|
||||||
const { require } = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
|
const { require } = ChromeUtils.import("resource://devtools/shared/Loader.jsm", {});
|
||||||
|
const Services = require("Services");
|
||||||
|
|
||||||
|
// ================================================
|
||||||
|
// Load mocking/stubbing library, sinon
|
||||||
|
// docs: http://sinonjs.org/releases/v2.3.2/
|
||||||
|
ChromeUtils.import("resource://gre/modules/Timer.jsm");
|
||||||
|
Services.scriptloader.loadSubScript("resource://testing-common/sinon-2.3.2.js", this);
|
||||||
|
/* globals sinon */
|
||||||
|
// ================================================
|
||||||
|
|
|
@ -8,3 +8,4 @@ support-files =
|
||||||
|
|
||||||
[test_adb.js]
|
[test_adb.js]
|
||||||
run-sequentially = An extension having the same id is installed/uninstalled in different tests
|
run-sequentially = An extension having the same id is installed/uninstalled in different tests
|
||||||
|
[test_addon-aware-adb-scanner.js]
|
||||||
|
|
Загрузка…
Ссылка в новой задаче