diff options
-rw-r--r-- | packages/astro/test/0-css.nodetest.js (renamed from packages/astro/test/0-css.test.js) | 185 | ||||
-rw-r--r-- | packages/astro/test/cli.nodetest.js | 204 | ||||
-rw-r--r-- | packages/astro/test/cli.test.js | 186 | ||||
-rw-r--r-- | packages/astro/test/client-address.nodetest.js (renamed from packages/astro/test/client-address.test.js) | 20 | ||||
-rw-r--r-- | packages/astro/test/code-component.nodetest.js (renamed from packages/astro/test/code-component.test.js) | 11 | ||||
-rw-r--r-- | packages/astro/test/component-library.nodetest.js (renamed from packages/astro/test/component-library.test.js) | 47 | ||||
-rw-r--r-- | packages/astro/test/config-mode.nodetest.js (renamed from packages/astro/test/config-mode.test.js) | 19 | ||||
-rw-r--r-- | packages/astro/test/config-vite-css-target.nodetest.js (renamed from packages/astro/test/config-vite-css-target.test.js) | 5 | ||||
-rw-r--r-- | packages/astro/test/config-vite.nodetest.js (renamed from packages/astro/test/config-vite.test.js) | 5 | ||||
-rw-r--r-- | packages/astro/test/content-collections.nodetest.js (renamed from packages/astro/test/content-collections.test.js) | 110 | ||||
-rw-r--r-- | packages/astro/test/core-image-infersize.nodetest.js (renamed from packages/astro/test/core-image-infersize.test.js) | 24 | ||||
-rw-r--r-- | packages/astro/test/core-image-remark-imgattr.nodetest.js (renamed from packages/astro/test/core-image-remark-imgattr.test.js) | 9 | ||||
-rw-r--r-- | packages/astro/test/core-image.nodetest.js (renamed from packages/astro/test/core-image.test.js) | 393 | ||||
-rw-r--r-- | packages/astro/test/custom-assets-name.nodetest.js (renamed from packages/astro/test/custom-assets-name.test.js) | 5 |
14 files changed, 655 insertions, 568 deletions
diff --git a/packages/astro/test/0-css.test.js b/packages/astro/test/0-css.nodetest.js index c8c5af6d8..4cc1d1864 100644 --- a/packages/astro/test/0-css.test.js +++ b/packages/astro/test/0-css.nodetest.js @@ -4,7 +4,8 @@ * rather than trying to start up when all other threads are busy and having to fight for resources */ -import { expect } from 'chai'; +import assert from 'node:assert/strict'; +import { describe, before, it, after } from 'node:test'; import * as cheerio from 'cheerio'; import { loadFixture } from './test-utils.js'; @@ -22,18 +23,22 @@ describe('CSS', function () { let html; let bundledCSS; - before(async () => { - this.timeout(45000); // test needs a little more time in CI - await fixture.build(); - - // get bundled CSS (will be hashed, hence DOM query) - html = await fixture.readFile('/index.html'); - $ = cheerio.load(html); - const bundledCSSHREF = $('link[rel=stylesheet][href^=/_astro/]').attr('href'); - bundledCSS = (await fixture.readFile(bundledCSSHREF.replace(/^\/?/, '/'))) - .replace(/\s/g, '') - .replace('/n', ''); - }); + before( + async () => { + await fixture.build(); + + // get bundled CSS (will be hashed, hence DOM query) + html = await fixture.readFile('/index.html'); + $ = cheerio.load(html); + const bundledCSSHREF = $('link[rel=stylesheet][href^=/_astro/]').attr('href'); + bundledCSS = (await fixture.readFile(bundledCSSHREF.replace(/^\/?/, '/'))) + .replace(/\s/g, '') + .replace('/n', ''); + }, + { + timeout: 45000, + } + ); describe('Astro Styles', () => { it('HTML and CSS scoped correctly', async () => { @@ -53,24 +58,24 @@ describe('CSS', function () { } // 1. check HTML - expect(el1.attr('class')).to.equal(`blue`); - expect(el2.attr('class')).to.equal(`visible`); + assert.equal(el1.attr('class'), `blue`); + assert.equal(el2.attr('class'), `visible`); // 2. check CSS const expected = `.blue[${scopedAttribute}],.color\\:blue[${scopedAttribute}]{color:#b0e0e6}.visible[${scopedAttribute}]{display:block}`; - expect(bundledCSS).to.include(expected); + assert.equal(bundledCSS.includes(expected), true); }); it('Generated link tags are void elements', async () => { - expect(html).to.not.include('</link>'); + assert.notEqual(html.includes('</link>'), true); }); it('No <style> skips scoping', async () => { // Astro component without <style> should not include scoped class - expect($('#no-scope').attr('class')).to.equal(undefined); + assert.equal($('#no-scope').attr('class'), undefined); }); - it('Child inheritance', (done) => { + it('Child inheritance', (t, done) => { for (const [key] of Object.entries($('#passed-in')[0].attribs)) { if (/^data-astro-cid-[A-Za-z\d-]+/.test(key)) { done(); @@ -80,29 +85,29 @@ describe('CSS', function () { it('Using hydrated components adds astro-island styles', async () => { const inline = $('style').html(); - expect(inline).to.include('display:contents'); + assert.equal(inline.includes('display:contents'), true); }); it('<style lang="sass">', async () => { - expect(bundledCSS).to.match(/h1\[data-astro-cid-[^{]*\{color:#90ee90\}/); + assert.match(bundledCSS, /h1\[data-astro-cid-[^{]*\{color:#90ee90\}/); }); it('<style lang="scss">', async () => { - expect(bundledCSS).to.match(/h1\[data-astro-cid-[^{]*\{color:#ff69b4\}/); + assert.match(bundledCSS, /h1\[data-astro-cid-[^{]*\{color:#ff69b4\}/); }); }); describe('Styles in src/', () => { it('.css', async () => { - expect(bundledCSS).to.match(/.linked-css[^{]*\{color:gold/); + assert.match(bundledCSS, /.linked-css[^{]*\{color:gold/); }); it('.sass', async () => { - expect(bundledCSS).to.match(/.linked-sass[^{]*\{color:#789/); + assert.match(bundledCSS, /.linked-sass[^{]*\{color:#789/); }); it('.scss', async () => { - expect(bundledCSS).to.match(/.linked-scss[^{]*\{color:#6b8e23/); + assert.match(bundledCSS, /.linked-scss[^{]*\{color:#6b8e23/); }); }); @@ -110,9 +115,9 @@ describe('CSS', function () { it('.css', async () => { const el = $('#react-css'); // 1. check HTML - expect(el.attr('class')).to.include('react-title'); + assert.equal(el.attr('class'), 'react-title'); // 2. check CSS - expect(bundledCSS).to.include('.react-title'); + assert.equal(bundledCSS.includes('.react-title'), true); }); it('.module.css', async () => { @@ -121,30 +126,30 @@ describe('CSS', function () { const moduleClass = classes.find((name) => /^_title_[\w-]+/.test(name)); // 1. check HTML - expect(el.attr('class')).to.include(moduleClass); + assert.equal(el.attr('class').includes(moduleClass), true); // 2. check CSS - expect(bundledCSS).to.match(new RegExp(`.${moduleClass}[^{]*{font-family:fantasy`)); + assert.match(bundledCSS, new RegExp(`.${moduleClass}[^{]*{font-family:fantasy`)); }); it('.sass', async () => { const el = $('#react-sass'); // 1. check HTML - expect(el.attr('class')).to.include('react-sass-title'); + assert.equal(el.attr('class').includes('react-sass-title'), true); // 2. check CSS - expect(bundledCSS).to.match(/.react-sass-title[^{]*\{font-family:fantasy/); + assert.match(bundledCSS, /.react-sass-title[^{]*\{font-family:fantasy/); }); it('.scss', async () => { const el = $('#react-scss'); // 1. check HTML - expect(el.attr('class')).to.include('react-scss-title'); + assert.equal(el.attr('class').includes('react-scss-title'), true); // 2. check CSS - expect(bundledCSS).to.match(/.react-scss-title[^{]*\{font-family:fantasy/); + assert.match(bundledCSS, /.react-scss-title[^{]*\{font-family:fantasy/); }); it('.module.sass', async () => { @@ -153,10 +158,10 @@ describe('CSS', function () { const moduleClass = classes.find((name) => /^_title_[\w-]+/.test(name)); // 1. check HTML - expect(el.attr('class')).to.include(moduleClass); + assert.equal(el.attr('class').includes(moduleClass), true); // 2. check CSS - expect(bundledCSS).to.match(new RegExp(`.${moduleClass}[^{]*{font-family:fantasy`)); + assert.match(bundledCSS, new RegExp(`.${moduleClass}[^{]*{font-family:fantasy`)); }); it('.module.scss', async () => { @@ -165,19 +170,19 @@ describe('CSS', function () { const moduleClass = classes.find((name) => /^_title_[\w-]+/.test(name)); // 1. check HTML - expect(el.attr('class')).to.include(moduleClass); + assert.equal(el.attr('class').includes(moduleClass), true); // 2. check CSS - expect(bundledCSS).to.match(new RegExp(`.${moduleClass}[^{]*{font-family:fantasy`)); + assert.match(bundledCSS, new RegExp(`.${moduleClass}[^{]*{font-family:fantasy`)); }); it('.module.css ordering', () => { const globalStyleClassIndex = bundledCSS.indexOf('.module-ordering'); const moduleStyleClassIndex = bundledCSS.indexOf('._module_ordering'); // css module has higher priority than global style - expect(globalStyleClassIndex).to.be.greaterThan(-1); - expect(moduleStyleClassIndex).to.be.greaterThan(-1); - expect(moduleStyleClassIndex).to.be.greaterThan(globalStyleClassIndex); + assert.equal(globalStyleClassIndex > -1, true); + assert.equal(moduleStyleClassIndex > -1, true); + assert.equal(moduleStyleClassIndex > globalStyleClassIndex, true); }); }); @@ -186,10 +191,10 @@ describe('CSS', function () { const el = $('#vue-css'); // 1. check HTML - expect(el.attr('class')).to.include('vue-css'); + assert.equal(el.attr('class').includes('vue-css'), true); // 2. check CSS - expect(bundledCSS).to.match(/.vue-css[^{]*\{font-family:cursive/); + assert.match(bundledCSS, /.vue-css[^{]*\{font-family:cursive/); }); it('<style scoped>', async () => { @@ -198,13 +203,13 @@ describe('CSS', function () { // find data-v-* attribute (how Vue CSS scoping works) const { attribs } = el.get(0); const scopeId = Object.keys(attribs).find((k) => k.startsWith('data-v-')); - expect(scopeId).to.be.ok; + assert.ok(scopeId); // 1. check HTML - expect(el.attr('class')).to.include('vue-scoped'); + assert.equal(el.attr('class').includes('vue-scoped'), true); // 2. check CSS - expect(bundledCSS).to.include(`.vue-scoped[${scopeId}]`); + assert.equal(bundledCSS.includes(`.vue-scoped[${scopeId}]`), true); }); it('<style module>', async () => { @@ -213,30 +218,30 @@ describe('CSS', function () { const moduleClass = classes.find((name) => /^_title_[\w-]+/.test(name)); // 1. check HTML - expect(el.attr('class')).to.include(moduleClass); + assert.equal(el.attr('class').includes(moduleClass), true); // 2. check CSS - expect(bundledCSS).to.match(new RegExp(`.${moduleClass}[^{]*{font-family:cursive`)); + assert.match(bundledCSS, new RegExp(`.${moduleClass}[^{]*{font-family:cursive`)); }); it('<style lang="sass">', async () => { const el = $('#vue-sass'); // 1. check HTML - expect(el.attr('class')).to.include('vue-sass'); + assert.equal(el.attr('class').includes('vue-sass'), true); // 2. check CSS - expect(bundledCSS).to.match(/.vue-sass[^{]*\{font-family:cursive/); + assert.match(bundledCSS, /.vue-sass[^{]*\{font-family:cursive/); }); it('<style lang="scss">', async () => { const el = $('#vue-scss'); // 1. check HTML - expect(el.attr('class')).to.include('vue-scss'); + assert.equal(el.attr('class').includes('vue-scss'), true); // 2. check CSS - expect(bundledCSS).to.match(/.vue-scss[^{]*\{font-family:cursive/); + assert.match(bundledCSS, /.vue-scss[^{]*\{font-family:cursive/); }); }); @@ -249,10 +254,11 @@ describe('CSS', function () { ); // 1. check HTML - expect(el.attr('class')).to.include('svelte-css'); + assert.equal(el.attr('class').includes('svelte-css'), true); // 2. check CSS - expect(bundledCSS).to.match( + assert.match( + bundledCSS, new RegExp(`.svelte-css.${scopedClass}[^{]*{font-family:ComicSansMS`) ); }); @@ -265,10 +271,11 @@ describe('CSS', function () { ); // 1. check HTML - expect(el.attr('class')).to.include('svelte-sass'); + assert.equal(el.attr('class').includes('svelte-sass'), true); // 2. check CSS - expect(bundledCSS).to.match( + assert.match( + bundledCSS, new RegExp(`.svelte-sass.${scopedClass}[^{]*{font-family:ComicSansMS`) ); }); @@ -281,10 +288,11 @@ describe('CSS', function () { ); // 1. check HTML - expect(el.attr('class')).to.include('svelte-scss'); + assert.equal(el.attr('class').includes('svelte-scss'), true); // 2. check CSS - expect(bundledCSS).to.match( + assert.match( + bundledCSS, new RegExp(`.svelte-scss.${scopedClass}[^{]*{font-family:ComicSansMS`) ); }); @@ -300,15 +308,15 @@ describe('CSS', function () { const ssrHtmlCssHref = $ssrHtml('link[rel=stylesheet][href^=/_astro/]').attr('href'); const ssrHtmlCss = await fixture.readFile(ssrHtmlCssHref.replace(/^\/?/, '/')); - expect(onlyHtmlCss).to.include('.svelte-only-and-ssr'); - expect(ssrHtmlCss).to.include('.svelte-only-and-ssr'); + assert.equal(onlyHtmlCss.includes('.svelte-only-and-ssr'), true); + assert.equal(ssrHtmlCss.includes('.svelte-only-and-ssr'), true); }); }); describe('Vite features', () => { it('.css?raw return a string', () => { const el = $('#css-raw'); - expect(el.text()).to.equal('.foo {color: red;}'); + assert.equal(el.text(), '.foo {color: red;}'); }); }); }); @@ -330,7 +338,7 @@ describe('CSS', function () { it('resolves CSS in public/', async () => { const href = $('link[href="/global.css"]').attr('href'); - expect((await fixture.fetch(href)).status).to.equal(200); + assert.equal((await fixture.fetch(href)).status, 200); }); // Skipped until upstream fix lands @@ -339,25 +347,25 @@ describe('CSS', function () { // Next Vite PR: https://github.com/vitejs/vite/pull/5796 it.skip('resolved imported CSS with ?url', async () => { const href = $('link[href$="imported-url.css"]').attr('href'); - expect(href).to.be.ok; - expect((await fixture.fetch(href)).status).to.equal(200); + assert.ok(href); + assert.equal((await fixture.fetch(href)).status, 200); }); it('resolves ESM style imports', async () => { const allInjectedStyles = $('style').text().replace(/\s*/g, ''); - expect(allInjectedStyles, 'styles/imported-url.css').to.contain('.imported{'); - expect(allInjectedStyles, 'styles/imported-url.sass').to.contain('.imported-sass{'); - expect(allInjectedStyles, 'styles/imported-url.scss').to.contain('.imported-scss{'); + assert.equal(allInjectedStyles.includes('.imported{'), true, 'styles/imported-url.css'); + assert.equal(allInjectedStyles.includes('.imported-sass{'), true, 'styles/imported-url.sass'); + assert.equal(allInjectedStyles.includes('.imported-scss{'), true, 'styles/imported-url.scss'); }); it('resolves Astro styles', async () => { const allInjectedStyles = $('style').text(); - expect(allInjectedStyles).to.contain('.linked-css[data-astro-cid-'); - expect(allInjectedStyles).to.contain('.linked-sass[data-astro-cid-'); - expect(allInjectedStyles).to.contain('.linked-scss[data-astro-cid-'); - expect(allInjectedStyles).to.contain('.wrapper[data-astro-cid-'); + assert.equal(allInjectedStyles.includes('.linked-css[data-astro-cid-'), true); + assert.equal(allInjectedStyles.includes('.linked-sass[data-astro-cid-'), true); + assert.equal(allInjectedStyles.includes('.linked-scss[data-astro-cid-'), true); + assert.equal(allInjectedStyles.includes('.wrapper[data-astro-cid-'), true); }); it('resolves Styles from React', async () => { @@ -368,44 +376,44 @@ describe('CSS', function () { ]; for (const style of styles) { const href = $(`style[data-vite-dev-id$="${style}"]`).attr('data-vite-dev-id'); - expect((await fixture.fetch(href)).status, style).to.equal(200); + assert.equal((await fixture.fetch(href)).status, 200); } const allInjectedStyles = $('style').text().replace(/\s*/g, ''); - expect(allInjectedStyles).to.contain('.react-title{'); - expect(allInjectedStyles).to.contain('.react-sass-title{'); - expect(allInjectedStyles).to.contain('.react-scss-title{'); + assert.equal(allInjectedStyles.includes('.react-title{'), true); + assert.equal(allInjectedStyles.includes('.react-sass-title{'), true); + assert.equal(allInjectedStyles.includes('.react-scss-title{'), true); }); it('resolves CSS from Svelte', async () => { const allInjectedStyles = $('style').text(); - expect(allInjectedStyles).to.contain('.svelte-css'); - expect(allInjectedStyles).to.contain('.svelte-sass'); - expect(allInjectedStyles).to.contain('.svelte-scss'); + assert.equal(allInjectedStyles.includes('.svelte-css'), true); + assert.equal(allInjectedStyles.includes('.svelte-sass'), true); + assert.equal(allInjectedStyles.includes('.svelte-scss'), true); }); it('resolves CSS from Vue', async () => { const styles = ['VueModules.vue?vue&type=style&index=0&lang.module.scss']; for (const style of styles) { const href = $(`link[href$="${style}"]`).attr('href'); - expect((await fixture.fetch(href)).status, style).to.equal(200); + assert.equal((await fixture.fetch(href)).status, 200, style); } const allInjectedStyles = $('style').text().replace(/\s*/g, ''); - expect(allInjectedStyles).to.contain('.vue-css{'); - expect(allInjectedStyles).to.contain('.vue-sass{'); - expect(allInjectedStyles).to.contain('.vue-scss{'); - expect(allInjectedStyles).to.contain('.vue-scoped[data-v-'); + assert.equal(allInjectedStyles.includes('.vue-css{'), true); + assert.equal(allInjectedStyles.includes('.vue-sass{'), true); + assert.equal(allInjectedStyles.includes('.vue-scss{'), true); + assert.equal(allInjectedStyles.includes('.vue-scoped[data-v-'), true); }); it('remove unused styles from client:load components', async () => { const bundledAssets = await fixture.readdir('./_astro'); // SvelteDynamic styles is already included in the main page css asset const unusedCssAsset = bundledAssets.find((asset) => /SvelteDynamic\..*\.css/.test(asset)); - expect(unusedCssAsset, 'Found unused style ' + unusedCssAsset).to.be.undefined; + assert.equal(unusedCssAsset, undefined, 'Found unused style ' + unusedCssAsset); let foundVitePreloadCSS = false; const bundledJS = await fixture.glob('**/*.?(m)js'); @@ -415,7 +423,8 @@ describe('CSS', function () { foundVitePreloadCSS = filename; } } - expect(foundVitePreloadCSS).to.equal( + assert.equal( + foundVitePreloadCSS, false, 'Should not have found a preload for the dynamic CSS' ); @@ -427,14 +436,14 @@ describe('CSS', function () { const globalStyleClassIndex = globalStyleTag.index(); const moduleStyleClassIndex = moduleStyleTag.index(); // css module has higher priority than global style - expect(globalStyleClassIndex).to.be.greaterThan(-1); - expect(moduleStyleClassIndex).to.be.greaterThan(-1); - expect(moduleStyleClassIndex).to.be.greaterThan(globalStyleClassIndex); + assert.equal(globalStyleClassIndex > -1, true); + assert.equal(moduleStyleClassIndex > -1, true); + assert.equal(moduleStyleClassIndex > globalStyleClassIndex, true); }); it('.css?raw return a string', () => { const el = $('#css-raw'); - expect(el.text()).to.equal('.foo {color: red;}'); + assert.equal(el.text(), '.foo {color: red;}'); }); }); }); diff --git a/packages/astro/test/cli.nodetest.js b/packages/astro/test/cli.nodetest.js new file mode 100644 index 000000000..6a88b5b5d --- /dev/null +++ b/packages/astro/test/cli.nodetest.js @@ -0,0 +1,204 @@ +import assert from 'node:assert/strict'; +import { describe, it } from 'node:test'; +import { cli, parseCliDevStart, cliServerLogSetup, loadFixture } from './test-utils.js'; +import stripAnsi from 'strip-ansi'; +import { promises as fs, readFileSync } from 'node:fs'; +import { fileURLToPath } from 'node:url'; +import { isIPv4 } from 'node:net'; +import { join } from 'node:path'; +import { Writable } from 'node:stream'; + +describe('astro cli', () => { + const cliServerLogSetupWithFixture = (flags, cmd) => { + const projectRootURL = new URL('./fixtures/astro-basic/', import.meta.url); + return cliServerLogSetup(['--root', fileURLToPath(projectRootURL), ...flags], cmd); + }; + + it('astro', async () => { + const proc = await cli(); + assert.equal(proc.exitCode, 0); + }); + + // Flaky test, in CI it exceeds the timeout most of the times + it.skip( + 'astro check --watch reports errors on modified files', + { + timeout: 35000, + }, + async () => { + let messageResolve; + const messagePromise = new Promise((resolve) => { + messageResolve = resolve; + }); + const oneErrorContent = 'foobar'; + + /** @type {import('./test-utils').Fixture} */ + const fixture = await loadFixture({ + root: './fixtures/astro-check-watch/', + }); + const logs = []; + + const checkServer = await fixture.check({ + flags: { watch: true }, + logging: { + level: 'info', + dest: new Writable({ + objectMode: true, + write(event, _, callback) { + logs.push({ ...event, message: stripAnsi(event.message) }); + if (event.message.includes('1 error')) { + messageResolve(logs); + } + callback(); + }, + }), + }, + }); + await checkServer.watch(); + const pagePath = join(fileURLToPath(fixture.config.root), 'src/pages/index.astro'); + const pageContent = readFileSync(pagePath, 'utf-8'); + await fs.writeFile(pagePath, oneErrorContent); + const messages = await messagePromise; + await fs.writeFile(pagePath, pageContent); + await checkServer.stop(); + const diagnostics = messages.filter( + (m) => m.type === 'diagnostics' && m.message.includes('Result') + ); + assert.equal(diagnostics[0].message.includes('0 errors'), true); + assert.equal(diagnostics[1].message.includes('1 error'), true); + } + ); + + it('astro --version', async () => { + const pkgURL = new URL('../package.json', import.meta.url); + const pkgVersion = await fs.readFile(pkgURL, 'utf8').then((data) => JSON.parse(data).version); + + const proc = await cli('--version'); + + assert.equal(proc.stdout.includes(pkgVersion), true); + }); + + it( + 'astro check no errors', + { + timeout: 35000, + }, + async () => { + let proc = undefined; + const projectRootURL = new URL('./fixtures/astro-check-no-errors/', import.meta.url); + try { + proc = await cli('check', '--root', fileURLToPath(projectRootURL)); + } catch (err) {} + + assert.equal(proc?.stdout.includes('0 errors'), true); + } + ); + + it( + 'astro check has errors', + { + timeout: 35000, + }, + async () => { + let stdout = undefined; + const projectRootURL = new URL('./fixtures/astro-check-errors/', import.meta.url); + + // When `astro check` finds errors, it returns an error code. As such, we need to wrap this + // in a try/catch because otherwise Mocha will always report this test as a fail + try { + await cli('check', '--root', fileURLToPath(projectRootURL)); + } catch (err) { + stdout = err.toString(); + } + + assert.equal(stdout.includes('1 error'), true); + } + ); + + it('astro dev welcome', async () => { + const pkgURL = new URL('../package.json', import.meta.url); + const pkgVersion = await fs.readFile(pkgURL, 'utf8').then((data) => JSON.parse(data).version); + + const projectRootURL = new URL('./fixtures/astro-basic/', import.meta.url); + const proc = cli('dev', '--root', fileURLToPath(projectRootURL)); + const { messages } = await parseCliDevStart(proc); + + const index = messages[0].includes('[vite]') ? 1 : 0; + assert.equal(messages[index].includes('astro'), true); + assert.equal(messages[index].includes(pkgVersion), true); + assert.equal(messages[index].includes('ready in'), true); + }); + + ['dev', 'preview'].forEach((cmd) => { + const networkLogFlags = [['--host'], ['--host', '0.0.0.0']]; + networkLogFlags.forEach(([flag, flagValue]) => { + it(`astro ${cmd} ${flag} ${flagValue ?? ''} - network log`, async () => { + const { local, network } = await cliServerLogSetupWithFixture( + flagValue ? [flag, flagValue] : [flag], + cmd + ); + + assert.notEqual(local, undefined); + assert.notEqual(network, undefined); + + const localURL = new URL(local); + const networkURL = new URL(network); + + assert.equal(['localhost', '127.0.0.1'].includes(localURL.hostname), true), + `Expected local URL to be on localhost`; + + // Note: our tests run in parallel so this could be 3000+! + assert.equal(Number.parseInt(localURL.port) >= 4321, true, `Expected Port to be >= 4321`); + assert.equal( + networkURL.port, + localURL.port, + `Expected local and network ports to be equal` + ); + assert.equal( + isIPv4(networkURL.hostname), + true, + `Expected network URL to respect --host flag` + ); + }); + }); + + const hostToExposeFlags = [['', '']]; + hostToExposeFlags.forEach(([flag, flagValue]) => { + it(`astro ${cmd} ${flag} ${flagValue} - host to expose`, async () => { + const { local, network } = await cliServerLogSetupWithFixture([flag, flagValue], cmd); + + assert.notEqual(local, undefined); + assert.notEqual(network, undefined); + const localURL = new URL(local); + + assert.equal( + ['localhost', '127.0.0.1'].includes(localURL.hostname), + true, + `Expected local URL to be on localhost` + ); + + assert.throws(() => new URL(networkURL)); + }); + }); + + const noNetworkLogFlags = [ + ['--host', 'localhost'], + ['--host', '127.0.0.1'], + ]; + noNetworkLogFlags.forEach(([flag, flagValue]) => { + it(`astro ${cmd} ${flag} ${flagValue} - no network log`, async () => { + const { local, network } = await cliServerLogSetupWithFixture([flag, flagValue], cmd); + + assert.notEqual(local, undefined); + assert.equal(network, undefined); + + const localURL = new URL(local); + assert.equal( + ['localhost', '127.0.0.1'].includes(localURL.hostname), + true, + `Expected local URL to be on localhost` + ); + }); + }); + }); +}); diff --git a/packages/astro/test/cli.test.js b/packages/astro/test/cli.test.js deleted file mode 100644 index 8fb375fe9..000000000 --- a/packages/astro/test/cli.test.js +++ /dev/null @@ -1,186 +0,0 @@ -import { expect } from 'chai'; -import { cli, parseCliDevStart, cliServerLogSetup, loadFixture } from './test-utils.js'; -import stripAnsi from 'strip-ansi'; -import { promises as fs, readFileSync } from 'node:fs'; -import { fileURLToPath } from 'node:url'; -import { isIPv4 } from 'node:net'; -import { join } from 'node:path'; -import { Writable } from 'node:stream'; - -describe('astro cli', () => { - const cliServerLogSetupWithFixture = (flags, cmd) => { - const projectRootURL = new URL('./fixtures/astro-basic/', import.meta.url); - return cliServerLogSetup(['--root', fileURLToPath(projectRootURL), ...flags], cmd); - }; - - it('astro', async () => { - const proc = await cli(); - expect(proc.exitCode).to.equal(0); - }); - - // Flaky test, in CI it exceeds the timeout most of the times - it.skip('astro check --watch reports errors on modified files', async () => { - let messageResolve; - const messagePromise = new Promise((resolve) => { - messageResolve = resolve; - }); - const oneErrorContent = 'foobar'; - - /** @type {import('./test-utils').Fixture} */ - const fixture = await loadFixture({ - root: './fixtures/astro-check-watch/', - }); - const logs = []; - - const checkServer = await fixture.check({ - flags: { watch: true }, - logging: { - level: 'info', - dest: new Writable({ - objectMode: true, - write(event, _, callback) { - logs.push({ ...event, message: stripAnsi(event.message) }); - if (event.message.includes('1 error')) { - messageResolve(logs); - } - callback(); - }, - }), - }, - }); - await checkServer.watch(); - const pagePath = join(fileURLToPath(fixture.config.root), 'src/pages/index.astro'); - const pageContent = readFileSync(pagePath, 'utf-8'); - await fs.writeFile(pagePath, oneErrorContent); - const messages = await messagePromise; - await fs.writeFile(pagePath, pageContent); - await checkServer.stop(); - const diagnostics = messages.filter( - (m) => m.type === 'diagnostics' && m.message.includes('Result') - ); - expect(diagnostics[0].message).to.include('0 errors'); - expect(diagnostics[1].message).to.include('1 error'); - }).timeout(35000); - - it('astro --version', async () => { - const pkgURL = new URL('../package.json', import.meta.url); - const pkgVersion = await fs.readFile(pkgURL, 'utf8').then((data) => JSON.parse(data).version); - - const proc = await cli('--version'); - - expect(proc.stdout).to.include(pkgVersion); - }); - - it('astro check no errors', async () => { - let proc = undefined; - const projectRootURL = new URL('./fixtures/astro-check-no-errors/', import.meta.url); - try { - proc = await cli('check', '--root', fileURLToPath(projectRootURL)); - } catch (err) {} - - expect(proc?.stdout).to.include('0 errors'); - }).timeout(35000); - - it('astro check has errors', async () => { - let stdout = undefined; - const projectRootURL = new URL('./fixtures/astro-check-errors/', import.meta.url); - - // When `astro check` finds errors, it returns an error code. As such, we need to wrap this - // in a try/catch because otherwise Mocha will always report this test as a fail - try { - await cli('check', '--root', fileURLToPath(projectRootURL)); - } catch (err) { - stdout = err.toString(); - } - - expect(stdout).to.include('1 error'); - }).timeout(35000); - - it('astro dev welcome', async () => { - const pkgURL = new URL('../package.json', import.meta.url); - const pkgVersion = await fs.readFile(pkgURL, 'utf8').then((data) => JSON.parse(data).version); - - const projectRootURL = new URL('./fixtures/astro-basic/', import.meta.url); - const proc = cli('dev', '--root', fileURLToPath(projectRootURL)); - const { messages } = await parseCliDevStart(proc); - - const index = messages[0].includes('[vite]') ? 1 : 0; - expect(messages[index]).to.contain('astro'); - expect(messages[index]).to.contain(pkgVersion); - expect(messages[index]).to.contain('ready in'); - }); - - ['dev', 'preview'].forEach((cmd) => { - const networkLogFlags = [['--host'], ['--host', '0.0.0.0']]; - networkLogFlags.forEach(([flag, flagValue]) => { - it(`astro ${cmd} ${flag} ${flagValue ?? ''} - network log`, async () => { - const { local, network } = await cliServerLogSetupWithFixture( - flagValue ? [flag, flagValue] : [flag], - cmd - ); - - expect(local).to.not.be.undefined; - expect(network).to.not.be.undefined; - - const localURL = new URL(local); - const networkURL = new URL(network); - - expect(localURL.hostname).to.be.oneOf( - ['localhost', '127.0.0.1'], - `Expected local URL to be on localhost` - ); - - // Note: our tests run in parallel so this could be 3000+! - expect(Number.parseInt(localURL.port)).to.be.greaterThanOrEqual( - 4321, - `Expected Port to be >= 4321` - ); - expect(networkURL.port).to.be.equal( - localURL.port, - `Expected local and network ports to be equal` - ); - expect(isIPv4(networkURL.hostname)).to.be.equal( - true, - `Expected network URL to respect --host flag` - ); - }); - }); - - const hostToExposeFlags = [['', '']]; - hostToExposeFlags.forEach(([flag, flagValue]) => { - it(`astro ${cmd} ${flag} ${flagValue} - host to expose`, async () => { - const { local, network } = await cliServerLogSetupWithFixture([flag, flagValue], cmd); - - expect(local).to.not.be.undefined; - expect(network).to.not.be.undefined; - const localURL = new URL(local); - - expect(localURL.hostname).to.be.oneOf( - ['localhost', '127.0.0.1'], - `Expected local URL to be on localhost` - ); - - expect(() => new URL(networkURL)).to.throw(); - }); - }); - - const noNetworkLogFlags = [ - ['--host', 'localhost'], - ['--host', '127.0.0.1'], - ]; - noNetworkLogFlags.forEach(([flag, flagValue]) => { - it(`astro ${cmd} ${flag} ${flagValue} - no network log`, async () => { - const { local, network } = await cliServerLogSetupWithFixture([flag, flagValue], cmd); - - expect(local).to.not.be.undefined; - expect(network).to.be.undefined; - - const localURL = new URL(local); - expect(localURL.hostname).to.be.oneOf( - ['localhost', '127.0.0.1'], - `Expected local URL to be on localhost` - ); - }); - }); - }); -}); diff --git a/packages/astro/test/client-address.test.js b/packages/astro/test/client-address.nodetest.js index 339d17ad9..de4a6a4f4 100644 --- a/packages/astro/test/client-address.test.js +++ b/packages/astro/test/client-address.nodetest.js @@ -1,4 +1,5 @@ -import { expect } from 'chai'; +import assert from 'node:assert/strict'; +import { describe, before, it, after } from 'node:test'; import { loadFixture } from './test-utils.js'; import testAdapter from './test-adapter.js'; import * as cheerio from 'cheerio'; @@ -27,7 +28,7 @@ describe('Astro.clientAddress', () => { const response = await app.render(request); const html = await response.text(); const $ = cheerio.load(html); - expect($('#address').text()).to.equal('0.0.0.0'); + assert.equal($('#address').text(), '0.0.0.0'); }); it('app.render can provide the address', async () => { @@ -36,7 +37,7 @@ describe('Astro.clientAddress', () => { const response = await app.render(request, { clientAddress: '1.1.1.1' }); const html = await response.text(); const $ = cheerio.load(html); - expect($('#address').text()).to.equal('1.1.1.1'); + assert.equal($('#address').text(), '1.1.1.1'); }); }); @@ -54,14 +55,14 @@ describe('Astro.clientAddress', () => { it('Gets the address', async () => { let res = await fixture.fetch('/'); - expect(res.status).to.equal(200); + assert.equal(res.status, 200); let html = await res.text(); let $ = cheerio.load(html); let address = $('#address'); // Just checking that something is here. Not specifying address as it // might differ per machine. - expect(address.length).to.be.greaterThan(0); + assert.equal(address.length > 0, true); }); }); }); @@ -83,7 +84,7 @@ describe('Astro.clientAddress', () => { const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/'); const response = await app.render(request); - expect(response.status).to.equal(500); + assert.equal(response.status, 500); }); }); @@ -102,9 +103,10 @@ describe('Astro.clientAddress', () => { it('throws during generation', async () => { try { await fixture.build(); - expect(false).to.equal(true, 'Build should not have completed'); + assert.equal(false, true, 'Build should not have completed'); } catch (err) { - expect(err.message).to.match( + assert.match( + err.message, /Astro\.clientAddress/, 'Error message mentions Astro.clientAddress' ); @@ -126,7 +128,7 @@ describe('Astro.clientAddress', () => { it('is not accessible', async () => { let res = await fixture.fetch('/'); - expect(res.status).to.equal(500); + assert.equal(res.status, 500); }); }); }); diff --git a/packages/astro/test/code-component.test.js b/packages/astro/test/code-component.nodetest.js index 8481e95d8..a3ed65088 100644 --- a/packages/astro/test/code-component.test.js +++ b/packages/astro/test/code-component.nodetest.js @@ -1,4 +1,5 @@ -import { expect } from 'chai'; +import assert from 'node:assert/strict'; +import { describe, before, it } from 'node:test'; import * as cheerio from 'cheerio'; import { loadFixture } from './test-utils.js'; @@ -14,20 +15,20 @@ describe('Code component', () => { it('Debug component styles are not included in the page', async () => { let html = await fixture.readFile('/index.html'); let $ = cheerio.load(html); - expect($('link[rel=stylesheet]')).to.have.a.lengthOf(0, 'No styles should be built'); - expect($('style')).to.have.a.lengthOf(0); + assert.equal($('link[rel=stylesheet]').length, 0, 'No styles should be built'); + assert.equal($('style').length, 0); }); it('is:raw attribute not serialized', async () => { let html = await fixture.readFile('/index.html'); let $ = cheerio.load(html); - expect($('pre').attr('is:raw')).to.equal(undefined); + assert.equal($('pre').attr('is:raw'), undefined); }); // ViewTransitions bug it('No script should be added to the page', async () => { let html = await fixture.readFile('/index.html'); let $ = cheerio.load(html); - expect($('script')).to.have.a.lengthOf(0); + assert.equal($('script').length, 0); }); }); diff --git a/packages/astro/test/component-library.test.js b/packages/astro/test/component-library.nodetest.js index a135c40cb..9533509d6 100644 --- a/packages/astro/test/component-library.test.js +++ b/packages/astro/test/component-library.nodetest.js @@ -1,4 +1,5 @@ -import { expect } from 'chai'; +import assert from 'node:assert/strict'; +import { describe, before, it, after } from 'node:test'; import { load as cheerioLoad } from 'cheerio'; import { loadFixture } from './test-utils.js'; @@ -43,23 +44,24 @@ describe('Component Libraries', () => { it('Built .astro pages', async () => { let html = await fixture.readFile('/with-astro/index.html'); - expect(html).to.be.a('string'); + assert.equal(typeof html, 'string'); html = await fixture.readFile('/with-react/index.html'); - expect(html).to.be.a('string'); + assert.equal(typeof html, 'string'); html = await fixture.readFile('/internal-hydration/index.html'); - expect(html).to.be.a('string'); + assert.equal(typeof html, 'string'); }); it('Works with .astro components', async () => { const html = await fixture.readFile('/with-astro/index.html'); const $ = cheerioLoad(html); - expect($('button').text()).to.equal('Click me', "Rendered the component's slot"); + assert.equal($('button').text(), 'Click me', "Rendered the component's slot"); const findEvidence = createFindEvidence(/border-radius:\s*1rem/); - expect(await findEvidence('with-astro/index.html')).to.equal( + assert.equal( + await findEvidence('with-astro/index.html'), true, "Included the .astro component's <style>" ); @@ -69,27 +71,29 @@ describe('Component Libraries', () => { const html = await fixture.readFile('/with-react/index.html'); const $ = cheerioLoad(html); - expect($('#react-static').text()).to.equal('Hello static!', 'Rendered the static component'); + assert.equal($('#react-static').text(), 'Hello static!', 'Rendered the static component'); - expect($('#react-idle').text()).to.equal( + assert.equal( + $('#react-idle').text(), 'Hello idle!', 'Rendered the client hydrated component' ); - expect($('astro-island[uid]')).to.have.lengthOf(1, 'Included one hydration island'); + assert.equal($('astro-island[uid]').length, 1, 'Included one hydration island'); }); it('Works with components hydrated internally', async () => { const html = await fixture.readFile('/internal-hydration/index.html'); const $ = cheerioLoad(html); - expect($('.counter').length).to.equal(1, 'Rendered the svelte counter'); - expect($('.counter-message').text().trim()).to.equal( + assert.equal($('.counter').length, 1, 'Rendered the svelte counter'); + assert.equal( + $('.counter-message').text().trim(), 'Hello, Svelte!', "rendered the counter's slot" ); - expect($('astro-island[uid]')).to.have.lengthOf(1, 'Included one hydration island'); + assert.equal($('astro-island[uid]').length, 1, 'Included one hydration island'); }); }); @@ -134,10 +138,11 @@ describe('Component Libraries', () => { const html = await fixture.fetch('/with-astro/').then((res) => res.text()); const $ = cheerioLoad(html); - expect($('button').text()).to.equal('Click me', "Rendered the component's slot"); + assert.equal($('button').text(), 'Click me', "Rendered the component's slot"); const findEvidence = createFindEvidence(/border-radius:\s*1rem/); - expect(await findEvidence('/with-astro/')).to.equal( + assert.equal( + await findEvidence('/with-astro/'), true, "Included the .astro component's <style>" ); @@ -147,27 +152,29 @@ describe('Component Libraries', () => { const html = await fixture.fetch('/with-react/').then((res) => res.text()); const $ = cheerioLoad(html); - expect($('#react-static').text()).to.equal('Hello static!', 'Rendered the static component'); + assert.equal($('#react-static').text(), 'Hello static!', 'Rendered the static component'); - expect($('#react-idle').text()).to.equal( + assert.equal( + $('#react-idle').text(), 'Hello idle!', 'Rendered the client hydrated component' ); - expect($('astro-island[uid]')).to.have.lengthOf(1, 'Included one hydration island'); + assert.equal($('astro-island[uid]').length, 1, 'Included one hydration island'); }); it('Works with components hydrated internally', async () => { const html = await fixture.fetch('/internal-hydration/').then((res) => res.text()); const $ = cheerioLoad(html); - expect($('.counter').length).to.equal(1, 'Rendered the svelte counter'); - expect($('.counter-message').text().trim()).to.equal( + assert.equal($('.counter').length, 1, 'Rendered the svelte counter'); + assert.equal( + $('.counter-message').text().trim(), 'Hello, Svelte!', "rendered the counter's slot" ); - expect($('astro-island[uid]')).to.have.lengthOf(1, 'Included one hydration island'); + assert.equal($('astro-island[uid]').length, 1, 'Included one hydration island'); }); }); }); diff --git a/packages/astro/test/config-mode.test.js b/packages/astro/test/config-mode.nodetest.js index 84dafb81f..2b5533f4d 100644 --- a/packages/astro/test/config-mode.test.js +++ b/packages/astro/test/config-mode.nodetest.js @@ -1,4 +1,5 @@ -import { expect } from 'chai'; +import assert from 'node:assert/strict'; +import { describe, before, it } from 'node:test'; import { loadFixture } from './test-utils.js'; import testAdapter from './test-adapter.js'; @@ -22,10 +23,10 @@ describe('AstroConfig - config.output', () => { const app = await fixture.loadTestAdapterApp(); const request = new Request('http://example.com/'); const response = await app.render(request); - expect(response.status).to.equal(200); - expect(response.headers.get('content-type')).to.equal('text/html'); + assert.equal(response.status, 200); + assert.equal(response.headers.get('content-type'), 'text/html'); const html = await response.text(); - expect(html.length).to.be.greaterThan(0); + assert.equal(html.length > 0, true); }); }); @@ -47,11 +48,11 @@ describe('AstroConfig - config.output', () => { await fixture.build(); built = true; } catch (err) { - expect(err).to.be.an.instanceOf(Error); - expect(err.message).to.match(/without an adapter/); + assert.equal(err instanceof Error, true); + assert.match(err.message, /without an adapter/); } - expect(built).to.equal(false, 'Should not have built'); + assert.equal(built, false, 'Should not have built'); }); }); }); @@ -75,9 +76,9 @@ describe('AstroConfig - config.output', () => { try { html = await fixture.readFile('/index.html'); } catch (err) { - expect(false).to.equal(true, 'Couldnt find the file, which mean it did not build.'); + assert.equal(false, true, 'Couldnt find the file, which mean it did not build.'); } - expect(html.length).to.be.greaterThan(0); + assert.equal(html.length > 0, true); }); }); diff --git a/packages/astro/test/config-vite-css-target.test.js b/packages/astro/test/config-vite-css-target.nodetest.js index b0cac084f..97cba273f 100644 --- a/packages/astro/test/config-vite-css-target.test.js +++ b/packages/astro/test/config-vite-css-target.nodetest.js @@ -2,7 +2,8 @@ * css-target */ -import { expect } from 'chai'; +import assert from 'node:assert/strict'; +import { describe, before, it } from 'node:test'; import * as cheerio from 'cheerio'; import { loadFixture } from './test-utils.js'; @@ -35,7 +36,7 @@ describe('CSS', function () { }); it('vite.build.cssTarget is respected', async () => { - expect(bundledCSS).to.match(/\.class\[data-astro-[^{]*\{top:0;right:0;bottom:0;left:0\}/); + assert.match(bundledCSS, /\.class\[data-astro-[^{]*\{top:0;right:0;bottom:0;left:0\}/); }); }); }); diff --git a/packages/astro/test/config-vite.test.js b/packages/astro/test/config-vite.nodetest.js index 1b4eaf11c..24927e9c7 100644 --- a/packages/astro/test/config-vite.test.js +++ b/packages/astro/test/config-vite.nodetest.js @@ -1,4 +1,5 @@ -import { expect } from 'chai'; +import assert from 'node:assert/strict'; +import { describe, before, it } from 'node:test'; import * as cheerio from 'cheerio'; import { loadFixture } from './test-utils.js'; @@ -17,6 +18,6 @@ describe('Vite Config', async () => { it('Allows overriding bundle naming options in the build', async () => { const html = await fixture.readFile('/index.html'); const $ = cheerio.load(html); - expect($('link').attr('href')).to.match(/\/assets\/testing-[a-z\d]+\.css/); + assert.match($('link').attr('href'), /\/assets\/testing-[a-z\d]+\.css/); }); }); diff --git a/packages/astro/test/content-collections.test.js b/packages/astro/test/content-collections.nodetest.js index 44d08b532..28c153150 100644 --- a/packages/astro/test/content-collections.test.js +++ b/packages/astro/test/content-collections.nodetest.js @@ -1,6 +1,7 @@ import * as devalue from 'devalue'; import * as cheerio from 'cheerio'; -import { expect } from 'chai'; +import assert from 'node:assert/strict'; +import { describe, before, it } from 'node:test'; import { loadFixture } from './test-utils.js'; import testAdapter from './test-adapter.js'; import { preventNodeBuiltinDependencyPlugin } from './test-plugins.js'; @@ -21,11 +22,11 @@ describe('Content Collections', () => { }); it('Returns `without config` collection', async () => { - expect(json).to.haveOwnProperty('withoutConfig'); - expect(Array.isArray(json.withoutConfig)).to.equal(true); + assert.ok(json.hasOwnProperty('withoutConfig')); + assert.equal(Array.isArray(json.withoutConfig), true); const ids = json.withoutConfig.map((item) => item.id); - expect(ids).to.deep.equal([ + assert.deepEqual(ids, [ 'columbia.md', 'endeavour.md', 'enterprise.md', @@ -35,11 +36,11 @@ describe('Content Collections', () => { }); it('Handles spaces in `without config` slugs', async () => { - expect(json).to.haveOwnProperty('withoutConfig'); - expect(Array.isArray(json.withoutConfig)).to.equal(true); + assert.ok(json.hasOwnProperty('withoutConfig')); + assert.equal(Array.isArray(json.withoutConfig), true); const slugs = json.withoutConfig.map((item) => item.slug); - expect(slugs).to.deep.equal([ + assert.deepEqual(slugs, [ 'columbia', 'endeavour', 'enterprise', @@ -49,46 +50,50 @@ describe('Content Collections', () => { }); it('Returns `with schema` collection', async () => { - expect(json).to.haveOwnProperty('withSchemaConfig'); - expect(Array.isArray(json.withSchemaConfig)).to.equal(true); + assert.ok(json.hasOwnProperty('withSchemaConfig')); + assert.equal(Array.isArray(json.withSchemaConfig), true); const ids = json.withSchemaConfig.map((item) => item.id); const publishedDates = json.withSchemaConfig.map((item) => item.data.publishedAt); - expect(ids).to.deep.equal(['four%.md', 'one.md', 'three.md', 'two.md']); - expect(publishedDates.every((date) => date instanceof Date)).to.equal( + assert.deepEqual(ids, ['four%.md', 'one.md', 'three.md', 'two.md']); + assert.equal( + publishedDates.every((date) => date instanceof Date), true, 'Not all publishedAt dates are Date objects' ); - expect(publishedDates.map((date) => date.toISOString())).to.deep.equal([ - '2021-01-01T00:00:00.000Z', - '2021-01-01T00:00:00.000Z', - '2021-01-03T00:00:00.000Z', - '2021-01-02T00:00:00.000Z', - ]); + assert.deepEqual( + publishedDates.map((date) => date.toISOString()), + [ + '2021-01-01T00:00:00.000Z', + '2021-01-01T00:00:00.000Z', + '2021-01-03T00:00:00.000Z', + '2021-01-02T00:00:00.000Z', + ] + ); }); it('Returns `with custom slugs` collection', async () => { - expect(json).to.haveOwnProperty('withSlugConfig'); - expect(Array.isArray(json.withSlugConfig)).to.equal(true); + assert.ok(json.hasOwnProperty('withSlugConfig')); + assert.equal(Array.isArray(json.withSlugConfig), true); const slugs = json.withSlugConfig.map((item) => item.slug); - expect(slugs).to.deep.equal(['fancy-one', 'excellent-three', 'interesting-two']); + assert.deepEqual(slugs, ['fancy-one', 'excellent-three', 'interesting-two']); }); it('Returns `with union schema` collection', async () => { - expect(json).to.haveOwnProperty('withUnionSchema'); - expect(Array.isArray(json.withUnionSchema)).to.equal(true); + assert.ok(json.hasOwnProperty('withUnionSchema')); + assert.equal(Array.isArray(json.withUnionSchema), true); const post = json.withUnionSchema.find((item) => item.id === 'post.md'); - expect(post).to.not.be.undefined; - expect(post.data).to.deep.equal({ + assert.notEqual(post, undefined); + assert.deepEqual(post.data, { type: 'post', title: 'My Post', description: 'This is my post', }); const newsletter = json.withUnionSchema.find((item) => item.id === 'newsletter.md'); - expect(newsletter).to.not.be.undefined; - expect(newsletter.data).to.deep.equal({ + assert.notEqual(newsletter, undefined); + assert.deepEqual(newsletter.data, { type: 'newsletter', subject: 'My Newsletter', }); @@ -99,7 +104,7 @@ describe('Content Collections', () => { it('Applies styles', async () => { const html = await fixture.readFile('/propagation/index.html'); const $ = cheerio.load(html); - expect($('style').text()).to.include('content:"works!"'); + assert.equal($('style').text().includes('content:"works!"'), true); }); }); @@ -111,28 +116,29 @@ describe('Content Collections', () => { }); it('Returns `without config` collection entry', async () => { - expect(json).to.haveOwnProperty('columbiaWithoutConfig'); - expect(json.columbiaWithoutConfig.id).to.equal('columbia.md'); + assert.ok(json.hasOwnProperty('columbiaWithoutConfig')); + assert.equal(json.columbiaWithoutConfig.id, 'columbia.md'); }); it('Returns `with schema` collection entry', async () => { - expect(json).to.haveOwnProperty('oneWithSchemaConfig'); - expect(json.oneWithSchemaConfig.id).to.equal('one.md'); - expect(json.oneWithSchemaConfig.data.publishedAt instanceof Date).to.equal(true); - expect(json.oneWithSchemaConfig.data.publishedAt.toISOString()).to.equal( + assert.ok(json.hasOwnProperty('oneWithSchemaConfig')); + assert.equal(json.oneWithSchemaConfig.id, 'one.md'); + assert.equal(json.oneWithSchemaConfig.data.publishedAt instanceof Date, true); + assert.equal( + json.oneWithSchemaConfig.data.publishedAt.toISOString(), '2021-01-01T00:00:00.000Z' ); }); it('Returns `with custom slugs` collection entry', async () => { - expect(json).to.haveOwnProperty('twoWithSlugConfig'); - expect(json.twoWithSlugConfig.slug).to.equal('interesting-two'); + assert.ok(json.hasOwnProperty('twoWithSlugConfig')); + assert.equal(json.twoWithSlugConfig.slug, 'interesting-two'); }); it('Returns `with union schema` collection entry', async () => { - expect(json).to.haveOwnProperty('postWithUnionSchema'); - expect(json.postWithUnionSchema.id).to.equal('post.md'); - expect(json.postWithUnionSchema.data).to.deep.equal({ + assert.ok(json.hasOwnProperty('postWithUnionSchema')); + assert.equal(json.postWithUnionSchema.id, 'post.md'); + assert.deepEqual(json.postWithUnionSchema.data, { type: 'post', title: 'My Post', description: 'This is my post', @@ -174,7 +180,7 @@ describe('Content Collections', () => { it('Generates expected pages', async () => { for (const slug in blogSlugToContents) { - expect(fixture.pathExists(`/posts/${slug}`)).to.equal(true); + assert.equal(fixture.pathExists(`/posts/${slug}`), true); } }); @@ -182,7 +188,7 @@ describe('Content Collections', () => { for (const slug in blogSlugToContents) { const post = await fixture.readFile(`/posts/${slug}/index.html`); const $ = cheerio.load(post); - expect($('h1').text()).to.equal(blogSlugToContents[slug].title); + assert.equal($('h1').text(), blogSlugToContents[slug].title); } }); @@ -190,7 +196,8 @@ describe('Content Collections', () => { for (const slug in blogSlugToContents) { const post = await fixture.readFile(`/posts/${slug}/index.html`); const $ = cheerio.load(post); - expect($(blogSlugToContents[slug].element).text().trim()).to.equal( + assert.equal( + $(blogSlugToContents[slug].element).text().trim(), blogSlugToContents[slug].content ); } @@ -206,7 +213,7 @@ describe('Content Collections', () => { } catch (e) { error = e.message; } - expect(error).to.be.null; + assert.equal(error, null); }); }); describe('With config.mjs', () => { @@ -220,7 +227,7 @@ describe('Content Collections', () => { } catch (e) { error = e.message; } - expect(error).to.include('**title**: Expected type `"string"`, received "number"'); + assert.equal(error.includes('**title**: Expected type `"string"`, received "number"'), true); }); }); describe('With config.mts', () => { @@ -234,7 +241,7 @@ describe('Content Collections', () => { } catch (e) { error = e.message; } - expect(error).to.include('**title**: Expected type `"string"`, received "number"'); + assert.equal(error.includes('**title**: Expected type `"string"`, received "number"'), true); }); }); @@ -249,7 +256,7 @@ describe('Content Collections', () => { } catch (e) { error = e.message; } - expect(error).to.include('**title**: Required'); + assert.equal(error.includes('**title**: Required'), true); }); }); @@ -264,7 +271,7 @@ describe('Content Collections', () => { } catch (e) { error = e.message; } - expect(error).to.be.undefined; + assert.equal(error, undefined); // TODO: try to render a page }); }); @@ -289,7 +296,7 @@ describe('Content Collections', () => { for (const slug in blogSlugToContents) { const request = new Request('http://example.com/posts/' + slug); const response = await app.render(request); - expect(response.status).to.equal(200); + assert.equal(response.status, 200); } }); @@ -299,7 +306,7 @@ describe('Content Collections', () => { const response = await app.render(request); const body = await response.text(); const $ = cheerio.load(body); - expect($('h1').text()).to.equal(blogSlugToContents[slug].title); + assert.equal($('h1').text(), blogSlugToContents[slug].title); } }); @@ -309,7 +316,8 @@ describe('Content Collections', () => { const response = await app.render(request); const body = await response.text(); const $ = cheerio.load(body); - expect($(blogSlugToContents[slug].element).text().trim()).to.equal( + assert.equal( + $(blogSlugToContents[slug].element).text().trim(), blogSlugToContents[slug].content ); } @@ -329,13 +337,13 @@ describe('Content Collections', () => { it('Includes base in links', async () => { const html = await fixture.readFile('/docs/index.html'); const $ = cheerio.load(html); - expect($('link').attr('href')).to.satisfies((a) => a.startsWith('/docs')); + assert.equal($('link').attr('href').startsWith('/docs'), true); }); it('Includes base in hoisted scripts', async () => { const html = await fixture.readFile('/docs/index.html'); const $ = cheerio.load(html); - expect($('script').attr('src')).to.satisfies((a) => a.startsWith('/docs')); + assert.equal($('script').attr('src').startsWith('/docs'), true); }); }); }); diff --git a/packages/astro/test/core-image-infersize.test.js b/packages/astro/test/core-image-infersize.nodetest.js index 62f342230..44c571d17 100644 --- a/packages/astro/test/core-image-infersize.test.js +++ b/packages/astro/test/core-image-infersize.nodetest.js @@ -1,4 +1,5 @@ -import { expect } from 'chai'; +import assert from 'node:assert/strict'; +import { describe, before, after, it } from 'node:test'; import * as cheerio from 'cheerio'; import { Writable } from 'node:stream'; @@ -48,23 +49,26 @@ describe('astro:image:infersize', () => { it('Image component works', async () => { let $img = $('img'); - expect( - $img.attr('src').startsWith('/_image') && $img.attr('src').endsWith('f=webp') - ).to.equal(true); + assert.equal( + $img.attr('src').startsWith('/_image') && $img.attr('src').endsWith('f=webp'), + true + ); }); it('Picture component works', async () => { let $img = $('picture img'); - expect( - $img.attr('src').startsWith('/_image') && $img.attr('src').endsWith('f=png') - ).to.equal(true); + assert.equal( + $img.attr('src').startsWith('/_image') && $img.attr('src').endsWith('f=png'), + true + ); }); it('getImage works', async () => { let $img = $('#getImage'); - expect( - $img.attr('src').startsWith('/_image') && $img.attr('src').endsWith('f=webp') - ).to.equal(true); + assert.equal( + $img.attr('src').startsWith('/_image') && $img.attr('src').endsWith('f=webp'), + true + ); }); }); }); diff --git a/packages/astro/test/core-image-remark-imgattr.test.js b/packages/astro/test/core-image-remark-imgattr.nodetest.js index 791014329..936decfd2 100644 --- a/packages/astro/test/core-image-remark-imgattr.test.js +++ b/packages/astro/test/core-image-remark-imgattr.nodetest.js @@ -1,4 +1,5 @@ -import { expect } from 'chai'; +import assert from 'node:assert/strict'; +import { describe, before, after, it } from 'node:test'; import * as cheerio from 'cheerio'; import { Writable } from 'node:stream'; @@ -48,14 +49,12 @@ describe('astro:image', () => { it('Image has eager loading meaning getImage passed props it doesnt use through it', async () => { let $img = $('img'); - expect($img.attr('loading')).to.equal('eager'); + assert.equal($img.attr('loading'), 'eager'); }); it('Image src contains w=50 meaning getImage correctly used props added through the remark plugin', async () => { let $img = $('img'); - expect(new URL($img.attr('src'), 'http://example.com').searchParams.get('w')).to.equal( - '50' - ); + assert.equal(new URL($img.attr('src'), 'http://example.com').searchParams.get('w'), '50'); }); }); }); diff --git a/packages/astro/test/core-image.test.js b/packages/astro/test/core-image.nodetest.js index 1b5618349..561c7dc2e 100644 --- a/packages/astro/test/core-image.test.js +++ b/packages/astro/test/core-image.nodetest.js @@ -1,4 +1,5 @@ -import { expect } from 'chai'; +import assert from 'node:assert/strict'; +import { describe, before, after, it } from 'node:test'; import * as cheerio from 'cheerio'; import { basename } from 'node:path'; import { Writable } from 'node:stream'; @@ -56,57 +57,57 @@ describe('astro:image', () => { it('Adds the <img> tag', () => { let $img = $('#local img'); - expect($img).to.have.a.lengthOf(1); - expect($img.attr('src').startsWith('/_image')).to.equal(true); + assert.equal($img.length, 1); + assert.equal($img.attr('src').startsWith('/_image'), true); }); it('includes loading and decoding attributes', () => { let $img = $('#local img'); - expect(!!$img.attr('loading')).to.equal(true); - expect(!!$img.attr('decoding')).to.equal(true); + assert.equal(!!$img.attr('loading'), true); + assert.equal(!!$img.attr('decoding'), true); }); it('has width and height - no dimensions set', () => { let $img = $('#local img'); - expect($img.attr('width')).to.equal('207'); - expect($img.attr('height')).to.equal('243'); + assert.equal($img.attr('width'), '207'); + assert.equal($img.attr('height'), '243'); }); it('has proper width and height - only width', () => { let $img = $('#local-width img'); - expect($img.attr('width')).to.equal('350'); - expect($img.attr('height')).to.equal('411'); + assert.equal($img.attr('width'), '350'); + assert.equal($img.attr('height'), '411'); }); it('has proper width and height - only height', () => { let $img = $('#local-height img'); - expect($img.attr('width')).to.equal('170'); - expect($img.attr('height')).to.equal('200'); + assert.equal($img.attr('width'), '170'); + assert.equal($img.attr('height'), '200'); }); it('has proper width and height - has both width and height', () => { let $img = $('#local-both img'); - expect($img.attr('width')).to.equal('300'); - expect($img.attr('height')).to.equal('400'); + assert.equal($img.attr('width'), '300'); + assert.equal($img.attr('height'), '400'); }); it('includes the provided alt', () => { let $img = $('#local img'); - expect($img.attr('alt')).to.equal('a penguin'); + assert.equal($img.attr('alt'), 'a penguin'); }); it('middleware loads the file', async () => { let $img = $('#local img'); let src = $img.attr('src'); let res = await fixture.fetch(src); - expect(res.status).to.equal(200); + assert.equal(res.status, 200); }); it('returns proper content-type', async () => { let $img = $('#local img'); let src = $img.attr('src'); let res = await fixture.fetch(src); - expect(res.headers.get('content-type')).to.equal('image/webp'); + assert.equal(res.headers.get('content-type'), 'image/webp'); }); it('properly skip processing SVGs, but does not error', async () => { @@ -115,11 +116,11 @@ describe('astro:image', () => { $ = cheerio.load(html); let $img = $('img'); - expect($img).to.have.a.lengthOf(1); + assert.equal($img.length, 1); let src = $img.attr('src'); res = await fixture.fetch(src); - expect(res.status).to.equal(200); + assert.equal(res.status, 200); }); it("errors when an ESM imported image's src is passed to Image/getImage instead of the full import", async () => { @@ -127,8 +128,8 @@ describe('astro:image', () => { let res = await fixture.fetch('/error-image-src-passed'); await res.text(); - expect(logs).to.have.a.lengthOf(1); - expect(logs[0].message).to.contain('must be an imported image or an URL'); + assert.equal(logs.length, 1); + assert.equal(logs[0].message.includes('must be an imported image or an URL'), true); }); it('supports images from outside the project', async () => { @@ -137,15 +138,16 @@ describe('astro:image', () => { $ = cheerio.load(html); let $img = $('img'); - expect($img).to.have.a.lengthOf(2); - expect( + assert.equal($img.length, 2); + assert.equal( $img.toArray().every((img) => { return ( img.attribs['src'].startsWith('/@fs/') || img.attribs['src'].startsWith('/_image?href=%2F%40fs%2F') ); - }) - ).to.be.true; + }), + true + ); }); it('supports inlined imports', async () => { @@ -154,11 +156,11 @@ describe('astro:image', () => { $ = cheerio.load(html); let $img = $('img'); - expect($img).to.have.a.lengthOf(1); + assert.equal($img.length, 1); let src = $img.attr('src'); res = await fixture.fetch(src); - expect(res.status).to.equal(200); + assert.equal(res.status, 200); }); it('supports uppercased imports', async () => { @@ -167,13 +169,13 @@ describe('astro:image', () => { $ = cheerio.load(html); let $img = $('img'); - expect($img).to.have.a.lengthOf(1); + assert.equal($img.length, 1); let src = $img.attr('src'); let loading = $img.attr('loading'); res = await fixture.fetch(src); - expect(res.status).to.equal(200); - expect(loading).to.not.be.undefined; + assert.equal(res.status, 200); + assert.notEqual(loading, undefined); }); it('supports avif', async () => { @@ -182,12 +184,12 @@ describe('astro:image', () => { $ = cheerio.load(html); let $img = $('img'); - expect($img).to.have.a.lengthOf(1); + assert.equal($img.length, 1); let src = $img.attr('src'); res = await fixture.fetch(src); - expect(res.status).to.equal(200); - expect(res.headers.get('content-type')).to.equal('image/avif'); + assert.equal(res.status, 200); + assert.equal(res.headers.get('content-type'), 'image/avif'); }); it('has a working Picture component', async () => { @@ -197,38 +199,51 @@ describe('astro:image', () => { // Fallback format let $img = $('#picture-fallback img'); - expect($img).to.have.a.lengthOf(1); + assert.equal($img.length, 1); const imageURL = new URL($img.attr('src'), 'http://localhost'); - expect(imageURL.searchParams.get('f')).to.equal('jpeg'); - expect($img.attr('fallbackformat')).to.be.undefined; + assert.equal(imageURL.searchParams.get('f'), 'jpeg'); + assert.equal($img.attr('fallbackformat'), undefined); // Densities $img = $('#picture-density-2-format img'); let $picture = $('#picture-density-2-format picture'); let $source = $('#picture-density-2-format source'); - expect($img).to.have.a.lengthOf(1); - expect($picture).to.have.a.lengthOf(1); - expect($source).to.have.a.lengthOf(2); + assert.equal($img.length, 1); + assert.equal($picture.length, 1); + assert.equal($source.length, 2); const srcset = parseSrcset($source.attr('srcset')); - expect(srcset.every((src) => src.url.startsWith('/_image'))).to.equal(true); - expect(srcset.map((src) => src.d)).to.deep.equal([undefined, 2]); + assert.equal( + srcset.every((src) => src.url.startsWith('/_image')), + true + ); + assert.deepEqual( + srcset.map((src) => src.d), + [undefined, 2] + ); // Widths $img = $('#picture-widths img'); $picture = $('#picture-widths picture'); $source = $('#picture-widths source'); - expect($img).to.have.a.lengthOf(1); - expect($picture).to.have.a.lengthOf(1); - expect($source).to.have.a.lengthOf(1); - expect($source.attr('sizes')).to.equal( + assert.equal($img.length, 1); + assert.equal($picture.length, 1); + assert.equal($source.length, 1); + assert.equal( + $source.attr('sizes'), '(max-width: 448px) 400px, (max-width: 810px) 750px, 1050px' ); const srcset2 = parseSrcset($source.attr('srcset')); - expect(srcset2.every((src) => src.url.startsWith('/_image'))).to.equal(true); - expect(srcset2.map((src) => src.w)).to.deep.equal([207]); + assert.equal( + srcset2.every((src) => src.url.startsWith('/_image')), + true + ); + assert.deepEqual( + srcset2.map((src) => src.w), + [207] + ); }); it('properly deduplicate srcset images', async () => { @@ -237,52 +252,58 @@ describe('astro:image', () => { $ = cheerio.load(html); let localImage = $('#local-3-images img'); - expect( + assert.equal( new Set([ ...parseSrcset(localImage.attr('srcset')).map((src) => src.url), localImage.attr('src'), - ]).size - ).to.equal(3); + ]).size, + 3 + ); let remoteImage = $('#remote-3-images img'); - expect( + assert.equal( new Set([ ...parseSrcset(remoteImage.attr('srcset')).map((src) => src.url), remoteImage.attr('src'), - ]).size - ).to.equal(3); + ]).size, + 3 + ); let local1x = $('#local-1x img'); - expect( + assert.equal( new Set([ ...parseSrcset(local1x.attr('srcset')).map((src) => src.url), local1x.attr('src'), - ]).size - ).to.equal(1); + ]).size, + 1 + ); let remote1x = $('#remote-1x img'); - expect( + assert.equal( new Set([ ...parseSrcset(remote1x.attr('srcset')).map((src) => src.url), remote1x.attr('src'), - ]).size - ).to.equal(1); + ]).size, + 1 + ); let local2Widths = $('#local-2-widths img'); - expect( + assert.equal( new Set([ ...parseSrcset(local2Widths.attr('srcset')).map((src) => src.url), local2Widths.attr('src'), - ]).size - ).to.equal(2); + ]).size, + 2 + ); let remote2Widths = $('#remote-2-widths img'); - expect( + assert.equal( new Set([ ...parseSrcset(remote2Widths.attr('srcset')).map((src) => src.url), remote2Widths.attr('src'), - ]).size - ).to.equal(2); + ]).size, + 2 + ); }); }); @@ -299,17 +320,17 @@ describe('astro:image', () => { it('support ?url imports', () => { let $url = $('#url'); - expect($url.text()).to.equal('string'); + assert.equal($url.text(), 'string'); }); it('support ?raw imports', () => { let $raw = $('#raw'); - expect($raw.text()).to.equal('string'); + assert.equal($raw.text(), 'string'); }); it('support glob import as raw', () => { let $raw = $('#glob-import'); - expect($raw.text()).to.equal('string'); + assert.equal($raw.text(), 'string'); }); }); @@ -326,42 +347,43 @@ describe('astro:image', () => { let $img = $('#remote img'); let src = $img.attr('src'); - expect(src.startsWith('/_image?')).to.be.true; + assert.ok(src.startsWith('/_image?')); const imageRequest = await fixture.fetch(src); - expect(imageRequest.status).to.equal(200); + assert.equal(imageRequest.status, 200); }); it('includes the provided alt', async () => { let $img = $('#remote img'); - expect($img.attr('alt')).to.equal('fred'); + assert.equal($img.attr('alt'), 'fred'); }); it('includes loading and decoding attributes', () => { let $img = $('#remote img'); - expect(!!$img.attr('loading')).to.equal(true); - expect(!!$img.attr('decoding')).to.equal(true); + assert.equal(!!$img.attr('loading'), true); + assert.equal(!!$img.attr('decoding'), true); }); it('includes width and height attributes', () => { let $img = $('#remote img'); - expect(!!$img.attr('width')).to.equal(true); - expect(!!$img.attr('height')).to.equal(true); + assert.equal(!!$img.attr('width'), true); + assert.equal(!!$img.attr('height'), true); }); it('support data: URI', () => { let $img = $('#data-uri img'); - expect($img.attr('src')).to.equal( + assert.equal( + $img.attr('src'), 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAANCAYAAABy6+R8AAAAAXNSR0IArs4c6QAAAIRlWElmTU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAIdpAAQAAAABAAAAWgAAAAAAAABIAAAAAQAAAEgAAAABAAOgAQADAAAAAQABAACgAgAEAAAAAQAAAA2gAwAEAAAAAQAAAA0AAAAAWvB1rQAAAAlwSFlzAAALEwAACxMBAJqcGAAAAVlpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDYuMC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KGV7hBwAAAWJJREFUKBVtUDEsQ1EUve+1/SItKYMIkYpF06GJdGAwNFFGkxBEYupssRm6EpvJbpVoYhRd6FBikDSxYECsBpG25D/nvP/+p+Ik551z73v33feuyA/izq5CL8ET8ALcBolYIP+vd0ibX/yAT7uj2qkVzwWzUBa0nbacbkKJHi5dlYhXmARYeAS+MwCWA5FPqKIP/9IH/wiygMru5y5mcRYkPHYKP7gAPw4SDbCjRXMgRBJctM4t4ROriM2QSpmkeOtub6YfMYrZvelykbD1sxJVg+6AfKqURRKQLfA4JvoVWgIjDMNlGLVKZxNRFsZsoHGAgREZHKPlJEi2t7if3r2KKS9nVOo0rtNZ3yR7M/VGTqTy5Y4o/scWHBbKfIq0/eZ+x3850OZpaTTxlu/4D3ssuA72uxrYS2rFYjh+aRbmb24LpTVu1IqVKG8P/lmUEaNMxeh6fmquOhkMBE8JJ2yPfwPjdVhiDbiX6AAAAABJRU5ErkJggg==' ); - expect(!!$img.attr('width')).to.equal(true); - expect(!!$img.attr('height')).to.equal(true); + assert.equal(!!$img.attr('width'), true); + assert.equal(!!$img.attr('height'), true); }); it('support images from public', () => { let $img = $('#public img'); - expect($img.attr('src')).to.equal('/penguin3.jpg'); - expect(!!$img.attr('width')).to.equal(true); - expect(!!$img.attr('height')).to.equal(true); + assert.equal($img.attr('src'), '/penguin3.jpg'); + assert.equal(!!$img.attr('width'), true); + assert.equal(!!$img.attr('height'), true); }); }); @@ -370,8 +392,8 @@ describe('astro:image', () => { let res = await fixture.fetch('/remote-error-no-dimensions'); await res.text(); - expect(logs).to.have.a.lengthOf(1); - expect(logs[0].message).to.contain('Missing width and height attributes'); + assert.equal(logs.length, 1); + assert.equal(logs[0].message.includes('Missing width and height attributes'), true); }); it('error if no height', async () => { @@ -379,8 +401,8 @@ describe('astro:image', () => { let res = await fixture.fetch('/remote-error-no-height'); await res.text(); - expect(logs).to.have.a.lengthOf(1); - expect(logs[0].message).to.contain('Missing height attribute'); + assert.equal(logs.length, 1); + assert.equal(logs[0].message.includes('Missing height attribute'), true); }); it('supports aliases', async () => { @@ -389,8 +411,8 @@ describe('astro:image', () => { let $ = cheerio.load(html); let $img = $('img'); - expect($img).to.have.a.lengthOf(1); - expect($img.attr('src').includes('penguin1.jpg')).to.equal(true); + assert.equal($img.length, 1); + assert.equal($img.attr('src').includes('penguin1.jpg'), true); }); }); @@ -404,18 +426,19 @@ describe('astro:image', () => { it('Adds the <img> tag', () => { let $img = $('img'); - expect($img).to.have.a.lengthOf(2); + assert.equal($img.length, 2); // Verbose test for the full URL to make sure the image went through the full pipeline - expect( - $img.attr('src').startsWith('/_image') && $img.attr('src').endsWith('f=webp') - ).to.equal(true); + assert.equal( + $img.attr('src').startsWith('/_image') && $img.attr('src').endsWith('f=webp'), + true + ); }); it('has width and height attributes', () => { let $img = $('img'); - expect(!!$img.attr('width')).to.equal(true); - expect(!!$img.attr('height')).to.equal(true); + assert.equal(!!$img.attr('width'), true); + assert.equal(!!$img.attr('height'), true); }); it('Supports aliased paths', async () => { @@ -424,7 +447,7 @@ describe('astro:image', () => { $ = cheerio.load(html); let $img = $('img'); - expect($img.attr('src').startsWith('/_image')).to.equal(true); + assert.equal($img.attr('src').startsWith('/_image'), true); }); it('Supports special characters in file name', async () => { @@ -433,7 +456,7 @@ describe('astro:image', () => { $ = cheerio.load(html); let $img = $('img'); - expect($img.attr('src').startsWith('/_image')).to.equal(true); + assert.equal($img.attr('src').startsWith('/_image'), true); }); it('properly handles remote images', async () => { @@ -442,10 +465,10 @@ describe('astro:image', () => { $ = cheerio.load(html); let $img = $('img'); - expect($img).to.have.a.lengthOf(2); + assert.equal($img.length, 2); const remoteUrls = ['https://example.com/image.png', '/image.png']; $img.each((index, element) => { - expect(element.attribs['src']).to.equal(remoteUrls[index]); + assert.equal(element.attribs['src'], remoteUrls[index]); }); }); }); @@ -460,13 +483,13 @@ describe('astro:image', () => { it('Adds the <img> tag', () => { let $img = $('img'); - expect($img).to.have.a.lengthOf(1); - expect($img.attr('src').startsWith('/_image')).to.equal(true); + assert.equal($img.length, 1); + assert.equal($img.attr('src').startsWith('/_image'), true); }); it('includes the provided alt', () => { let $img = $('img'); - expect($img.attr('alt')).to.equal('a penguin'); + assert.equal($img.attr('alt'), 'a penguin'); }); }); @@ -480,52 +503,55 @@ describe('astro:image', () => { it('Adds the <img> tags', () => { let $img = $('img'); - expect($img).to.have.a.lengthOf(8); + assert.equal($img.length, 8); }); it('image in cc folder is processed', () => { let $imgs = $('img'); let $blogfolderimg = $($imgs[7]); - expect($blogfolderimg.attr('src')).to.include('blogfolder.jpg'); - expect($blogfolderimg.attr('src').endsWith('f=webp')).to.equal(true); + assert.equal($blogfolderimg.attr('src').includes('blogfolder.jpg'), true); + assert.equal($blogfolderimg.attr('src').endsWith('f=webp'), true); }); it('has proper source for directly used image', () => { let $img = $('#direct-image img'); - expect($img.attr('src').startsWith('/')).to.equal(true); + assert.equal($img.attr('src').startsWith('/'), true); }); it('has proper source for refined image', () => { let $img = $('#refined-image img'); - expect($img.attr('src').startsWith('/')).to.equal(true); + assert.equal($img.attr('src').startsWith('/'), true); }); it('has proper sources for array of images', () => { let $img = $('#array-of-images img'); const imgsSrcs = []; $img.each((i, img) => imgsSrcs.push(img.attribs['src'])); - expect($img).to.have.a.lengthOf(2); - expect(imgsSrcs.every((img) => img.startsWith('/'))).to.be.true; + assert.equal($img.length, 2); + assert.equal( + imgsSrcs.every((img) => img.startsWith('/')), + true + ); }); it('has proper attributes for optimized image through getImage', () => { let $img = $('#optimized-image-get-image img'); - expect($img.attr('src').startsWith('/_image')).to.equal(true); - expect($img.attr('width')).to.equal('207'); - expect($img.attr('height')).to.equal('243'); + assert.equal($img.attr('src').startsWith('/_image'), true); + assert.equal($img.attr('width'), '207'); + assert.equal($img.attr('height'), '243'); }); it('has proper attributes for optimized image through Image component', () => { let $img = $('#optimized-image-component img'); - expect($img.attr('src').startsWith('/_image')).to.equal(true); - expect($img.attr('width')).to.equal('207'); - expect($img.attr('height')).to.equal('243'); - expect($img.attr('alt')).to.equal('A penguin!'); + assert.equal($img.attr('src').startsWith('/_image'), true); + assert.equal($img.attr('width'), '207'); + assert.equal($img.attr('height'), '243'); + assert.equal($img.attr('alt'), 'A penguin!'); }); it('properly handles nested images', () => { let $img = $('#nested-image img'); - expect($img.attr('src').startsWith('/')).to.equal(true); + assert.equal($img.attr('src').startsWith('/'), true); }); }); @@ -539,11 +565,11 @@ describe('astro:image', () => { }); it('does not have a file url', async () => { - expect($('img').attr('src').startsWith('file://')).to.equal(false); + assert.equal($('img').attr('src').startsWith('file://'), false); }); it('includes /src in the path', async () => { - expect($('img').attr('src').includes('/src')).to.equal(true); + assert.equal($('img').attr('src').includes('/src'), true); }); }); @@ -553,7 +579,7 @@ describe('astro:image', () => { const html = await response.text(); const $ = cheerio.load(html); - expect($('#local img').attr('data-service')).to.equal('my-custom-service'); + assert.equal($('#local img').attr('data-service'), 'my-custom-service'); }); it('custom service works in Markdown', async () => { @@ -561,7 +587,7 @@ describe('astro:image', () => { const html = await response.text(); const $ = cheerio.load(html); - expect($('img').attr('data-service')).to.equal('my-custom-service'); + assert.equal($('img').attr('data-service'), 'my-custom-service'); }); it('gets service config', async () => { @@ -569,7 +595,7 @@ describe('astro:image', () => { const html = await response.text(); const $ = cheerio.load(html); - expect($('#local img').attr('data-service-config')).to.equal('bar'); + assert.equal($('#local img').attr('data-service-config'), 'bar'); }); }); @@ -603,8 +629,9 @@ describe('astro:image', () => { const src = $('#local img').attr('src'); let res = await customEndpointFixture.fetch(src); - expect(res.status).to.equal(200); - expect(await res.text()).to.equal( + assert.equal(res.status, 200); + assert.equal( + await res.text(), "You fool! I'm not a image endpoint at all, I just return this!" ); }); @@ -652,8 +679,8 @@ describe('astro:image', () => { let res = await fixture.fetch('/get-image-empty'); await res.text(); - expect(logs).to.have.a.lengthOf(1); - expect(logs[0].message).to.contain('Expected getImage() parameter'); + assert.equal(logs.length, 1); + assert.equal(logs[0].message.includes('Expected getImage() parameter'), true); }); it('properly error when src is undefined', async () => { @@ -661,8 +688,8 @@ describe('astro:image', () => { let res = await fixture.fetch('/get-image-undefined'); await res.text(); - expect(logs).to.have.a.lengthOf(1); - expect(logs[0].message).to.contain('Expected `src` property'); + assert.equal(logs.length, 1); + assert.equal(logs[0].message.includes('Expected `src` property'), true); }); it('properly error image in Markdown frontmatter is not found', async () => { @@ -670,16 +697,16 @@ describe('astro:image', () => { let res = await fixture.fetch('/blog/one'); await res.text(); - expect(logs).to.have.a.lengthOf(1); - expect(logs[0].message).to.contain('does not exist. Is the path correct?'); + assert.equal(logs.length, 1); + assert.equal(logs[0].message.includes('does not exist. Is the path correct?'), true); }); it('properly error image in Markdown content is not found', async () => { logs.length = 0; let res = await fixture.fetch('/post'); await res.text(); - expect(logs).to.have.a.lengthOf(1); - expect(logs[0].message).to.contain('Could not find requested image'); + assert.equal(logs.length, 1); + assert.equal(logs[0].message.includes('Could not find requested image'), true); }); }); @@ -699,40 +726,40 @@ describe('astro:image', () => { const html = await fixture.readFile('/index.html'); const $ = cheerio.load(html); const src = $('#local img').attr('src'); - expect(src.length).to.be.greaterThan(0); - expect(src.startsWith('/blog')).to.be.true; + assert.equal(src.length > 0, true); + assert.equal(src.startsWith('/blog'), true); }); it('has base path prefix when using getImage', async () => { const html = await fixture.readFile('/get-image/index.html'); const $ = cheerio.load(html); const src = $('img').attr('src'); - expect(src.length).to.be.greaterThan(0); - expect(src.startsWith('/blog')).to.be.true; + assert.equal(src.length > 0, true); + assert.equal(src.startsWith('/blog'), true); }); it('has base path prefix when using image directly', async () => { const html = await fixture.readFile('/direct/index.html'); const $ = cheerio.load(html); const src = $('img').attr('src'); - expect(src.length).to.be.greaterThan(0); - expect(src.startsWith('/blog')).to.be.true; + assert.equal(src.length > 0, true); + assert.equal(src.startsWith('/blog'), true); }); it('has base path prefix in Markdown', async () => { const html = await fixture.readFile('/post/index.html'); const $ = cheerio.load(html); const src = $('img').attr('src'); - expect(src.length).to.be.greaterThan(0); - expect(src.startsWith('/blog')).to.be.true; + assert.equal(src.length > 0, true); + assert.equal(src.startsWith('/blog'), true); }); it('has base path prefix in Content Collection frontmatter', async () => { const html = await fixture.readFile('/blog/one/index.html'); const $ = cheerio.load(html); const src = $('img').attr('src'); - expect(src.length).to.be.greaterThan(0); - expect(src.startsWith('/blog')).to.be.true; + assert.equal(src.length > 0, true); + assert.equal(src.startsWith('/blog'), true); }); it('has base path prefix in SSR', async () => { @@ -749,11 +776,11 @@ describe('astro:image', () => { const app = await fixtureWithBase.loadTestAdapterApp(); const request = new Request('http://example.com/blog/'); const response = await app.render(request); - expect(response.status).to.equal(200); + assert.equal(response.status, 200); const html = await response.text(); const $ = cheerio.load(html); const src = $('#local img').attr('src'); - expect(src.startsWith('/blog')).to.be.true; + assert.equal(src.startsWith('/blog'), true); }); }); @@ -776,25 +803,25 @@ describe('astro:image', () => { const html = await fixture.readFile('/index.html'); const $ = cheerio.load(html); const src = $('#local img').attr('src'); - expect(src.length).to.be.greaterThan(0); + assert.equal(src.length > 0, true); const data = await fixture.readFile(src, null); - expect(data).to.be.an.instanceOf(Buffer); + assert.equal(data instanceof Buffer, true); }); it('writes out allowed remote images', async () => { const html = await fixture.readFile('/remote/index.html'); const $ = cheerio.load(html); const src = $('#remote img').attr('src'); - expect(src.length).to.be.greaterThan(0); + assert.equal(src.length > 0, true); const data = await fixture.readFile(src, null); - expect(data).to.be.an.instanceOf(Buffer); + assert.equal(data instanceof Buffer, true); }); it('writes out images to dist folder with proper extension if no format was passed', async () => { const html = await fixture.readFile('/index.html'); const $ = cheerio.load(html); const src = $('#local img').attr('src'); - expect(src.endsWith('.webp')).to.be.true; + assert.equal(src.endsWith('.webp'), true); }); it('getImage() usage also written', async () => { @@ -803,13 +830,13 @@ describe('astro:image', () => { let $img = $('img'); // <img> tag - expect($img).to.have.a.lengthOf(1); - expect($img.attr('alt')).to.equal('a penguin'); + assert.equal($img.length, 1); + assert.equal($img.attr('alt'), 'a penguin'); // image itself const src = $img.attr('src'); const data = await fixture.readFile(src, null); - expect(data).to.be.an.instanceOf(Buffer); + assert.equal(data instanceof Buffer, true); }); it('Picture component images are written', async () => { @@ -818,8 +845,8 @@ describe('astro:image', () => { let $img = $('img'); let $source = $('source'); - expect($img).to.have.a.lengthOf(1); - expect($source).to.have.a.lengthOf(2); + assert.equal($img.length, 1); + assert.equal($source.length, 2); const srcset = parseSrcset($source.attr('srcset')); let hasExistingSrc = await Promise.all( @@ -829,7 +856,10 @@ describe('astro:image', () => { }) ); - expect(hasExistingSrc.every((src) => src === true)).to.deep.equal(true); + assert.deepEqual( + hasExistingSrc.every((src) => src === true), + true + ); }); it('markdown images are written', async () => { @@ -838,13 +868,13 @@ describe('astro:image', () => { let $img = $('img'); // <img> tag - expect($img).to.have.a.lengthOf(1); - expect($img.attr('alt')).to.equal('My article cover'); + assert.equal($img.length, 1); + assert.equal($img.attr('alt'), 'My article cover'); // image itself const src = $img.attr('src'); const data = await fixture.readFile(src, null); - expect(data).to.be.an.instanceOf(Buffer); + assert.equal(data instanceof Buffer, true); }); it('aliased images are written', async () => { @@ -854,13 +884,13 @@ describe('astro:image', () => { let $img = $('img'); // <img> tag - expect($img).to.have.a.lengthOf(1); - expect($img.attr('alt')).to.equal('A penguin!'); + assert.equal($img.length, 1); + assert.equal($img.attr('alt'), 'A penguin!'); // image itself const src = $img.attr('src'); const data = await fixture.readFile(src, null); - expect(data).to.be.an.instanceOf(Buffer); + assert.equal(data instanceof Buffer, true); }); it('aliased images in Markdown are written', async () => { @@ -870,13 +900,13 @@ describe('astro:image', () => { let $img = $('img'); // <img> tag - expect($img).to.have.a.lengthOf(1); - expect($img.attr('alt')).to.equal('A penguin'); + assert.equal($img.length, 1); + assert.equal($img.attr('alt'), 'A penguin'); // image itself const src = $img.attr('src'); const data = await fixture.readFile(src, null); - expect(data).to.be.an.instanceOf(Buffer); + assert.equal(data instanceof Buffer, true); }); it('output files for content collections images', async () => { @@ -884,33 +914,33 @@ describe('astro:image', () => { const $ = cheerio.load(html); let $img = $('img'); - expect($img).to.have.a.lengthOf(2); + assert.equal($img.length, 2); const srcdirect = $('#direct-image img').attr('src'); const datadirect = await fixture.readFile(srcdirect, null); - expect(datadirect).to.be.an.instanceOf(Buffer); + assert.equal(datadirect instanceof Buffer, true); const srcnested = $('#nested-image img').attr('src'); const datanested = await fixture.readFile(srcnested, null); - expect(datanested).to.be.an.instanceOf(Buffer); + assert.equal(datanested instanceof Buffer, true); }); it('quality attribute produces a different file', async () => { const html = await fixture.readFile('/quality/index.html'); const $ = cheerio.load(html); - expect($('#no-quality img').attr('src')).to.not.equal($('#quality-low img').attr('src')); + assert.notEqual($('#no-quality img').attr('src'), $('#quality-low img').attr('src')); }); it('quality can be a number between 0-100', async () => { const html = await fixture.readFile('/quality/index.html'); const $ = cheerio.load(html); - expect($('#no-quality img').attr('src')).to.not.equal($('#quality-num img').attr('src')); + assert.notEqual($('#no-quality img').attr('src'), $('#quality-num img').attr('src')); }); it('format attribute produces a different file', async () => { const html = await fixture.readFile('/format/index.html'); const $ = cheerio.load(html); - expect($('#no-format img').attr('src')).to.not.equal($('#format-avif img').attr('src')); + assert.notEqual($('#no-format img').attr('src'), $('#format-avif img').attr('src')); }); it('has cache entries', async () => { @@ -924,7 +954,7 @@ describe('astro:image', () => { .map((path) => basename(path).replace('.webp.json', '.webp')) .sort(); - expect(generatedImages).to.deep.equal(cachedImages); + assert.deepEqual(generatedImages, cachedImages); }); it('uses cache entries', async () => { @@ -946,7 +976,7 @@ describe('astro:image', () => { logLine.message.includes('(reused cache entry)') ); - expect(isReusingCache).to.be.true; + assert.equal(isReusingCache, true); }); it('client images are written to build', async () => { @@ -958,7 +988,7 @@ describe('astro:image', () => { const regex = /src:"([^"]*)/; const imageSrc = regex.exec($script.html())[1]; const data = await fixture.readFile(imageSrc, null); - expect(data).to.be.an.instanceOf(Buffer); + assert.equal(data instanceof Buffer, true); }); it('client images srcset parsed correctly', async () => { @@ -969,7 +999,7 @@ describe('astro:image', () => { // Find image const regex = /^(.+?) \d+[wx]$/m; const imageSrcset = regex.exec(srcset)[1]; - expect(imageSrcset).to.not.contain(' '); + assert.notEqual(imageSrcset.includes(' '), true); }); it('supports images with encoded characters in url', async () => { @@ -978,7 +1008,7 @@ describe('astro:image', () => { const img = $('#encoded-chars img'); const src = img.attr('src'); const data = await fixture.readFile(src); - expect(data).to.not.be.undefined; + assert.notEqual(data, undefined); }); describe('custom service in build', () => { @@ -992,15 +1022,20 @@ describe('astro:image', () => { .map((_, el) => $(el).attr('src')) .get(); - expect(allTheSamePath.every((path) => path === allTheSamePath[0])).to.equal(true); + assert.equal( + allTheSamePath.every((path) => path === allTheSamePath[0]), + true + ); const useCustomHashProperty = $('#use-data img') .map((_, el) => $(el).attr('src')) .get(); - expect(useCustomHashProperty.every((path) => path === useCustomHashProperty[0])).to.equal( + assert.equal( + useCustomHashProperty.every((path) => path === useCustomHashProperty[0]), false ); - expect(useCustomHashProperty[1]).to.not.equal(allTheSamePath[0]); + + assert.notEqual(useCustomHashProperty[1], useCustomHashProperty[0]); }); }); }); @@ -1026,7 +1061,7 @@ describe('astro:image', () => { it('does not interfere with query params', async () => { let res = await fixture.fetch('/api?src=image.png'); const html = await res.text(); - expect(html).to.equal('An image: "image.png"'); + assert.equal(html, 'An image: "image.png"'); }); }); @@ -1048,13 +1083,13 @@ describe('astro:image', () => { const app = await fixture.loadTestAdapterApp(); let request = new Request('http://example.com/'); let response = await app.render(request); - expect(response.status).to.equal(200); + assert.equal(response.status, 200); const html = await response.text(); const $ = cheerio.load(html); const src = $('#local img').attr('src'); request = new Request('http://example.com' + src); response = await app.render(request); - expect(response.status).to.equal(200); + assert.equal(response.status, 200); }); it('prerendered routes images are built', async () => { @@ -1062,7 +1097,7 @@ describe('astro:image', () => { const $ = cheerio.load(html); const src = $('img').attr('src'); const imgData = await fixture.readFile('/client' + src, null); - expect(imgData).to.be.an.instanceOf(Buffer); + assert.equal(imgData instanceof Buffer, true); }); }); }); diff --git a/packages/astro/test/custom-assets-name.test.js b/packages/astro/test/custom-assets-name.nodetest.js index c44116921..7f101cbf1 100644 --- a/packages/astro/test/custom-assets-name.test.js +++ b/packages/astro/test/custom-assets-name.nodetest.js @@ -1,4 +1,5 @@ -import { expect } from 'chai'; +import assert from 'node:assert/strict'; +import { describe, before, it } from 'node:test'; import { loadFixture } from './test-utils.js'; describe('custom the assets name function', () => { @@ -16,6 +17,6 @@ describe('custom the assets name function', () => { it('It cant find this file cause the node throws an error if the users custom a path that includes the folder path', async () => { const csslength = await fixture.readFile('client/assets/css/a.css'); /** @type {Set<string>} */ - expect(!!csslength).to.equal(true); + assert.equal(!!csslength, true); }); }); |