Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Beta Part 5: Part of Mega Dynamic Load/Unload support #1782

Merged
merged 1 commit into from
Mar 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export class SenderTests extends AITestClass {
this._offline = createOfflineListener("SenderTests");
}

public testCleanup() {
public testFinishedCleanup() {
if (this._offline) {
this._offline.unload();
}
Expand Down
121 changes: 103 additions & 18 deletions common/Tests/Framework/src/AITestClass.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ export class AITestClass {
public fakeServerAutoRespond: boolean = false;
public isEmulatingEs3: boolean;

/**
* Automatically assert that all registered events have been removed
*/
public assertNoEvents: boolean = false;

/**
* Automatically assert that all hooks have been removed
*/
public assertNoHooks: boolean = false;

protected _orgCrypto: Crypto | null;
protected _orgLocation: Location | null;

Expand All @@ -96,6 +106,8 @@ export class AITestClass {
private _orgObjectFuncs: any = null;
private _orgFetch: any = null;

private _onDoneFuncs: VoidFunction[] = [];

constructor(name?: string, emulateEs3?: boolean) {
this._moduleName = (emulateEs3 ? "(ES3) " : "") + (name || _getObjName(this, ""));
this.isEmulatingEs3 = emulateEs3
Expand All @@ -122,7 +134,24 @@ export class AITestClass {
public testInitialize() {
}

/** Method called after each test method has completed */
/**
* Method called immediately after the test case has finished, but before the automatic test case assertions.
* Use this method to call unload / teardown so the SDK can remove it's own events before being validated
*/
public testFinishedCleanup() {
this._onDoneFuncs.forEach((fn) => {
try {
fn();
} catch (e) {
// Do nothing during cleanup
}
});
this._onDoneFuncs = [];
}

/** Method called after each test method has completed and after the test sandbox has been cleanup up.
* This is the final step before the next test is executed
*/
public testCleanup() {
}

Expand Down Expand Up @@ -185,14 +214,29 @@ export class AITestClass {
this._emulateEs3();
}

if (testInfo.assertNoEvents === undefined) {
testInfo.assertNoEvents = this.assertNoEvents;
}

if (testInfo.assertNoHooks === undefined) {
testInfo.assertNoHooks = this.assertNoHooks;
}

// Run the test.
try {
let self = this;
let testComplete = false;
let timeOutTimer: any = null;
let stepIndex = 0;

const testDone = () => {
this._onDoneFuncs.forEach((fn) => {
fn();
});
this._onDoneFuncs = [];

self.testFinishedCleanup();

if (testInfo.assertNoEvents) {
self._assertEventsRemoved();
}
Expand Down Expand Up @@ -325,6 +369,8 @@ export class AITestClass {
AITestClass.currentTestInfo = testInfo;

function _testFinished(failed?: boolean) {
self.testFinishedCleanup();

if (testInfo.assertNoEvents) {
self._assertEventsRemoved();
}
Expand Down Expand Up @@ -366,6 +412,14 @@ export class AITestClass {
this._emulateEs3();
}

if (testInfo.assertNoEvents === undefined) {
testInfo.assertNoEvents = this.assertNoEvents;
}

if (testInfo.assertNoHooks === undefined) {
testInfo.assertNoHooks = this.assertNoHooks;
}

// Run the test.
try {
this._testStarting();
Expand Down Expand Up @@ -472,6 +526,12 @@ export class AITestClass {
Assert.ok(false, msg);
}

protected onDone(cleanupFn: VoidFunction) {
if (cleanupFn) {
this._onDoneFuncs.push(cleanupFn);
}
}

protected setUserAgent(userAgent: string) {
// Hook Send beacon which also mocks navigator
this.hookSendBeacon(null);
Expand Down Expand Up @@ -829,6 +889,7 @@ export class AITestClass {

this._beaconHooks = [];
this._cleanupAllHooks();
this._cleanupEvents();
this._restoreEs3();

if (failed) {
Expand All @@ -841,21 +902,27 @@ export class AITestClass {
}

this.testCleanup();
this._cleanupEvents();

// Clear the instance of the currently running suite.
AITestClass.currentTestClass = null;
AITestClass.currentTestInfo = null;
}

private _assertRemoveFuncHooks(fn:any, targetName: string) {
let failed = false;

if (typeof fn === "function") {
let aiHook:any = fn["_aiHooks"];

if (aiHook && aiHook.h) {
aiHook.h.forEach((hook: any) => {
Assert.ok(false, targetName + " Hook: " + aiHook.n + "." + _formatNamespace(hook.cbks.ns || "") + " exists");
failed = true;
});

if (!failed) {
QUnit.assert.ok(true, "Validated [" + targetName + "] has no registered hooks");
}
}
}
}
Expand All @@ -864,7 +931,7 @@ export class AITestClass {
if (target) {
Object.keys(target).forEach(name => {
try {
this._assertRemoveFuncHooks(target[name], targetName);
this._assertRemoveFuncHooks(target[name], targetName + "." + name);
} catch (e) {
// eslint-disable-next-line no-empty
}
Expand Down Expand Up @@ -994,17 +1061,29 @@ export class AITestClass {
}

private _assertNoEvents(target: any, targetName: string): void {
let failed = false;
_getAllAiDataKeys(target, (name, value) => {
if (value && name.startsWith("_aiDataEvents")) {
let events = value.events;
_objForEachKey(events, (evtName, evts) => {
for (let lp = 0; lp < evts.length; lp++) {
let theEvent = evts[lp];
Assert.ok(false, "[" + targetName + "] has registered event handler [" + evtName + "." + (theEvent.evtName.ns || "") + "]");
}
});
if (events) {
_objForEachKey(events, (evtName, evts) => {
if (evts) {
for (let lp = 0; lp < evts.length; lp++) {
let theEvent = evts[lp];
if (theEvent) {
Assert.ok(false, "[" + targetName + "] has registered event handler [" + evtName + "." + (theEvent.evtName.ns || "") + "]");
failed = true;
}
}
}
});
}
}
});

if (!failed) {
QUnit.assert.ok(true, "Validated [" + targetName + "] has no registered event handlers");
}
}

private _removeAllEvents(target: any, targetName: string): any {
Expand All @@ -1013,15 +1092,21 @@ export class AITestClass {
if (value && name.startsWith("_aiDataEvents")) {
dataName.push(name);
let events = value.events;
_objForEachKey(events, (evtName, evts) => {
for (let lp = 0; lp < evts.length; lp++) {
let theEvent = evts[lp];
console && console.log("Removing [" + targetName + "] event handler " + evtName + "." + (theEvent.evtName.ns || ""));
if (target.removeEventListener) {
target.removeEventListener(evtName, theEvent.handler, theEvent.capture);
if (events) {
_objForEachKey(events, (evtName, evts) => {
if (evts) {
for (let lp = 0; lp < evts.length; lp++) {
let theEvent = evts[lp];
if (theEvent) {
console && console.log("Removing [" + targetName + "] event handler " + evtName + "." + (theEvent.evtName.ns || ""));
if (target.removeEventListener) {
target.removeEventListener(evtName, theEvent.handler, theEvent.capture);
}
}
}
}
}
});
});
}

delete value.events;
}
Expand Down
Loading