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

chore: added worker support #163

Merged
merged 11 commits into from
May 30, 2023
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
.reports
*.log
dist
ponyfill.bundle.js
polyfill.bundle.js
*.bundle.js

# OSX
#
Expand Down
14 changes: 10 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
.PHONY: all
all: test lint typecheck

.PHONY: browser
browser:
@./bin/server --exec "npx open-cli http://127.0.0.1:8000/test/fetch-api/browser/"

.PHONY: clean
clean:
@rm -Rf node_modules dist
Expand All @@ -21,6 +17,9 @@ release:
release-alpha:
npx standard-version --prerelease alpha

.PHONY: server
server:
@./bin/server --silent --exec "echo Fetch api test suites: http://127.0.0.1:8000/test/fetch-api/"

##
# Builds
Expand Down Expand Up @@ -79,6 +78,7 @@ test: | test-browser test-node
test-browser: |\
test-fetch-browser-native \
test-fetch-browser-whatwg \
test-fetch-browser-service-worker \
test-module-web-cjs \
test-module-web-esm \
test-module-react-native
Expand Down Expand Up @@ -106,6 +106,12 @@ test-fetch-browser-whatwg: | dist test/fetch-api/api.spec.js
@echo "=> make $@"
@./test/fetch-api/whatwg/run.sh

.PHONY: test-fetch-browser-service-worker
test-fetch-browser-service-worker: dist test/fetch-api/api.spec.js
@echo ""
@echo "=> make $@"
@./test/fetch-api/service-worker/run.sh

.PHONY: test-fetch-node-native
test-fetch-node-native: | dist test/fetch-api/api.spec.js
@echo ""
Expand Down
4 changes: 3 additions & 1 deletion bin/server
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ function processFileUrl (args) {
}

