test(service-worker): remove obsolete async test helpers (#30977)

Jasmine natively supports returning promises from spec functions for
quite some time now. We don't need special async helpers.

PR Close #30977
This commit is contained in:
George Kalpakas 2019-06-24 15:04:07 +03:00 committed by Alex Rickabaugh
parent 6c0cca093a
commit b6e8d19313
8 changed files with 117 additions and 188 deletions

View File

@ -1,28 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
function wrap(fn: () => Promise<void>): (done: DoneFn) => void {
return (done: DoneFn) => { fn().then(() => done()).catch(err => done.fail(err)); };
}
export function async_beforeAll(fn: () => Promise<void>): void {
beforeAll(wrap(fn));
}
export function async_beforeEach(fn: () => Promise<void>): void {
beforeEach(wrap(fn));
}
export function async_it(desc: string, fn: () => Promise<void>): void {
it(desc, wrap(fn));
}
export function async_fit(desc: string, fn: () => Promise<void>): void {
// tslint:disable-next-line:no-jasmine-focus
fit(desc, wrap(fn));
}

View File

@ -14,8 +14,6 @@ import {SwPush} from '@angular/service-worker/src/push';
import {SwUpdate} from '@angular/service-worker/src/update';
import {MockPushManager, MockPushSubscription, MockServiceWorkerContainer, MockServiceWorkerRegistration, patchDecodeBase64} from '@angular/service-worker/testing/mock';
import {async_fit, async_it} from './async';
{
describe('ServiceWorker library', () => {
let mock: MockServiceWorkerContainer;
@ -160,7 +158,7 @@ import {async_fit, async_it} from './async';
});
describe('requestSubscription()', () => {
async_it('returns a promise that resolves to the subscription', async() => {
it('returns a promise that resolves to the subscription', async() => {
const promise = push.requestSubscription({serverPublicKey: 'test'});
expect(promise).toEqual(jasmine.any(Promise));
@ -168,7 +166,7 @@ import {async_fit, async_it} from './async';
expect(sub).toEqual(jasmine.any(MockPushSubscription));
});
async_it('calls `PushManager.subscribe()` (with appropriate options)', async() => {
it('calls `PushManager.subscribe()` (with appropriate options)', async() => {
const decode = (charCodeArr: Uint8Array) =>
Array.from(charCodeArr).map(c => String.fromCharCode(c)).join('');
@ -190,7 +188,7 @@ import {async_fit, async_it} from './async';
expect(actualAppServerKeyStr).toBe(appServerKeyStr);
});
async_it('emits the new `PushSubscription` on `SwPush.subscription`', async() => {
it('emits the new `PushSubscription` on `SwPush.subscription`', async() => {
const subscriptionSpy = jasmine.createSpy('subscriptionSpy');
push.subscription.subscribe(subscriptionSpy);
const sub = await push.requestSubscription({serverPublicKey: 'test'});
@ -206,7 +204,7 @@ import {async_fit, async_it} from './async';
psUnsubscribeSpy = spyOn(MockPushSubscription.prototype, 'unsubscribe').and.callThrough();
});
async_it('rejects if currently not subscribed to push notifications', async() => {
it('rejects if currently not subscribed to push notifications', async() => {
try {
await push.unsubscribe();
throw new Error('`unsubscribe()` should fail');
@ -215,14 +213,14 @@ import {async_fit, async_it} from './async';
}
});
async_it('calls `PushSubscription.unsubscribe()`', async() => {
it('calls `PushSubscription.unsubscribe()`', async() => {
await push.requestSubscription({serverPublicKey: 'test'});
await push.unsubscribe();
expect(psUnsubscribeSpy).toHaveBeenCalledTimes(1);
});
async_it('rejects if `PushSubscription.unsubscribe()` fails', async() => {
it('rejects if `PushSubscription.unsubscribe()` fails', async() => {
psUnsubscribeSpy.and.callFake(() => { throw new Error('foo'); });
try {
@ -234,7 +232,7 @@ import {async_fit, async_it} from './async';
}
});
async_it('rejects if `PushSubscription.unsubscribe()` returns false', async() => {
it('rejects if `PushSubscription.unsubscribe()` returns false', async() => {
psUnsubscribeSpy.and.returnValue(Promise.resolve(false));
try {
@ -246,7 +244,7 @@ import {async_fit, async_it} from './async';
}
});
async_it('emits `null` on `SwPush.subscription`', async() => {
it('emits `null` on `SwPush.subscription`', async() => {
const subscriptionSpy = jasmine.createSpy('subscriptionSpy');
push.subscription.subscribe(subscriptionSpy);
@ -256,7 +254,7 @@ import {async_fit, async_it} from './async';
expect(subscriptionSpy).toHaveBeenCalledWith(null);
});
async_it('does not emit on `SwPush.subscription` on failure', async() => {
it('does not emit on `SwPush.subscription` on failure', async() => {
const subscriptionSpy = jasmine.createSpy('subscriptionSpy');
const initialSubEmit = new Promise(resolve => subscriptionSpy.and.callFake(resolve));
@ -340,7 +338,7 @@ import {async_fit, async_it} from './async';
push.subscription.subscribe(subscriptionSpy);
});
async_it('emits on worker-driven changes (i.e. when the controller changes)', async() => {
it('emits on worker-driven changes (i.e. when the controller changes)', async() => {
// Initial emit for the current `ServiceWorkerController`.
await nextSubEmitPromise;
expect(subscriptionSpy).toHaveBeenCalledTimes(1);
@ -355,7 +353,7 @@ import {async_fit, async_it} from './async';
expect(subscriptionSpy).toHaveBeenCalledWith(null);
});
async_it('emits on subscription changes (i.e. when subscribing/unsubscribing)', async() => {
it('emits on subscription changes (i.e. when subscribing/unsubscribing)', async() => {
await nextSubEmitPromise;
subscriptionSpy.calls.reset();

View File

@ -19,8 +19,6 @@ import {SwTestHarness, SwTestHarnessBuilder} from '@angular/service-worker/worke
import {Observable} from 'rxjs';
import {take} from 'rxjs/operators';
import {async_beforeEach, async_fit, async_it} from './async';
(function() {
// Skip environments that don't support the minimum APIs needed to run the SW tests.
if (!SwTestHarness.envIsSupported()) {
@ -80,7 +78,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
let scope: SwTestHarness;
let driver: Driver;
async_beforeEach(async() => {
beforeEach(async() => {
// Fire up the client.
mock = new MockServiceWorkerContainer();
comm = new NgswCommChannel(mock as any);
@ -100,12 +98,12 @@ import {async_beforeEach, async_fit, async_it} from './async';
await driver.initialized;
});
async_it('communicates back and forth via update check', async() => {
it('communicates back and forth via update check', async() => {
const update = new SwUpdate(comm);
await update.checkForUpdate();
});
async_it('detects an actual update', async() => {
it('detects an actual update', async() => {
const update = new SwUpdate(comm);
scope.updateServerState(serverUpdate);
@ -116,7 +114,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
await gotUpdateNotice;
});
async_it('receives push message notifications', async() => {
it('receives push message notifications', async() => {
const push = new SwPush(comm);
scope.updateServerState(serverUpdate);
@ -133,7 +131,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
await gotPushNotice;
});
async_it('receives push message click events', async() => {
it('receives push message click events', async() => {
const push = new SwPush(comm);
scope.updateServerState(serverUpdate);
@ -147,4 +145,4 @@ import {async_beforeEach, async_fit, async_it} from './async';
await gotNotificationClick;
});
});
})();
})();

View File

@ -1,28 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
function wrap(fn: () => Promise<void>): (done: DoneFn) => void {
return (done: DoneFn) => { fn().then(() => done()).catch(err => done.fail(err)); };
}
export function async_beforeAll(fn: () => Promise<void>): void {
beforeAll(wrap(fn));
}
export function async_beforeEach(fn: () => Promise<void>): void {
beforeEach(wrap(fn));
}
export function async_it(desc: string, fn: () => Promise<void>): void {
it(desc, wrap(fn));
}
export function async_fit(desc: string, fn: () => Promise<void>): void {
// tslint:disable-next-line:no-jasmine-focus
fit(desc, wrap(fn));
}

View File

@ -13,8 +13,6 @@ import {MockRequest} from '../testing/fetch';
import {MockFileSystemBuilder, MockServerStateBuilder, tmpHashTableForFs} from '../testing/mock';
import {SwTestHarness, SwTestHarnessBuilder} from '../testing/scope';
import {async_beforeEach, async_fit, async_it} from './async';
(function() {
// Skip environments that don't support the minimum APIs needed to run the SW tests.
if (!SwTestHarness.envIsSupported()) {
@ -122,7 +120,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
describe('data cache', () => {
let scope: SwTestHarness;
let driver: Driver;
async_beforeEach(async() => {
beforeEach(async() => {
server.clearRequests();
scope = new SwTestHarnessBuilder().withServerState(server).build();
driver = new Driver(scope, scope, new CacheDatabase(scope, scope));
@ -135,13 +133,13 @@ import {async_beforeEach, async_fit, async_it} from './async';
});
describe('in performance mode', () => {
async_it('names the caches correctly', async() => {
it('names the caches correctly', async() => {
expect(await makeRequest(scope, '/api/test')).toEqual('version 1');
const keys = await scope.caches.keys();
expect(keys.every(key => key.startsWith('ngsw:/:'))).toEqual(true);
});
async_it('caches a basic request', async() => {
it('caches a basic request', async() => {
expect(await makeRequest(scope, '/api/test')).toEqual('version 1');
server.assertSawRequestFor('/api/test');
scope.advance(1000);
@ -149,7 +147,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
server.assertNoOtherRequests();
});
async_it('refreshes after awhile', async() => {
it('refreshes after awhile', async() => {
expect(await makeRequest(scope, '/api/test')).toEqual('version 1');
server.clearRequests();
scope.advance(10000);
@ -157,7 +155,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
expect(await makeRequest(scope, '/api/test')).toEqual('version 2');
});
async_it('expires the least recently used entry', async() => {
it('expires the least recently used entry', async() => {
expect(await makeRequest(scope, '/api/a')).toEqual('version A');
expect(await makeRequest(scope, '/api/b')).toEqual('version B');
expect(await makeRequest(scope, '/api/c')).toEqual('version C');
@ -175,7 +173,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
server.assertNoOtherRequests();
});
async_it('does not carry over cache with new version', async() => {
it('does not carry over cache with new version', async() => {
expect(await makeRequest(scope, '/api/test')).toEqual('version 1');
scope.updateServerState(serverSeqUpdate);
expect(await driver.checkForUpdate()).toEqual(true);
@ -185,7 +183,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
});
describe('in freshness mode', () => {
async_it('goes to the server first', async() => {
it('goes to the server first', async() => {
expect(await makeRequest(scope, '/fresh/data')).toEqual('this is fresh data');
server.assertSawRequestFor('/fresh/data');
server.clearRequests();
@ -198,7 +196,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
serverUpdate.assertNoOtherRequests();
});
async_it('falls back on the cache when server times out', async() => {
it('falls back on the cache when server times out', async() => {
expect(await makeRequest(scope, '/fresh/data')).toEqual('this is fresh data');
server.assertSawRequestFor('/fresh/data');
server.clearRequests();
@ -225,7 +223,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
expect(await res2).toEqual('this is fresher data');
});
async_it('refreshes ahead', async() => {
it('refreshes ahead', async() => {
server.assertNoOtherRequests();
serverUpdate.assertNoOtherRequests();
expect(await makeRequest(scope, '/refresh/data')).toEqual('this is some data');

View File

@ -16,8 +16,6 @@ import {MockRequest} from '../testing/fetch';
import {MockFileSystemBuilder, MockServerStateBuilder, tmpHashTableForFs} from '../testing/mock';
import {SwTestHarness, SwTestHarnessBuilder} from '../testing/scope';
import {async_beforeEach, async_fit, async_it} from './async';
(function() {
// Skip environments that don't support the minimum APIs needed to run the SW tests.
if (!SwTestHarness.envIsSupported()) {
@ -248,19 +246,19 @@ import {async_beforeEach, async_fit, async_it} from './async';
driver = new Driver(scope, scope, new CacheDatabase(scope, scope));
});
async_it('activates without waiting', async() => {
it('activates without waiting', async() => {
const skippedWaiting = await scope.startup(true);
expect(skippedWaiting).toBe(true);
});
async_it('claims all clients, after activation', async() => {
it('claims all clients, after activation', async() => {
const claimSpy = spyOn(scope.clients, 'claim');
await scope.startup(true);
expect(claimSpy).toHaveBeenCalledTimes(1);
});
async_it('cleans up old `@angular/service-worker` caches, after activation', async() => {
it('cleans up old `@angular/service-worker` caches, after activation', async() => {
const claimSpy = spyOn(scope.clients, 'claim');
const cleanupOldSwCachesSpy = spyOn(driver, 'cleanupOldSwCaches');
@ -274,24 +272,23 @@ import {async_beforeEach, async_fit, async_it} from './async';
expect(claimSpy).toHaveBeenCalledBefore(cleanupOldSwCachesSpy);
});
async_it(
'does not blow up if cleaning up old `@angular/service-worker` caches fails', async() => {
spyOn(driver, 'cleanupOldSwCaches').and.callFake(() => Promise.reject('Ooops'));
it('does not blow up if cleaning up old `@angular/service-worker` caches fails', async() => {
spyOn(driver, 'cleanupOldSwCaches').and.callFake(() => Promise.reject('Ooops'));
// Automatically advance time to trigger idle tasks as they are added.
scope.autoAdvanceTime = true;
await scope.startup(true);
await scope.resolveSelfMessages();
scope.autoAdvanceTime = false;
// Automatically advance time to trigger idle tasks as they are added.
scope.autoAdvanceTime = true;
await scope.startup(true);
await scope.resolveSelfMessages();
scope.autoAdvanceTime = false;
server.clearRequests();
server.clearRequests();
expect(driver.state).toBe(DriverReadyState.NORMAL);
expect(await makeRequest(scope, '/foo.txt')).toBe('this is foo');
server.assertNoOtherRequests();
});
expect(driver.state).toBe(DriverReadyState.NORMAL);
expect(await makeRequest(scope, '/foo.txt')).toBe('this is foo');
server.assertNoOtherRequests();
});
async_it('initializes prefetched content correctly, after activation', async() => {
it('initializes prefetched content correctly, after activation', async() => {
// Automatically advance time to trigger idle tasks as they are added.
scope.autoAdvanceTime = true;
await scope.startup(true);
@ -307,7 +304,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
server.assertNoOtherRequests();
});
async_it('initializes prefetched content correctly, after a request kicks it off', async() => {
it('initializes prefetched content correctly, after a request kicks it off', async() => {
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');
await driver.initialized;
server.assertSawRequestFor('ngsw.json');
@ -319,7 +316,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
server.assertNoOtherRequests();
});
async_it('handles non-relative URLs', async() => {
it('handles non-relative URLs', async() => {
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');
await driver.initialized;
server.clearRequests();
@ -327,7 +324,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
server.assertNoOtherRequests();
});
async_it('handles actual errors from the browser', async() => {
it('handles actual errors from the browser', async() => {
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');
await driver.initialized;
server.clearRequests();
@ -339,7 +336,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
expect(res.statusText).toEqual('Gateway Timeout');
});
async_it('handles redirected responses', async() => {
it('handles redirected responses', async() => {
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');
await driver.initialized;
server.clearRequests();
@ -347,7 +344,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
server.assertNoOtherRequests();
});
async_it('caches lazy content on-request', async() => {
it('caches lazy content on-request', async() => {
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');
await driver.initialized;
server.clearRequests();
@ -361,7 +358,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
server.assertNoOtherRequests();
});
async_it('updates to new content when requested', async() => {
it('updates to new content when requested', async() => {
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');
await driver.initialized;
@ -394,7 +391,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
serverUpdate.assertNoOtherRequests();
});
async_it('detects new version even if only `manifest.timestamp` is different', async() => {
it('detects new version even if only `manifest.timestamp` is different', async() => {
expect(await makeRequest(scope, '/foo.txt', 'newClient')).toEqual('this is foo');
await driver.initialized;
@ -407,7 +404,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
expect(await makeRequest(scope, '/foo.txt', 'newestClient')).toEqual('this is foo');
});
async_it('updates a specific client to new content on request', async() => {
it('updates a specific client to new content on request', async() => {
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');
await driver.initialized;
@ -435,7 +432,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo v2');
});
async_it('handles empty client ID', async() => {
it('handles empty client ID', async() => {
const navRequest = (url: string, clientId: string | null) =>
makeRequest(scope, url, clientId, {
headers: {Accept: 'text/plain, text/html, text/css'},
@ -456,7 +453,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
expect(await navRequest('/bar/file2', null)).toEqual('this is foo v2');
});
async_it('checks for updates on restart', async() => {
it('checks for updates on restart', async() => {
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');
await driver.initialized;
@ -478,7 +475,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
serverUpdate.assertNoOtherRequests();
});
async_it('checks for updates on navigation', async() => {
it('checks for updates on navigation', async() => {
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');
await driver.initialized;
server.clearRequests();
@ -493,7 +490,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
server.assertSawRequestFor('ngsw.json');
});
async_it('does not make concurrent checks for updates on navigation', async() => {
it('does not make concurrent checks for updates on navigation', async() => {
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');
await driver.initialized;
server.clearRequests();
@ -513,7 +510,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
server.assertNoOtherRequests();
});
async_it('preserves multiple client assignments across restarts', async() => {
it('preserves multiple client assignments across restarts', async() => {
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');
await driver.initialized;
@ -533,7 +530,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
serverUpdate.assertNoOtherRequests();
});
async_it('updates when refreshed', async() => {
it('updates when refreshed', async() => {
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');
await driver.initialized;
@ -565,7 +562,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
serverUpdate.assertNoOtherRequests();
});
async_it('cleans up properly when manually requested', async() => {
it('cleans up properly when manually requested', async() => {
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');
await driver.initialized;
@ -585,7 +582,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
serverUpdate.assertNoOtherRequests();
});
async_it('cleans up properly on restart', async() => {
it('cleans up properly on restart', async() => {
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');
await driver.initialized;
@ -616,7 +613,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
expect(hasOriginalCaches).toEqual(false);
});
async_it('shows notifications for push notifications', async() => {
it('shows notifications for push notifications', async() => {
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');
await driver.initialized;
await scope.handlePush({
@ -640,7 +637,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
}]);
});
async_it('broadcasts notification click events with action', async() => {
it('broadcasts notification click events with action', async() => {
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');
await driver.initialized;
await scope.handleClick(
@ -653,7 +650,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
expect(message.data.notification.body).toEqual('Test body with action');
});
async_it('broadcasts notification click events without action', async() => {
it('broadcasts notification click events without action', async() => {
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');
await driver.initialized;
await scope.handleClick(
@ -666,7 +663,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
expect(message.data.notification.body).toEqual('Test body without action');
});
async_it('prefetches updates to lazy cache when set', async() => {
it('prefetches updates to lazy cache when set', async() => {
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');
await driver.initialized;
@ -711,7 +708,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
serverUpdate.assertNoOtherRequests();
});
async_it('should bypass serviceworker on ngsw-bypass parameter', async() => {
it('should bypass serviceworker on ngsw-bypass parameter', async() => {
await makeRequest(scope, '/foo.txt', undefined, {headers: {'ngsw-bypass': 'true'}});
server.assertNoRequestFor('/foo.txt');
@ -779,7 +776,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
});
async_it('unregisters when manifest 404s', async() => {
it('unregisters when manifest 404s', async() => {
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');
await driver.initialized;
@ -789,7 +786,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
expect(await scope.caches.keys()).toEqual([]);
});
async_it('does not unregister or change state when offline (i.e. manifest 504s)', async() => {
it('does not unregister or change state when offline (i.e. manifest 504s)', async() => {
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');
await driver.initialized;
server.online = false;
@ -834,7 +831,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
return newScope;
};
async_it('includes the SW scope in all cache names', async() => {
it('includes the SW scope in all cache names', async() => {
// Default SW with scope `/`.
await makeRequest(scope, '/foo.txt');
await driver.initialized;
@ -851,7 +848,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
expect(fooCacheNames.every(name => name.includes('/foo/'))).toBe(true);
});
async_it('does not affect caches from other scopes', async() => {
it('does not affect caches from other scopes', async() => {
// Create SW with scope `/foo/`.
const fooScope = await initializeSwFor('/foo/');
const fooAssignments = await getClientAssignments(fooScope, '/foo/');
@ -874,7 +871,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
expect(fooAssignments2).toEqual({_foo_: manifestHash});
});
async_it('updates existing caches for same scope', async() => {
it('updates existing caches for same scope', async() => {
// Create SW with scope `/foo/`.
const fooScope = await initializeSwFor('/foo/');
await makeRequest(fooScope, '/foo.txt', '_bar_');
@ -910,27 +907,27 @@ import {async_beforeEach, async_fit, async_it} from './async';
});
describe('unhashed requests', () => {
async_beforeEach(async() => {
beforeEach(async() => {
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');
await driver.initialized;
server.clearRequests();
});
async_it('are cached appropriately', async() => {
it('are cached appropriately', async() => {
expect(await makeRequest(scope, '/unhashed/a.txt')).toEqual('this is unhashed');
server.assertSawRequestFor('/unhashed/a.txt');
expect(await makeRequest(scope, '/unhashed/a.txt')).toEqual('this is unhashed');
server.assertNoOtherRequests();
});
async_it(`doesn't error when 'Cache-Control' is 'no-cache'`, async() => {
it(`doesn't error when 'Cache-Control' is 'no-cache'`, async() => {
expect(await makeRequest(scope, '/unhashed/b.txt')).toEqual('this is unhashed b');
server.assertSawRequestFor('/unhashed/b.txt');
expect(await makeRequest(scope, '/unhashed/b.txt')).toEqual('this is unhashed b');
server.assertNoOtherRequests();
});
async_it('avoid opaque responses', async() => {
it('avoid opaque responses', async() => {
expect(await makeRequest(scope, '/unhashed/a.txt', 'default', {
credentials: 'include'
})).toEqual('this is unhashed');
@ -939,7 +936,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
server.assertNoOtherRequests();
});
async_it('expire according to Cache-Control headers', async() => {
it('expire according to Cache-Control headers', async() => {
expect(await makeRequest(scope, '/unhashed/a.txt')).toEqual('this is unhashed');
server.clearRequests();
@ -962,7 +959,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
server.assertNoOtherRequests();
});
async_it('survive serialization', async() => {
it('survive serialization', async() => {
expect(await makeRequest(scope, '/unhashed/a.txt')).toEqual('this is unhashed');
server.clearRequests();
@ -985,7 +982,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
server.assertNoRequestFor('/unhashed/a.txt');
});
async_it('get carried over during updates', async() => {
it('get carried over during updates', async() => {
expect(await makeRequest(scope, '/unhashed/a.txt')).toEqual('this is unhashed');
server.clearRequests();
@ -1020,28 +1017,28 @@ import {async_beforeEach, async_fit, async_it} from './async';
mode: 'navigate', ...init,
});
async_beforeEach(async() => {
beforeEach(async() => {
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');
await driver.initialized;
server.clearRequests();
});
async_it('redirects to index on a route-like request', async() => {
it('redirects to index on a route-like request', async() => {
expect(await navRequest('/baz')).toEqual('this is foo');
server.assertNoOtherRequests();
});
async_it('redirects to index on a request to the origin URL request', async() => {
it('redirects to index on a request to the origin URL request', async() => {
expect(await navRequest('http://localhost/')).toEqual('this is foo');
server.assertNoOtherRequests();
});
async_it('does not redirect to index on a non-navigation request', async() => {
it('does not redirect to index on a non-navigation request', async() => {
expect(await navRequest('/baz', {mode: undefined})).toBeNull();
server.assertSawRequestFor('/baz');
});
async_it('does not redirect to index on a request that does not accept HTML', async() => {
it('does not redirect to index on a request that does not accept HTML', async() => {
expect(await navRequest('/baz', {headers: {}})).toBeNull();
server.assertSawRequestFor('/baz');
@ -1049,7 +1046,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
server.assertSawRequestFor('/qux');
});
async_it('does not redirect to index on a request with an extension', async() => {
it('does not redirect to index on a request with an extension', async() => {
expect(await navRequest('/baz.html')).toBeNull();
server.assertSawRequestFor('/baz.html');
@ -1058,7 +1055,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
server.assertNoOtherRequests();
});
async_it('does not redirect to index if the URL contains `__`', async() => {
it('does not redirect to index if the URL contains `__`', async() => {
expect(await navRequest('/baz/x__x')).toBeNull();
server.assertSawRequestFor('/baz/x__x');
@ -1073,13 +1070,13 @@ import {async_beforeEach, async_fit, async_it} from './async';
});
describe('(with custom `navigationUrls`)', () => {
async_beforeEach(async() => {
beforeEach(async() => {
scope.updateServerState(serverUpdate);
await driver.checkForUpdate();
serverUpdate.clearRequests();
});
async_it('redirects to index on a request that matches any positive pattern', async() => {
it('redirects to index on a request that matches any positive pattern', async() => {
expect(await navRequest('/foo/file0')).toBeNull();
serverUpdate.assertSawRequestFor('/foo/file0');
@ -1090,21 +1087,19 @@ import {async_beforeEach, async_fit, async_it} from './async';
serverUpdate.assertNoOtherRequests();
});
async_it(
'does not redirect to index on a request that matches any negative pattern',
async() => {
expect(await navRequest('/ignored/file1')).toBe('this is not handled by the SW');
serverUpdate.assertSawRequestFor('/ignored/file1');
it('does not redirect to index on a request that matches any negative pattern', async() => {
expect(await navRequest('/ignored/file1')).toBe('this is not handled by the SW');
serverUpdate.assertSawRequestFor('/ignored/file1');
expect(await navRequest('/ignored/dir/file2'))
.toBe('this is not handled by the SW either');
serverUpdate.assertSawRequestFor('/ignored/dir/file2');
expect(await navRequest('/ignored/dir/file2'))
.toBe('this is not handled by the SW either');
serverUpdate.assertSawRequestFor('/ignored/dir/file2');
expect(await navRequest('/ignored/directory/file2')).toBe('this is foo v2');
serverUpdate.assertNoOtherRequests();
});
expect(await navRequest('/ignored/directory/file2')).toBe('this is foo v2');
serverUpdate.assertNoOtherRequests();
});
async_it('strips URL query before checking `navigationUrls`', async() => {
it('strips URL query before checking `navigationUrls`', async() => {
expect(await navRequest('/foo/file1?query=/a/b')).toBe('this is foo v2');
serverUpdate.assertNoOtherRequests();
@ -1117,7 +1112,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
serverUpdate.assertSawRequestFor('/ignored/dir/file2');
});
async_it('strips registration scope before checking `navigationUrls`', async() => {
it('strips registration scope before checking `navigationUrls`', async() => {
expect(await navRequest('http://localhost/ignored/file1'))
.toBe('this is not handled by the SW');
serverUpdate.assertSawRequestFor('/ignored/file1');
@ -1126,7 +1121,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
});
describe('cleanupOldSwCaches()', () => {
async_it('should delete the correct caches', async() => {
it('should delete the correct caches', async() => {
const oldSwCacheNames = [
// Example cache names from the beta versions of `@angular/service-worker`.
'ngsw:active',
@ -1152,7 +1147,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
expect(await scope.caches.keys()).toEqual(otherCacheNames);
});
async_it('should delete other caches even if deleting one of them fails', async() => {
it('should delete other caches even if deleting one of them fails', async() => {
const oldSwCacheNames = ['ngsw:active', 'ngsw:staged', 'ngsw:manifest:a1b2c3:super:duper'];
const deleteSpy = spyOn(scope.caches, 'delete')
.and.callFake(
@ -1169,7 +1164,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
});
describe('bugs', () => {
async_it('does not crash with bad index hash', async() => {
it('does not crash with bad index hash', async() => {
scope = new SwTestHarnessBuilder().withServerState(brokenServer).build();
(scope.registration as any).scope = 'http://site.com';
driver = new Driver(scope, scope, new CacheDatabase(scope, scope));
@ -1177,7 +1172,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');
});
async_it('enters degraded mode when update has a bad index', async() => {
it('enters degraded mode when update has a bad index', async() => {
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');
await driver.initialized;
server.clearRequests();
@ -1195,7 +1190,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
expect(driver.state).toEqual(DriverReadyState.EXISTING_CLIENTS_ONLY);
});
async_it('enters degraded mode when failing to write to cache', async() => {
it('enters degraded mode when failing to write to cache', async() => {
// Initialize the SW.
await makeRequest(scope, '/foo.txt');
await driver.initialized;
@ -1217,7 +1212,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
server.assertSawRequestFor('/foo.txt');
});
async_it('ignores invalid `only-if-cached` requests ', async() => {
it('ignores invalid `only-if-cached` requests ', async() => {
const requestFoo = (cache: RequestCache | 'only-if-cached', mode: RequestMode) =>
makeRequest(scope, '/foo.txt', undefined, {cache, mode});
@ -1226,7 +1221,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
expect(await requestFoo('only-if-cached', 'no-cors')).toBeNull();
});
async_it('ignores passive mixed content requests ', async() => {
it('ignores passive mixed content requests ', async() => {
const scopeFetchSpy = spyOn(scope, 'fetch').and.callThrough();
const getRequestUrls = () => scopeFetchSpy.calls.allArgs().map(args => args[0].url);
@ -1270,14 +1265,13 @@ import {async_beforeEach, async_fit, async_it} from './async';
});
// Test this bug: https://github.com/angular/angular/issues/27209
async_it(
'Fill previous versions of manifests with default navigation urls for backwards compatibility',
async() => {
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');
await driver.initialized;
scope.updateServerState(serverUpdate);
expect(await driver.checkForUpdate()).toEqual(true);
});
it('Fill previous versions of manifests with default navigation urls for backwards compatibility',
async() => {
expect(await makeRequest(scope, '/foo.txt')).toEqual('this is foo');
await driver.initialized;
scope.updateServerState(serverUpdate);
expect(await driver.checkForUpdate()).toEqual(true);
});
});
});
});

View File

@ -8,7 +8,6 @@
import {IdleScheduler} from '../src/idle';
import {SwTestHarness, SwTestHarnessBuilder} from '../testing/scope';
import {async_beforeEach, async_fit, async_it} from './async';
(function() {
// Skip environments that don't support the minimum APIs needed to run the SW tests.
@ -29,7 +28,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
// Validate that a single idle task executes when trigger()
// is called and the idle timeout passes.
async_it('executes scheduled work on time', async() => {
it('executes scheduled work on time', async() => {
// Set up a single idle task to set the completed flag to true when it runs.
let completed: boolean = false;
idle.schedule('work', async() => { completed = true; });
@ -53,7 +52,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
expect(completed).toEqual(true);
});
async_it('waits for multiple tasks to complete serially', async() => {
it('waits for multiple tasks to complete serially', async() => {
// Schedule several tasks that will increase a counter according to its
// current value. If these tasks execute in parallel, the writes to the counter
// will race, and the test will fail.
@ -93,7 +92,7 @@ import {async_beforeEach, async_fit, async_it} from './async';
// Validate that a single idle task does not execute until trigger() has been called
// and sufficient time passes without it being called again.
async_it('does not execute work until timeout passes with no triggers', async() => {
it('does not execute work until timeout passes with no triggers', async() => {
// Set up a single idle task to set the completed flag to true when it runs.
let completed: boolean = false;
idle.schedule('work', async() => { completed = true; });

View File

@ -12,8 +12,6 @@ import {IdleScheduler} from '../src/idle';
import {MockFileSystemBuilder, MockServerStateBuilder, tmpHashTable, tmpManifestSingleAssetGroup} from '../testing/mock';
import {SwTestHarness, SwTestHarnessBuilder} from '../testing/scope';
import {async_fit, async_it} from './async';
(function() {
// Skip environments that don't support the minimum APIs needed to run the SW tests.
if (!SwTestHarness.envIsSupported()) {
@ -44,8 +42,8 @@ import {async_fit, async_it} from './async';
group = new PrefetchAssetGroup(
scope, scope, idle, manifest.assetGroups ![0], tmpHashTable(manifest), db, 'test');
});
async_it('initializes without crashing', async() => { await group.initializeFully(); });
async_it('fully caches the two files', async() => {
it('initializes without crashing', async() => { await group.initializeFully(); });
it('fully caches the two files', async() => {
await group.initializeFully();
scope.updateServerState();
const res1 = await group.handleFetch(scope.newRequest('/foo.txt'), scope);
@ -53,7 +51,7 @@ import {async_fit, async_it} from './async';
expect(await res1 !.text()).toEqual('this is foo');
expect(await res2 !.text()).toEqual('this is bar');
});
async_it('persists the cache across restarts', async() => {
it('persists the cache across restarts', async() => {
await group.initializeFully();
const freshScope =
new SwTestHarnessBuilder().withCacheState(scope.caches.dehydrate()).build();
@ -66,7 +64,7 @@ import {async_fit, async_it} from './async';
expect(await res1 !.text()).toEqual('this is foo');
expect(await res2 !.text()).toEqual('this is bar');
});
async_it('caches properly if resources are requested before initialization', async() => {
it('caches properly if resources are requested before initialization', async() => {
const res1 = await group.handleFetch(scope.newRequest('/foo.txt'), scope);
const res2 = await group.handleFetch(scope.newRequest('/bar.txt'), scope);
expect(await res1 !.text()).toEqual('this is foo');
@ -74,7 +72,7 @@ import {async_fit, async_it} from './async';
scope.updateServerState();
await group.initializeFully();
});
async_it('throws if the server-side content does not match the manifest hash', async() => {
it('throws if the server-side content does not match the manifest hash', async() => {
const badHashFs = dist.extend().addFile('/foo.txt', 'corrupted file').build();
const badServer =
new MockServerStateBuilder().withManifest(manifest).withStaticFiles(badHashFs).build();