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

add tests #7

Merged
merged 3 commits into from
Mar 13, 2024
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
57 changes: 31 additions & 26 deletions src/source/rtl_text_plugin_main_thread.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ describe('RTLMainThreadPlugin', () => {
let server: FakeServer;
let broadcastSpy: jest.SpyInstance;
const url = 'http://example.com/plugin';
const failedToLoadMessage = `RTL Text Plugin failed to import scripts from ${url}`;
const SyncRTLPluginStateMessageName = 'syncRTLPluginState';

beforeEach(() => {
Expand All @@ -22,6 +23,7 @@ describe('RTLMainThreadPlugin', () => {
});

function broadcastMockSuccess(message: MessageType, payload: PluginState): Promise<PluginState[]> {
console.log('broadcastMockSuccessDefer', payload.pluginStatus);
if (message === SyncRTLPluginStateMessageName) {
if (payload.pluginStatus === 'loading') {
const resultState: PluginState = {
Expand All @@ -33,32 +35,25 @@ describe('RTLMainThreadPlugin', () => {
}
}

function broadcastMockFailure(message: MessageType, payload: PluginState): Promise<PluginState[]> {
function broadcastMockSuccessDefer(message: MessageType, payload: PluginState): Promise<PluginState[]> {
if (message === SyncRTLPluginStateMessageName) {
if (payload.pluginStatus === 'loading') {
if (payload.pluginStatus === 'deferred') {
const resultState: PluginState = {
pluginStatus: 'error',
pluginStatus: 'deferred',
pluginURL: payload.pluginURL
};
return Promise.resolve([resultState]);
}
}
}

/** return two results, one success one failure */
function broadcastMockMix(message: MessageType, payload: PluginState): Promise<PluginState[]> {
function broadcastMockFailure(message: MessageType, payload: PluginState): Promise<PluginState[]> {
if (message === SyncRTLPluginStateMessageName) {
if (payload.pluginStatus === 'loading') {
const resultState0: PluginState = {
pluginStatus: 'loaded',
pluginURL: payload.pluginURL
};
const resultState1: PluginState = {
pluginStatus: 'error',
pluginURL: payload.pluginURL
};
return Promise.resolve([resultState0, resultState1]);
return Promise.reject(failedToLoadMessage);
}
} else {
return Promise.resolve([]);
}
}

Expand Down Expand Up @@ -98,37 +93,42 @@ describe('RTLMainThreadPlugin', () => {

it('should be in error state if download fails', async () => {
broadcastSpy = jest.spyOn(Dispatcher.prototype, 'broadcast').mockImplementation(broadcastMockFailure as any);
await rtlMainThreadPlugin.setRTLTextPlugin(url);
const resultPromise = rtlMainThreadPlugin.setRTLTextPlugin(url);
await expect(resultPromise).rejects.toBe(failedToLoadMessage);
expect(rtlMainThreadPlugin.url).toEqual(url);
expect(rtlMainThreadPlugin.status).toBe('error');
});

it('should lazy load the plugin if deferred', async () => {
// use success spy to make sure test case does not throw exception
broadcastSpy = jest.spyOn(Dispatcher.prototype, 'broadcast').mockImplementation(broadcastMockSuccess as any);
const deferredSpy = jest.spyOn(Dispatcher.prototype, 'broadcast').mockImplementation(broadcastMockSuccessDefer as any);
await rtlMainThreadPlugin.setRTLTextPlugin(url, true);
expect(broadcastSpy).toHaveBeenCalledWith(SyncRTLPluginStateMessageName, {pluginStatus: 'deferred', pluginURL: url});
expect(deferredSpy).toHaveBeenCalledTimes(1);
expect(deferredSpy).toHaveBeenCalledWith(SyncRTLPluginStateMessageName, {pluginStatus: 'deferred', pluginURL: url});
expect(rtlMainThreadPlugin.status).toBe('deferred');
deferredSpy.mockRestore();

// this is really a fire and forget
// two calls to lazyLoad
broadcastSpy = jest.spyOn(Dispatcher.prototype, 'broadcast').mockImplementation(broadcastMockSuccess as any);
rtlMainThreadPlugin.lazyLoad();
await sleep(1);
expect(broadcastSpy).toHaveBeenCalledWith(SyncRTLPluginStateMessageName, {pluginStatus: 'loading', pluginURL: url});

// two times, first for "deferred", second for 'loading'
expect(broadcastSpy).toHaveBeenCalledTimes(2);
// 'loading'
expect(broadcastSpy).toHaveBeenCalledWith(SyncRTLPluginStateMessageName, {pluginStatus: 'loading', pluginURL: url});
expect(broadcastSpy).toHaveBeenCalledTimes(1);

// second call to lazyLoad should not change anything
// // second call to lazyLoad should not change anything
rtlMainThreadPlugin.lazyLoad();
expect(broadcastSpy).toHaveBeenCalledTimes(2);
expect(broadcastSpy).toHaveBeenCalledTimes(1);

expect(rtlMainThreadPlugin.status).toBe('loaded');

// 3rd call to lazyLoad should not change anything
rtlMainThreadPlugin.lazyLoad();
expect(rtlMainThreadPlugin.status).toBe('loaded');
expect(broadcastSpy).toHaveBeenCalledTimes(2);
expect(broadcastSpy).toHaveBeenCalledTimes(1);
});

it('should set status to requested if RTL plugin was not set', async () => {
Expand All @@ -155,13 +155,18 @@ describe('RTLMainThreadPlugin', () => {
expect(rtlMainThreadPlugin.status).toBe('requested');
});

it('should report error for multiple results and one failure', async () => {
broadcastSpy = jest.spyOn(Dispatcher.prototype, 'broadcast').mockImplementation(broadcastMockMix as any);
it('should be in error state if lazyLoad fails', async () => {
broadcastSpy = jest.spyOn(Dispatcher.prototype, 'broadcast').mockImplementation(broadcastMockSuccessDefer);
const resultPromise = rtlMainThreadPlugin.setRTLTextPlugin(url, true);
await expect(resultPromise).resolves.toBeUndefined();

await rtlMainThreadPlugin.setRTLTextPlugin(url);
expect(rtlMainThreadPlugin.status).toBe('deferred');

// the next one should fail
broadcastSpy = jest.spyOn(Dispatcher.prototype, 'broadcast').mockImplementation(broadcastMockFailure as any);

await expect(rtlMainThreadPlugin._requestImport()).rejects.toBe(failedToLoadMessage);
expect(rtlMainThreadPlugin.url).toEqual(url);
expect(rtlMainThreadPlugin.status).toBe('error');

});
});
19 changes: 18 additions & 1 deletion test/integration/browser/browser.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import puppeteer, {Page, Browser} from 'puppeteer';
import puppeteer, {Page, Browser, ConsoleMessage} from 'puppeteer';

Check warning on line 1 in test/integration/browser/browser.test.ts

View workflow job for this annotation

GitHub Actions / Code Hygiene

'ConsoleMessage' is defined but never used
import st from 'st';
import http, {type Server} from 'http';
import type {AddressInfo} from 'net';
Expand Down Expand Up @@ -385,4 +385,21 @@

expect(markerOpacity).toBe('1');
}, 20000);

test('Load map with RTL plugin should throw exception for invalid URL', async () => {

const rtlPromise = page.evaluate(() => {
// console.log('Testing start');
return maplibregl.setRTLTextPlugin('badURL', false);
});

await rtlPromise.catch(e => {
const message: string = e.message;

// exact message looks like
// Failed to execute 'importScripts' on 'WorkerGlobalScope': The script at 'http://localhost:52015/test/integration/browser/fixtures/badURL' failed to load.
const regex = new RegExp('Failed to execute \'importScripts\' on \'WorkerGlobalScope\': The script at \'.*\' failed to load.');
expect(regex.test(message)).toBe(true);
});
}, 2000);
});
Loading