const server = app.listen(port, ip, () => {
console.log(`Test server listening at ${url}`)
if (!argv.silent) {
console.log(`Test server listening at ${url}`)
}

if (argv.exec) {
const args = processFileUrl(argv.exec.split(' '))
Expand Down
2 changes: 1 addition & 1 deletion examples/cloud-worker/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "cloud-worker",
"name": "cloud-worker-fix",
"version": "0.0.0",
"devDependencies": {
"wrangler": "2.19.0"
Expand Down
2 changes: 1 addition & 1 deletion examples/cloud-worker/wrangler.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
name = "cloud-worker"
name = "cloud-worker-fix"
main = "src/index.js"
compatibility_date = "2023-05-06"
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@
},
"standard": {
"env": [
"browser",
"mocha",
"browser"
"serviceworker"
],
"globals": [
"expect",
"assert",
"chai"
"chai",
"Mocha"
],
"ignore": [
"/dist/",
Expand Down Expand Up @@ -87,7 +89,6 @@
"mocha-headless-chrome": "4.0.0",
"nock": "13.3.0",
"nyc": "15.1.0",
"open-cli": "7.2.0",
"rimraf": "5.0.0",
"rollup": "3.20.7",
"rollup-plugin-copy": "3.4.0",
Expand Down
5 changes: 2 additions & 3 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default [
name: 'irrelevant',
strict: false,
banner: outdent(`
// Save the global object in a variable
// Save global object in a variable
var __global__ =
(typeof globalThis !== 'undefined' && globalThis) ||
(typeof self !== 'undefined' && self) ||
Expand Down Expand Up @@ -53,8 +53,7 @@ export default [
delete __globalThis__.fetch.polyfill;
// Choose between native implementation (__global__) or custom implementation (__globalThis__)
// var ctx = __global__.fetch ? __global__ : __globalThis__;
var ctx = __globalThis__ // this line disable service worker support temporarily
var ctx = __global__.fetch ? __global__ : __globalThis__;
exports = ctx.fetch // To enable: import fetch from 'cross-fetch'
exports.default = ctx.fetch // For TypeScript consumers without esModuleInterop.
Expand Down
21 changes: 14 additions & 7 deletions test/fetch-api/api.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -425,15 +425,21 @@ function addFetchSuite() {
it('should default to status 200 OK', () => {
const res = new Response();
expect(res.status).to.equal(200);
// expect(res.statusText).to.equal('OK')
expect(res.ok).to.equal(true);
});
it('should default to status 200 OK when an explicit undefined status code is passed', () => {
const res = new Response('', { status: undefined });
expect(res.status).to.equal(200);
// expect(res.statusText).to.equal('OK')
expect(res.ok).to.equal(true);
});
/**
* Implementation conflict!
*/
it.skip('should have statusText as empty', () => {
const res = new Response();
expect(res.statusText).to.equal(''); // Pass on browser native, node native, node-fetch 3+, whatwg-fetch 3.1+
expect(res.statusText).to.equal('OK'); // Pass on node-fetch 2.6.9, whatwg-fetch 3.0 (thus, react native)
});
it('should create Headers object from raw headers', () => {
const response = new Response('{"foo":"bar"}', {
headers: { 'content-type': 'application/json' }
Expand Down Expand Up @@ -530,18 +536,19 @@ function addFetchSuite() {
const headers = new Headers({ Custom: undefined });
expect(headers.get('Custom')).to.equal('undefined');
});
// Breaking change: This tests fails on Node 18+
/**
* Implementation conflict!
*/
it.skip('should throw TypeError on invalid character in field name', () => {
/* eslint-disable no-new */
expect(function () { new Headers({ '<Accept>': 'application/json' }); }).to.throw();
expect(function () { new Headers({ 'Accept:': 'application/json' }); }).to.throw();
expect(function () {
const headers = new Headers();
headers.set({ field: 'value' }, 'application/json');
}).to.throw();
// The expects below don't pass on Node 18+ but pass in the others implementations
expect(function () { new Headers({ '<Accept>': 'application/json' }); }).to.throw();
expect(function () { new Headers({ 'Accept:': 'application/json' }); }).to.throw();
});
it('should not init an invalid header', () => {
/* eslint-disable no-new */
expect(function () { new Headers({ Héy: 'ok' }); }).to.throw();
});
it('should not set an invalid header', () => {
Expand Down
23 changes: 16 additions & 7 deletions test/fetch-api/api.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -486,17 +486,24 @@ function addFetchSuite () {
it('should default to status 200 OK', () => {
const res = new Response()
expect(res.status).to.equal(200)
// expect(res.statusText).to.equal('OK')
expect(res.ok).to.equal(true)
})

it('should default to status 200 OK when an explicit undefined status code is passed', () => {
const res = new Response('', { status: undefined })
expect(res.status).to.equal(200)
// expect(res.statusText).to.equal('OK')
expect(res.ok).to.equal(true)
})

/**
* Implementation conflict!
*/
it.skip('should have statusText as empty', () => {
const res = new Response()
expect(res.statusText).to.equal('') // Pass on browser native, node native, node-fetch 3+, whatwg-fetch 3.1+
expect(res.statusText).to.equal('OK') // Pass on node-fetch 2.6.9, whatwg-fetch 3.0 (thus, react native)
})

it('should create Headers object from raw headers', () => {
const response = new Response('{"foo":"bar"}', {
headers: { 'content-type': 'application/json' }
Expand Down Expand Up @@ -614,19 +621,21 @@ function addFetchSuite () {
expect(headers.get('Custom')).to.equal('undefined')
})

// Breaking change: This tests fails on Node 18+
/**
* Implementation conflict!
*/
it.skip('should throw TypeError on invalid character in field name', () => {
/* eslint-disable no-new */
expect(function (): void { new Headers({ '<Accept>': 'application/json' }) }).to.throw()
expect(function (): void { new Headers({ 'Accept:': 'application/json' }) }).to.throw()
expect(function (): void {
const headers = new Headers()
headers.set({ field: 'value' } as any, 'application/json')
}).to.throw()

// The expects below don't pass on Node 18+ but pass in the others implementations
expect(function (): void { new Headers({ '<Accept>': 'application/json' }) }).to.throw()
expect(function (): void { new Headers({ 'Accept:': 'application/json' }) }).to.throw()
})

it('should not init an invalid header', () => {
/* eslint-disable no-new */
expect(function (): void { new Headers({ Héy: 'ok' }) }).to.throw()
})

Expand Down
2 changes: 1 addition & 1 deletion test/fetch-api/browser/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<script src="../../setup/browser.env.js"></script>
<script src="../api.spec.js"></script>
<script src="../../module-system/module.spec.js"></script>
<script src="../../../dist/cross-fetch.js"></script>
<!-- use native fetch -->

<script>
describe('Browser:Fetch:Native', () => {
Expand Down
43 changes: 43 additions & 0 deletions test/fetch-api/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<link href="../../../node_modules/mocha/mocha.css" rel="stylesheet" />
<style>
.links li:before {
content: "•";
font-size: 10px;
padding: 0 10px;
}

.links a {
color: #89cff0;
font-size: 16px;
font-weight: 200;
text-decoration: none;
}

.links a:hover {
text-decoration: underline;
}
</style>
</head>

<body>
<div id="mocha">
<h1>Fetch API Test Suites</h1>

<div class="suite">
<h1>Implementations</h1>

<ul class="links">
<li><a href="./browser/">browser</a></li>
<li><a href="./whatwg/">whatwg-fetch lib</a></li>
<li><a href="./service-worker/">service worker</a></li>
</ul>
</div>
</div>
</body>

</html>
37 changes: 37 additions & 0 deletions test/fetch-api/service-worker/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<link href="../../../node_modules/mocha/mocha.css" rel="stylesheet" />
</head>

<body>
<div id="mocha">
<h1>Please check console!</h1>
</div>

<script>
const registration = navigator.serviceWorker.register('/test/fetch-api/service-worker/sw.bundle.js', {
scope: '/test/fetch-api/service-worker/'
})
.catch(err => console.error(`Registration failed with ${error}`));

const logChannel = new BroadcastChannel('sw-logger');
logChannel.addEventListener('message', event => {
console.log(...event.data);
});

const resChannel = new BroadcastChannel('sw-result');
resChannel.addEventListener('message', event => {
window.__mochaResult__ = JSON.parse(event.data);

// Avoids manually unregister to see output in the console
registration
.then(reg => reg.unregister())
.catch(err => console.error(`Unregistration failed with ${error}`));
});
</script>
</body>

</html>
6 changes: 6 additions & 0 deletions test/fetch-api/service-worker/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh

. test/setup/server.sh

npx webpack --config $(dirname "$0")/webpack.config.js &&
npx mocha-headless-chrome -f http://127.0.0.1:8000/$(dirname $0)/index.html
32 changes: 32 additions & 0 deletions test/fetch-api/service-worker/sw.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/* eslint-disable no-undef */
import fetch, { Request, Response, Headers } from '../../..'

const logChannel = new BroadcastChannel('sw-logger')

// Redirect all logs to top window
console.log = (...args) => logChannel.postMessage(args)

importScripts('../../../node_modules/mocha/mocha.js')
importScripts('../../../node_modules/chai/chai.js')
importScripts('./sw.reporter.js')

importScripts('../api.spec.js')
importScripts('../../module-system/module.spec.js')

globalThis.expect = chai.expect
globalThis.fetch = fetch
globalThis.Request = Request
globalThis.Response = Response
globalThis.Headers = Headers

mocha.setup({
ui: 'bdd',
reporter: SWReporter
})

describe('Browser:Fetch:ServiceWorker', () => {
addFetchSuite()
addNativeSuite({ fetch })
})

mocha.run()
Loading