tests: Port InjectionManager test to jasmine
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3164>
This commit is contained in:
parent
9315d42dd6
commit
d62146bc19
@ -21,6 +21,7 @@ unit_testenv.append('GI_TYPELIB_PATH', st_typelib_path, separator: ':')
|
|||||||
|
|
||||||
unit_tests = [
|
unit_tests = [
|
||||||
'highlighter',
|
'highlighter',
|
||||||
|
'injectionManager',
|
||||||
]
|
]
|
||||||
|
|
||||||
foreach test : unit_tests
|
foreach test : unit_tests
|
||||||
@ -39,7 +40,6 @@ foreach test : unit_tests
|
|||||||
endforeach
|
endforeach
|
||||||
|
|
||||||
legacy_tests = [
|
legacy_tests = [
|
||||||
'injectionManager',
|
|
||||||
'insertSorted',
|
'insertSorted',
|
||||||
'jsParse',
|
'jsParse',
|
||||||
'markup',
|
'markup',
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
const JsUnit = imports.jsUnit;
|
|
||||||
|
|
||||||
import GObject from 'gi://GObject';
|
import GObject from 'gi://GObject';
|
||||||
|
|
||||||
import 'resource:///org/gnome/shell/ui/environment.js';
|
import 'resource:///org/gnome/shell/ui/environment.js';
|
||||||
|
|
||||||
import {InjectionManager} from 'resource:///org/gnome/shell/extensions/extension.js';
|
import {InjectionManager} from 'resource:///org/gnome/shell/extensions/extension.js';
|
||||||
|
|
||||||
|
const FIXED_NUMBER = 42;
|
||||||
|
|
||||||
class Object1 {
|
class Object1 {
|
||||||
count = 0;
|
count = 0;
|
||||||
|
|
||||||
getNumber() {
|
getNumber() {
|
||||||
return 42;
|
return FIXED_NUMBER;
|
||||||
}
|
}
|
||||||
|
|
||||||
getCount() {
|
getCount() {
|
||||||
@ -29,109 +29,166 @@ class GObject1 extends GObject.Object {
|
|||||||
static {
|
static {
|
||||||
GObject.registerClass(this);
|
GObject.registerClass(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
plonk() {
|
|
||||||
this.set_property('plonked', true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
describe('InjectionManager', () => {
|
||||||
* @param {object} object to modify
|
const INJECTIONS = {
|
||||||
*/
|
'getNumber': originalMethod => {
|
||||||
function addInjections(object) {
|
|
||||||
// extend original method
|
|
||||||
injectionManager.overrideMethod(
|
|
||||||
object, 'getNumber', originalMethod => {
|
|
||||||
return function () {
|
return function () {
|
||||||
// eslint-disable-next-line no-invalid-this
|
// eslint-disable-next-line no-invalid-this
|
||||||
const num = originalMethod.call(this);
|
const num = originalMethod.call(this);
|
||||||
return 2 * num;
|
return 2 * num;
|
||||||
};
|
};
|
||||||
});
|
},
|
||||||
|
'getCount': () => {
|
||||||
// override original method
|
|
||||||
injectionManager.overrideMethod(
|
|
||||||
object, 'getCount', () => {
|
|
||||||
return function () {
|
return function () {
|
||||||
return 42;
|
return FIXED_NUMBER;
|
||||||
};
|
};
|
||||||
});
|
},
|
||||||
|
'getOtherNumber': () => {
|
||||||
// inject new method
|
|
||||||
injectionManager.overrideMethod(
|
|
||||||
object, 'getOtherNumber', () => {
|
|
||||||
return function () {
|
return function () {
|
||||||
return 42;
|
return FIXED_NUMBER;
|
||||||
};
|
};
|
||||||
});
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
|
let injectionManager;
|
||||||
|
|
||||||
const injectionManager = new InjectionManager();
|
function injectAll(obj) {
|
||||||
let obj;
|
for (const func in INJECTIONS) {
|
||||||
|
injectionManager.overrideMethod(obj,
|
||||||
|
func, INJECTIONS[func]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Prototype injections
|
beforeEach(() => {
|
||||||
addInjections(Object1.prototype);
|
injectionManager = new InjectionManager();
|
||||||
|
|
||||||
obj = new Object1();
|
|
||||||
|
|
||||||
// new obj is modified
|
|
||||||
JsUnit.assertEquals(obj.getNumber(), 84);
|
|
||||||
JsUnit.assertEquals(obj.getCount(), 42);
|
|
||||||
JsUnit.assertEquals(obj.count, 0);
|
|
||||||
JsUnit.assertEquals(obj.getOtherNumber(), 42);
|
|
||||||
|
|
||||||
injectionManager.clear();
|
|
||||||
|
|
||||||
obj = new Object1();
|
|
||||||
|
|
||||||
// new obj is unmodified
|
|
||||||
JsUnit.assertEquals(obj.getNumber(), 42);
|
|
||||||
JsUnit.assertEquals(obj.getCount(), obj.count);
|
|
||||||
JsUnit.assert(obj.count > 0);
|
|
||||||
JsUnit.assertRaises(() => obj.getOtherNumber());
|
|
||||||
|
|
||||||
// instance injections
|
|
||||||
addInjections(obj);
|
|
||||||
|
|
||||||
// obj is now modified
|
|
||||||
JsUnit.assertEquals(obj.getNumber(), 84);
|
|
||||||
JsUnit.assertEquals(obj.getCount(), 42);
|
|
||||||
JsUnit.assertEquals(obj.count, 1);
|
|
||||||
JsUnit.assertEquals(obj.getOtherNumber(), 42);
|
|
||||||
|
|
||||||
injectionManager.restoreMethod(obj, 'getNumber');
|
|
||||||
JsUnit.assertEquals(obj.getNumber(), 42);
|
|
||||||
|
|
||||||
injectionManager.clear();
|
|
||||||
|
|
||||||
// obj is unmodified again
|
|
||||||
JsUnit.assertEquals(obj.getNumber(), 42);
|
|
||||||
JsUnit.assertEquals(obj.getCount(), obj.count);
|
|
||||||
JsUnit.assert(obj.count > 0);
|
|
||||||
JsUnit.assertRaises(() => obj.getOtherNumber());
|
|
||||||
|
|
||||||
// GObject injections
|
|
||||||
const gobj = new GObject1();
|
|
||||||
let vfuncCalled;
|
|
||||||
|
|
||||||
injectionManager.overrideMethod(
|
|
||||||
GObject1.prototype, 'vfunc_set_property', originalMethod => {
|
|
||||||
return function (...args) {
|
|
||||||
// eslint-disable-next-line no-invalid-this
|
|
||||||
originalMethod.apply(this, args);
|
|
||||||
vfuncCalled = true;
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// gobj is now modified
|
afterEach(() => {
|
||||||
vfuncCalled = false;
|
injectionManager.clear();
|
||||||
gobj.plonk();
|
});
|
||||||
JsUnit.assertTrue(vfuncCalled);
|
|
||||||
|
|
||||||
injectionManager.clear();
|
it('can extend prototype methods', () => {
|
||||||
|
injectionManager.overrideMethod(Object1.prototype,
|
||||||
|
'getNumber', INJECTIONS['getNumber']);
|
||||||
|
|
||||||
// gobj is unmodified again
|
const obj = new Object1();
|
||||||
vfuncCalled = false;
|
expect(obj.getNumber()).toEqual(2 * FIXED_NUMBER);
|
||||||
gobj.plonk();
|
});
|
||||||
JsUnit.assertFalse(vfuncCalled);
|
|
||||||
|
it('can replace prototype methods', () => {
|
||||||
|
injectionManager.overrideMethod(Object1.prototype,
|
||||||
|
'getCount', INJECTIONS['getCount']);
|
||||||
|
|
||||||
|
const obj = new Object1();
|
||||||
|
expect(obj.getCount()).toEqual(42);
|
||||||
|
expect(obj.count).toEqual(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can inject methods into prototypes', () => {
|
||||||
|
injectionManager.overrideMethod(Object1.prototype,
|
||||||
|
'getOtherNumber', INJECTIONS['getOtherNumber']);
|
||||||
|
|
||||||
|
const obj = new Object1();
|
||||||
|
expect(obj.getOtherNumber()).toEqual(42);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can undo prototype injections', () => {
|
||||||
|
injectAll(Object1.prototype);
|
||||||
|
|
||||||
|
injectionManager.clear();
|
||||||
|
|
||||||
|
const obj = new Object1();
|
||||||
|
expect(obj.getNumber()).toEqual(FIXED_NUMBER);
|
||||||
|
expect(obj.getCount()).toEqual(obj.count);
|
||||||
|
expect(obj.count).toBeGreaterThan(0);
|
||||||
|
expect(() => obj.getOtherNumber()).toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can extend instance methods', () => {
|
||||||
|
const obj = new Object1();
|
||||||
|
injectionManager.overrideMethod(obj,
|
||||||
|
'getNumber', INJECTIONS['getNumber']);
|
||||||
|
|
||||||
|
expect(obj.getNumber()).toEqual(2 * FIXED_NUMBER);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can replace instance methods', () => {
|
||||||
|
const obj = new Object1();
|
||||||
|
injectionManager.overrideMethod(obj,
|
||||||
|
'getCount', INJECTIONS['getCount']);
|
||||||
|
|
||||||
|
expect(obj.getCount()).toEqual(42);
|
||||||
|
expect(obj.count).toEqual(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can inject methods into instances', () => {
|
||||||
|
const obj = new Object1();
|
||||||
|
injectionManager.overrideMethod(obj,
|
||||||
|
'getOtherNumber', INJECTIONS['getOtherNumber']);
|
||||||
|
|
||||||
|
expect(obj.getOtherNumber()).toEqual(42);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can undo instance injections', () => {
|
||||||
|
const obj = new Object1();
|
||||||
|
|
||||||
|
injectAll(obj);
|
||||||
|
|
||||||
|
injectionManager.clear();
|
||||||
|
|
||||||
|
expect(obj.getNumber()).toEqual(FIXED_NUMBER);
|
||||||
|
expect(obj.getCount()).toEqual(obj.count);
|
||||||
|
expect(obj.count).toBeGreaterThan(0);
|
||||||
|
expect(() => obj.getOtherNumber()).toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can restore an original method', () => {
|
||||||
|
const obj = new Object1();
|
||||||
|
|
||||||
|
injectAll(obj);
|
||||||
|
|
||||||
|
expect(obj.getNumber()).toEqual(2 * FIXED_NUMBER);
|
||||||
|
|
||||||
|
injectionManager.restoreMethod(obj, 'getNumber');
|
||||||
|
expect(obj.getNumber()).toEqual(FIXED_NUMBER);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can extend a GObject vfunc', () => {
|
||||||
|
const gobj = new GObject1();
|
||||||
|
let vfuncCalled;
|
||||||
|
|
||||||
|
injectionManager.overrideMethod(
|
||||||
|
GObject1.prototype, 'vfunc_set_property', originalMethod => {
|
||||||
|
return function (...args) {
|
||||||
|
// eslint-disable-next-line no-invalid-this
|
||||||
|
originalMethod.apply(this, args);
|
||||||
|
vfuncCalled = true;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
vfuncCalled = false;
|
||||||
|
gobj.set_property('plonked', true);
|
||||||
|
expect(vfuncCalled).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can restore a GObject vfunc', () => {
|
||||||
|
const gobj = new GObject1();
|
||||||
|
let vfuncCalled;
|
||||||
|
|
||||||
|
injectionManager.overrideMethod(
|
||||||
|
GObject1.prototype, 'vfunc_set_property', originalMethod => {
|
||||||
|
return function (...args) {
|
||||||
|
// eslint-disable-next-line no-invalid-this
|
||||||
|
originalMethod.apply(this, args);
|
||||||
|
vfuncCalled = true;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
injectionManager.clear();
|
||||||
|
|
||||||
|
vfuncCalled = false;
|
||||||
|
gobj.set_property('plonked', true);
|
||||||
|
expect(vfuncCalled).toEqual(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user