summaryrefslogtreecommitdiff
path: root/packages/integrations/image/test
diff options
context:
space:
mode:
Diffstat (limited to 'packages/integrations/image/test')
-rw-r--r--packages/integrations/image/test/fixtures/basic-image/package.json2
-rw-r--r--packages/integrations/image/test/fixtures/basic-image/src/pages/index.astro2
-rw-r--r--packages/integrations/image/test/fixtures/basic-picture/astro.config.mjs8
-rw-r--r--packages/integrations/image/test/fixtures/basic-picture/package.json10
-rw-r--r--packages/integrations/image/test/fixtures/basic-picture/public/favicon.icobin0 -> 4286 bytes
-rw-r--r--packages/integrations/image/test/fixtures/basic-picture/server/server.mjs44
-rw-r--r--packages/integrations/image/test/fixtures/basic-picture/src/assets/blog/introducing-astro.jpgbin0 -> 276382 bytes
-rw-r--r--packages/integrations/image/test/fixtures/basic-picture/src/assets/social.jpgbin0 -> 25266 bytes
-rw-r--r--packages/integrations/image/test/fixtures/basic-picture/src/assets/social.pngbin0 -> 1512228 bytes
-rw-r--r--packages/integrations/image/test/fixtures/basic-picture/src/pages/index.astro17
-rw-r--r--packages/integrations/image/test/image-ssg.test.js41
-rw-r--r--packages/integrations/image/test/image-ssr.test.js45
-rw-r--r--packages/integrations/image/test/picture-ssg.test.js263
-rw-r--r--packages/integrations/image/test/picture-ssr.test.js278
14 files changed, 707 insertions, 3 deletions
diff --git a/packages/integrations/image/test/fixtures/basic-image/package.json b/packages/integrations/image/test/fixtures/basic-image/package.json
index 42b4411a4..502e42c96 100644
--- a/packages/integrations/image/test/fixtures/basic-image/package.json
+++ b/packages/integrations/image/test/fixtures/basic-image/package.json
@@ -1,5 +1,5 @@
{
- "name": "@test/sharp",
+ "name": "@test/basic-image",
"version": "0.0.0",
"private": true,
"dependencies": {
diff --git a/packages/integrations/image/test/fixtures/basic-image/src/pages/index.astro b/packages/integrations/image/test/fixtures/basic-image/src/pages/index.astro
index 6ee02360b..34deda90e 100644
--- a/packages/integrations/image/test/fixtures/basic-image/src/pages/index.astro
+++ b/packages/integrations/image/test/fixtures/basic-image/src/pages/index.astro
@@ -12,6 +12,6 @@ import { Image } from '@astrojs/image';
<br />
<Image id="google" src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" width={544} height={184} format="webp" />
<br />
- <Image id='testing' src={import('../assets/social.jpg')} width={506} format="avif" />
+ <Image id='inline' src={import('../assets/social.jpg')} width={506} />
</body>
</html>
diff --git a/packages/integrations/image/test/fixtures/basic-picture/astro.config.mjs b/packages/integrations/image/test/fixtures/basic-picture/astro.config.mjs
new file mode 100644
index 000000000..45a11dc9d
--- /dev/null
+++ b/packages/integrations/image/test/fixtures/basic-picture/astro.config.mjs
@@ -0,0 +1,8 @@
+import { defineConfig } from 'astro/config';
+import image from '@astrojs/image';
+
+// https://astro.build/config
+export default defineConfig({
+ site: 'http://localhost:3000',
+ integrations: [image()]
+});
diff --git a/packages/integrations/image/test/fixtures/basic-picture/package.json b/packages/integrations/image/test/fixtures/basic-picture/package.json
new file mode 100644
index 000000000..23c91f009
--- /dev/null
+++ b/packages/integrations/image/test/fixtures/basic-picture/package.json
@@ -0,0 +1,10 @@
+{
+ "name": "@test/basic-picture",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "@astrojs/image": "workspace:*",
+ "@astrojs/node": "workspace:*",
+ "astro": "workspace:*"
+ }
+}
diff --git a/packages/integrations/image/test/fixtures/basic-picture/public/favicon.ico b/packages/integrations/image/test/fixtures/basic-picture/public/favicon.ico
new file mode 100644
index 000000000..578ad458b
--- /dev/null
+++ b/packages/integrations/image/test/fixtures/basic-picture/public/favicon.ico
Binary files differ
diff --git a/packages/integrations/image/test/fixtures/basic-picture/server/server.mjs b/packages/integrations/image/test/fixtures/basic-picture/server/server.mjs
new file mode 100644
index 000000000..d7a0a7a40
--- /dev/null
+++ b/packages/integrations/image/test/fixtures/basic-picture/server/server.mjs
@@ -0,0 +1,44 @@
+import { createServer } from 'http';
+import fs from 'fs';
+import mime from 'mime';
+import { handler as ssrHandler } from '../dist/server/entry.mjs';
+
+const clientRoot = new URL('../dist/client/', import.meta.url);
+
+async function handle(req, res) {
+ ssrHandler(req, res, async (err) => {
+ if (err) {
+ res.writeHead(500);
+ res.end(err.stack);
+ return;
+ }
+
+ let local = new URL('.' + req.url, clientRoot);
+ try {
+ const data = await fs.promises.readFile(local);
+ res.writeHead(200, {
+ 'Content-Type': mime.getType(req.url),
+ });
+ res.end(data);
+ } catch {
+ res.writeHead(404);
+ res.end();
+ }
+ });
+}
+
+const server = createServer((req, res) => {
+ handle(req, res).catch((err) => {
+ console.error(err);
+ res.writeHead(500, {
+ 'Content-Type': 'text/plain',
+ });
+ res.end(err.toString());
+ });
+});
+
+server.listen(8085);
+console.log('Serving at http://localhost:8085');
+
+// Silence weird <time> warning
+console.error = () => {};
diff --git a/packages/integrations/image/test/fixtures/basic-picture/src/assets/blog/introducing-astro.jpg b/packages/integrations/image/test/fixtures/basic-picture/src/assets/blog/introducing-astro.jpg
new file mode 100644
index 000000000..c58aacf66
--- /dev/null
+++ b/packages/integrations/image/test/fixtures/basic-picture/src/assets/blog/introducing-astro.jpg
Binary files differ
diff --git a/packages/integrations/image/test/fixtures/basic-picture/src/assets/social.jpg b/packages/integrations/image/test/fixtures/basic-picture/src/assets/social.jpg
new file mode 100644
index 000000000..906c76144
--- /dev/null
+++ b/packages/integrations/image/test/fixtures/basic-picture/src/assets/social.jpg
Binary files differ
diff --git a/packages/integrations/image/test/fixtures/basic-picture/src/assets/social.png b/packages/integrations/image/test/fixtures/basic-picture/src/assets/social.png
new file mode 100644
index 000000000..1399856f1
--- /dev/null
+++ b/packages/integrations/image/test/fixtures/basic-picture/src/assets/social.png
Binary files differ
diff --git a/packages/integrations/image/test/fixtures/basic-picture/src/pages/index.astro b/packages/integrations/image/test/fixtures/basic-picture/src/pages/index.astro
new file mode 100644
index 000000000..e3e0ade30
--- /dev/null
+++ b/packages/integrations/image/test/fixtures/basic-picture/src/pages/index.astro
@@ -0,0 +1,17 @@
+---
+import socialJpg from '../assets/social.jpg';
+import { Picture } from '@astrojs/image';
+---
+
+<html>
+ <head>
+ <!-- Head Stuff -->
+ </head>
+ <body>
+ <Picture id="social-jpg" src={socialJpg} sizes="(min-width: 640px) 50vw, 100vw" widths={[253, 506]} />
+ <br />
+ <Picture id="google" src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" sizes="(min-width: 640px) 50vw, 100vw" widths={[272, 544]} aspectRatio={544/184} />
+ <br />
+ <Picture id='inline' src={import('../assets/social.jpg')} sizes="(min-width: 640px) 50vw, 100vw" widths={[253, 506]} />
+ </body>
+</html>
diff --git a/packages/integrations/image/test/image-ssg.test.js b/packages/integrations/image/test/image-ssg.test.js
index 7df097d41..b314844b6 100644
--- a/packages/integrations/image/test/image-ssg.test.js
+++ b/packages/integrations/image/test/image-ssg.test.js
@@ -1,6 +1,5 @@
import { expect } from 'chai';
import * as cheerio from 'cheerio';
-import path from 'path';
import sizeOf from 'image-size';
import { fileURLToPath } from 'url';
import { loadFixture } from './test-utils.js';
@@ -38,6 +37,16 @@ describe('SSG images', function () {
expect(image.attr('width')).to.equal('506');
expect(image.attr('height')).to.equal('253');
});
+ });
+
+ describe('Inline imports', () => {
+ it ('includes src, width, and height attributes', () => {
+ const image = $('#inline');
+
+ expect(image.attr('src')).to.equal('/_image/assets/social_506x253.jpg');
+ expect(image.attr('width')).to.equal('506');
+ expect(image.attr('height')).to.equal('253');
+ });
it('built the optimized image', () => {
verifyImage('_image/assets/social_506x253.jpg', { width: 506, height: 253, type: 'jpg' });
@@ -111,6 +120,36 @@ describe('SSG images', function () {
});
});
+ describe('Local images with inline imports', () => {
+ it('includes src, width, and height attributes', () => {
+ const image = $('#inline');
+
+ const src = image.attr('src');
+ const [route, params] = src.split('?');
+
+ expect(route).to.equal('/_image');
+
+ const searchParams = new URLSearchParams(params);
+
+ expect(searchParams.get('f')).to.equal('jpg');
+ expect(searchParams.get('w')).to.equal('506');
+ expect(searchParams.get('h')).to.equal('253');
+ // TODO: possible to avoid encoding the full image path?
+ expect(searchParams.get('href').endsWith('/assets/social.jpg')).to.equal(true);
+ });
+
+ it('returns the optimized image', async () => {
+ const image = $('#inline');
+
+ const res = await fixture.fetch(image.attr('src'));
+
+ expect(res.status).to.equal(200);
+ expect(res.headers.get('Content-Type')).to.equal('image/jpeg');
+
+ // TODO: verify image file? It looks like sizeOf doesn't support ArrayBuffers
+ });
+ });
+
describe('Remote images', () => {
it('includes src, width, and height attributes', () => {
const image = $('#google');
diff --git a/packages/integrations/image/test/image-ssr.test.js b/packages/integrations/image/test/image-ssr.test.js
index 9881d090a..784a92e53 100644
--- a/packages/integrations/image/test/image-ssr.test.js
+++ b/packages/integrations/image/test/image-ssr.test.js
@@ -62,6 +62,32 @@ describe('SSR images - build', function () {
});
});
+ describe('Inline imports', () => {
+ it('includes src, width, and height attributes', async () => {
+ const app = await fixture.loadTestAdapterApp();
+
+ const request = new Request('http://example.com/');
+ const response = await app.render(request);
+ const html = await response.text();
+ const $ = cheerio.load(html);
+
+ const image = $('#inline');
+
+ const src = image.attr('src');
+ const [route, params] = src.split('?');
+
+ expect(route).to.equal('/_image');
+
+ const searchParams = new URLSearchParams(params);
+
+ expect(searchParams.get('f')).to.equal('jpg');
+ expect(searchParams.get('w')).to.equal('506');
+ expect(searchParams.get('h')).to.equal('253');
+ // TODO: possible to avoid encoding the full image path?
+ expect(searchParams.get('href').endsWith('/assets/social.jpg')).to.equal(true);
+ });
+ });
+
describe('Remote images', () => {
it('includes src, width, and height attributes', async () => {
const app = await fixture.loadTestAdapterApp();
@@ -142,6 +168,25 @@ describe('SSR images - dev', function () {
});
});
+ describe('Inline imports', () => {
+ it('includes src, width, and height attributes', () => {
+ const image = $('#inline');
+
+ const src = image.attr('src');
+ const [route, params] = src.split('?');
+
+ expect(route).to.equal('/_image');
+
+ const searchParams = new URLSearchParams(params);
+
+ expect(searchParams.get('f')).to.equal('jpg');
+ expect(searchParams.get('w')).to.equal('506');
+ expect(searchParams.get('h')).to.equal('253');
+ // TODO: possible to avoid encoding the full image path?
+ expect(searchParams.get('href').endsWith('/assets/social.jpg')).to.equal(true);
+ });
+ });
+
describe('Remote images', () => {
it('includes src, width, and height attributes', () => {
const image = $('#google');
diff --git a/packages/integrations/image/test/picture-ssg.test.js b/packages/integrations/image/test/picture-ssg.test.js
new file mode 100644
index 000000000..084c4d95b
--- /dev/null
+++ b/packages/integrations/image/test/picture-ssg.test.js
@@ -0,0 +1,263 @@
+import { expect } from 'chai';
+import * as cheerio from 'cheerio';
+import fs from 'fs';
+import sizeOf from 'image-size';
+import { fileURLToPath } from 'url';
+import { loadFixture } from './test-utils.js';
+
+let fixture;
+
+describe('SSG pictures', function () {
+ before(async () => {
+ fixture = await loadFixture({ root: './fixtures/basic-picture/' });
+ });
+
+ function verifyImage(pathname, expected) {
+ const url = new URL('./fixtures/basic-picture/dist/' + pathname, import.meta.url);
+ const dist = fileURLToPath(url);
+
+ // image-size doesn't support AVIF files
+ if (expected.type !== 'avif') {
+ const result = sizeOf(dist);
+ expect(result).to.deep.equal(expected);
+ } else {
+ expect(fs.statSync(dist)).not.to.be.undefined;
+ }
+ }
+
+ describe('build', () => {
+ let $;
+ let html;
+
+ before(async () => {
+ await fixture.build();
+
+ html = await fixture.readFile('/index.html');
+ $ = cheerio.load(html);
+ });
+
+ describe('Local images', () => {
+ it('includes sources', () => {
+ const sources = $('#social-jpg source');
+
+ expect(sources.length).to.equal(3);
+
+ // TODO: better coverage to verify source props
+ });
+
+ it('includes src, width, and height attributes', () => {
+ const image = $('#social-jpg img');
+
+ expect(image.attr('src')).to.equal('/_image/assets/social_506x253.jpg');
+ expect(image.attr('width')).to.equal('506');
+ expect(image.attr('height')).to.equal('253');
+ });
+
+ it('built the optimized image', () => {
+ verifyImage('_image/assets/social_253x127.avif', { width: 253, height: 127, type: 'avif' });
+ verifyImage('_image/assets/social_253x127.webp', { width: 253, height: 127, type: 'webp' });
+ verifyImage('_image/assets/social_253x127.jpg', { width: 253, height: 127, type: 'jpg' });
+ verifyImage('_image/assets/social_506x253.avif', { width: 506, height: 253, type: 'avif' });
+ verifyImage('_image/assets/social_506x253.webp', { width: 506, height: 253, type: 'webp' });
+ verifyImage('_image/assets/social_506x253.jpg', { width: 506, height: 253, type: 'jpg' });
+ });
+ });
+
+ describe('Inline imports', () => {
+ it('includes sources', () => {
+ const sources = $('#inline source');
+
+ expect(sources.length).to.equal(3);
+
+ // TODO: better coverage to verify source props
+ });
+
+ it('includes src, width, and height attributes', () => {
+ const image = $('#inline img');
+
+ expect(image.attr('src')).to.equal('/_image/assets/social_506x253.jpg');
+ expect(image.attr('width')).to.equal('506');
+ expect(image.attr('height')).to.equal('253');
+ });
+
+ it('built the optimized image', () => {
+ verifyImage('_image/assets/social_253x127.avif', { width: 253, height: 127, type: 'avif' });
+ verifyImage('_image/assets/social_253x127.webp', { width: 253, height: 127, type: 'webp' });
+ verifyImage('_image/assets/social_253x127.jpg', { width: 253, height: 127, type: 'jpg' });
+ verifyImage('_image/assets/social_506x253.avif', { width: 506, height: 253, type: 'avif' });
+ verifyImage('_image/assets/social_506x253.webp', { width: 506, height: 253, type: 'webp' });
+ verifyImage('_image/assets/social_506x253.jpg', { width: 506, height: 253, type: 'jpg' });
+ });
+ });
+
+ describe('Remote images', () => {
+ it('includes sources', () => {
+ const sources = $('#google source');
+
+ expect(sources.length).to.equal(3);
+
+ // TODO: better coverage to verify source props
+ });
+
+ it('includes src, width, and height attributes', () => {
+ const image = $('#google img');
+
+ expect(image.attr('src')).to.equal('/_image/googlelogo_color_272x92dp_544x184.png');
+ expect(image.attr('width')).to.equal('544');
+ expect(image.attr('height')).to.equal('184');
+ });
+
+ it('built the optimized image', () => {
+ verifyImage('_image/googlelogo_color_272x92dp_272x92.avif', {
+ width: 272,
+ height: 92,
+ type: 'avif',
+ });
+ verifyImage('_image/googlelogo_color_272x92dp_272x92.webp', {
+ width: 272,
+ height: 92,
+ type: 'webp',
+ });
+ verifyImage('_image/googlelogo_color_272x92dp_272x92.png', {
+ width: 272,
+ height: 92,
+ type: 'png',
+ });
+ verifyImage('_image/googlelogo_color_272x92dp_544x184.avif', {
+ width: 544,
+ height: 184,
+ type: 'avif',
+ });
+ verifyImage('_image/googlelogo_color_272x92dp_544x184.webp', {
+ width: 544,
+ height: 184,
+ type: 'webp',
+ });
+ verifyImage('_image/googlelogo_color_272x92dp_544x184.png', {
+ width: 544,
+ height: 184,
+ type: 'png',
+ });
+ });
+ });
+ });
+
+ describe('dev', () => {
+ let devServer;
+ let $;
+
+ before(async () => {
+ devServer = await fixture.startDevServer();
+ const html = await fixture.fetch('/').then((res) => res.text());
+ $ = cheerio.load(html);
+ });
+
+ after(async () => {
+ await devServer.stop();
+ });
+
+ describe('Local images', () => {
+ it('includes sources', () => {
+ const sources = $('#social-jpg source');
+
+ expect(sources.length).to.equal(3);
+
+ // TODO: better coverage to verify source props
+ });
+
+ it('includes src, width, and height attributes', () => {
+ const image = $('#social-jpg img');
+
+ const src = image.attr('src');
+ const [route, params] = src.split('?');
+
+ expect(route).to.equal('/_image');
+
+ const searchParams = new URLSearchParams(params);
+
+ expect(searchParams.get('f')).to.equal('jpg');
+ expect(searchParams.get('w')).to.equal('506');
+ expect(searchParams.get('h')).to.equal('253');
+ // TODO: possible to avoid encoding the full image path?
+ expect(searchParams.get('href').endsWith('/assets/social.jpg')).to.equal(true);
+ });
+
+ it('returns the optimized image', async () => {
+ const image = $('#social-jpg img');
+
+ const res = await fixture.fetch(image.attr('src'));
+
+ expect(res.status).to.equal(200);
+ expect(res.headers.get('Content-Type')).to.equal('image/jpeg');
+
+ // TODO: verify image file? It looks like sizeOf doesn't support ArrayBuffers
+ });
+ });
+
+ describe('Local images with inline imports', () => {
+ it('includes sources', () => {
+ const sources = $('#inline source');
+
+ expect(sources.length).to.equal(3);
+
+ // TODO: better coverage to verify source props
+ });
+
+ it('includes src, width, and height attributes', () => {
+ const image = $('#inline img');
+
+ const src = image.attr('src');
+ const [route, params] = src.split('?');
+
+ expect(route).to.equal('/_image');
+
+ const searchParams = new URLSearchParams(params);
+
+ expect(searchParams.get('f')).to.equal('jpg');
+ expect(searchParams.get('w')).to.equal('506');
+ expect(searchParams.get('h')).to.equal('253');
+ // TODO: possible to avoid encoding the full image path?
+ expect(searchParams.get('href').endsWith('/assets/social.jpg')).to.equal(true);
+ });
+
+ it('returns the optimized image', async () => {
+ const image = $('#inline img');
+
+ const res = await fixture.fetch(image.attr('src'));
+
+ expect(res.status).to.equal(200);
+ expect(res.headers.get('Content-Type')).to.equal('image/jpeg');
+
+ // TODO: verify image file? It looks like sizeOf doesn't support ArrayBuffers
+ });
+ });
+
+ describe('Remote images', () => {
+ it('includes sources', () => {
+ const sources = $('#google source');
+
+ expect(sources.length).to.equal(3);
+
+ // TODO: better coverage to verify source props
+ });
+
+ it('includes src, width, and height attributes', () => {
+ const image = $('#google img');
+
+ const src = image.attr('src');
+ const [route, params] = src.split('?');
+
+ expect(route).to.equal('/_image');
+
+ const searchParams = new URLSearchParams(params);
+
+ expect(searchParams.get('f')).to.equal('png');
+ expect(searchParams.get('w')).to.equal('544');
+ expect(searchParams.get('h')).to.equal('184');
+ expect(searchParams.get('href')).to.equal(
+ 'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png'
+ );
+ });
+ });
+ });
+});
diff --git a/packages/integrations/image/test/picture-ssr.test.js b/packages/integrations/image/test/picture-ssr.test.js
new file mode 100644
index 000000000..ebef4249b
--- /dev/null
+++ b/packages/integrations/image/test/picture-ssr.test.js
@@ -0,0 +1,278 @@
+import { expect } from 'chai';
+import * as cheerio from 'cheerio';
+import { loadFixture } from './test-utils.js';
+import testAdapter from '../../../astro/test/test-adapter.js';
+
+describe('SSR pictures - build', function () {
+ let fixture;
+
+ before(async () => {
+ fixture = await loadFixture({
+ root: './fixtures/basic-picture/',
+ adapter: testAdapter(),
+ experimental: {
+ ssr: true,
+ },
+ });
+ await fixture.build();
+ });
+
+ describe('Local images', () => {
+ it('includes sources', async () => {
+ const app = await fixture.loadTestAdapterApp();
+
+ const request = new Request('http://example.com/');
+ const response = await app.render(request);
+ const html = await response.text();
+ const $ = cheerio.load(html);
+
+ const sources = $('#social-jpg source');
+
+ expect(sources.length).to.equal(3);
+
+ // TODO: better coverage to verify source props
+ });
+
+ it('includes src, width, and height attributes', async () => {
+ const app = await fixture.loadTestAdapterApp();
+
+ const request = new Request('http://example.com/');
+ const response = await app.render(request);
+ const html = await response.text();
+ const $ = cheerio.load(html);
+
+ const image = $('#social-jpg img');
+
+ const src = image.attr('src');
+ const [route, params] = src.split('?');
+
+ expect(route).to.equal('/_image');
+
+ const searchParams = new URLSearchParams(params);
+
+ expect(searchParams.get('f')).to.equal('jpg');
+ expect(searchParams.get('w')).to.equal('506');
+ expect(searchParams.get('h')).to.equal('253');
+ // TODO: possible to avoid encoding the full image path?
+ expect(searchParams.get('href').endsWith('/assets/social.jpg')).to.equal(true);
+ });
+
+ // TODO: Track down why the fixture.fetch is failing with the test adapter
+ it.skip('built the optimized image', async () => {
+ const app = await fixture.loadTestAdapterApp();
+
+ const request = new Request('http://example.com/');
+ const response = await app.render(request);
+ const html = await response.text();
+ const $ = cheerio.load(html);
+
+ const image = $('#social-jpg img');
+
+ const res = await fixture.fetch(image.attr('src'));
+
+ expect(res.status).to.equal(200);
+ expect(res.headers.get('Content-Type')).to.equal('image/jpeg');
+
+ // TODO: verify image file? It looks like sizeOf doesn't support ArrayBuffers
+ });
+ });
+
+ describe('Inline imports', () => {
+ it('includes sources', async () => {
+ const app = await fixture.loadTestAdapterApp();
+
+ const request = new Request('http://example.com/');
+ const response = await app.render(request);
+ const html = await response.text();
+ const $ = cheerio.load(html);
+
+ const sources = $('#inline source');
+
+ expect(sources.length).to.equal(3);
+
+ // TODO: better coverage to verify source props
+ });
+
+ it('includes src, width, and height attributes', async () => {
+ const app = await fixture.loadTestAdapterApp();
+
+ const request = new Request('http://example.com/');
+ const response = await app.render(request);
+ const html = await response.text();
+ const $ = cheerio.load(html);
+
+ const image = $('#inline img');
+
+ const src = image.attr('src');
+ const [route, params] = src.split('?');
+
+ expect(route).to.equal('/_image');
+
+ const searchParams = new URLSearchParams(params);
+
+ expect(searchParams.get('f')).to.equal('jpg');
+ expect(searchParams.get('w')).to.equal('506');
+ expect(searchParams.get('h')).to.equal('253');
+ // TODO: possible to avoid encoding the full image path?
+ expect(searchParams.get('href').endsWith('/assets/social.jpg')).to.equal(true);
+ });
+ });
+
+ describe('Remote images', () => {
+ it('includes sources', async () => {
+ const app = await fixture.loadTestAdapterApp();
+
+ const request = new Request('http://example.com/');
+ const response = await app.render(request);
+ const html = await response.text();
+ const $ = cheerio.load(html);
+
+ const sources = $('#google source');
+
+ expect(sources.length).to.equal(3);
+
+ // TODO: better coverage to verify source props
+ });
+
+ it('includes src, width, and height attributes', async () => {
+ const app = await fixture.loadTestAdapterApp();
+
+ const request = new Request('http://example.com/');
+ const response = await app.render(request);
+ const html = await response.text();
+ const $ = cheerio.load(html);
+
+ const image = $('#google img');
+
+ const src = image.attr('src');
+ const [route, params] = src.split('?');
+
+ expect(route).to.equal('/_image');
+
+ const searchParams = new URLSearchParams(params);
+
+ expect(searchParams.get('f')).to.equal('png');
+ expect(searchParams.get('w')).to.equal('544');
+ expect(searchParams.get('h')).to.equal('184');
+ // TODO: possible to avoid encoding the full image path?
+ expect(searchParams.get('href').endsWith('googlelogo_color_272x92dp.png')).to.equal(true);
+ });
+ });
+});
+
+describe('SSR images - dev', function () {
+ let fixture;
+ let devServer;
+ let $;
+
+ before(async () => {
+ fixture = await loadFixture({
+ root: './fixtures/basic-picture/',
+ adapter: testAdapter(),
+ experimental: {
+ ssr: true,
+ },
+ });
+
+ devServer = await fixture.startDevServer();
+ const html = await fixture.fetch('/').then((res) => res.text());
+ $ = cheerio.load(html);
+ });
+
+ after(async () => {
+ await devServer.stop();
+ });
+
+ describe('Local images', () => {
+ it('includes sources', () => {
+ const sources = $('#social-jpg source');
+
+ expect(sources.length).to.equal(3);
+
+ // TODO: better coverage to verify source props
+ });
+
+ it('includes src, width, and height attributes', () => {
+ const image = $('#social-jpg img');
+
+ const src = image.attr('src');
+ const [route, params] = src.split('?');
+
+ expect(route).to.equal('/_image');
+
+ const searchParams = new URLSearchParams(params);
+
+ expect(searchParams.get('f')).to.equal('jpg');
+ expect(searchParams.get('w')).to.equal('506');
+ expect(searchParams.get('h')).to.equal('253');
+ // TODO: possible to avoid encoding the full image path?
+ expect(searchParams.get('href').endsWith('/assets/social.jpg')).to.equal(true);
+ });
+
+ it('returns the optimized image', async () => {
+ const image = $('#social-jpg img');
+
+ const res = await fixture.fetch(image.attr('src'));
+
+ expect(res.status).to.equal(200);
+ expect(res.headers.get('Content-Type')).to.equal('image/jpeg');
+
+ // TODO: verify image file? It looks like sizeOf doesn't support ArrayBuffers
+ });
+ });
+
+ describe('Inline imports', () => {
+ it('includes sources', () => {
+ const sources = $('#inline source');
+
+ expect(sources.length).to.equal(3);
+
+ // TODO: better coverage to verify source props
+ });
+
+ it('includes src, width, and height attributes', () => {
+ const image = $('#inline img');
+
+ const src = image.attr('src');
+ const [route, params] = src.split('?');
+
+ expect(route).to.equal('/_image');
+
+ const searchParams = new URLSearchParams(params);
+
+ expect(searchParams.get('f')).to.equal('jpg');
+ expect(searchParams.get('w')).to.equal('506');
+ expect(searchParams.get('h')).to.equal('253');
+ // TODO: possible to avoid encoding the full image path?
+ expect(searchParams.get('href').endsWith('/assets/social.jpg')).to.equal(true);
+ });
+ });
+
+ describe('Remote images', () => {
+ it('includes sources', () => {
+ const sources = $('#google source');
+
+ expect(sources.length).to.equal(3);
+
+ // TODO: better coverage to verify source props
+ });
+
+ it('includes src, width, and height attributes', () => {
+ const image = $('#google img');
+
+ const src = image.attr('src');
+ const [route, params] = src.split('?');
+
+ expect(route).to.equal('/_image');
+
+ const searchParams = new URLSearchParams(params);
+
+ expect(searchParams.get('f')).to.equal('png');
+ expect(searchParams.get('w')).to.equal('544');
+ expect(searchParams.get('h')).to.equal('184');
+ expect(searchParams.get('href')).to.equal(
+ 'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png'
+ );
+ });
+ });
+});