diff --git a/.github/workflows/ci-bun-loaders.yml b/.github/workflows/ci-bun-loaders.yml new file mode 100644 index 000000000..18026ada2 --- /dev/null +++ b/.github/workflows/ci-bun-loaders.yml @@ -0,0 +1,36 @@ +name: Continuous Integration - Bun (Loaders) + +on: [pull_request] + +jobs: + build: + runs-on: ubuntu-latest + + strategy: + matrix: + node: [24] + + steps: + - name: Clone repository + uses: actions/checkout@v4 + + # still using Yarn since we specifically rely on Yarn workspaces + - name: Setup Node.js ${{ matrix.node }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node }} + + - name: Install Bun + uses: oven-sh/setup-bun@v2 + + - name: Disable Strict SSL + run: yarn config set strict-ssl false + + - name: Install Dependencies + run: yarn install --frozen-lockfile + + - name: Test + run: bun run --bun test:bun:loaders + + - name: Build + run: bun run --bun build diff --git a/.github/workflows/ci-bun.yml b/.github/workflows/ci-bun.yml new file mode 100644 index 000000000..d0b95c1d5 --- /dev/null +++ b/.github/workflows/ci-bun.yml @@ -0,0 +1,37 @@ +name: Continuous Integration - Bun +on: + pull_request: + branches: master + +jobs: + build: + runs-on: ubuntu-latest + + strategy: + matrix: + node: [24] + + steps: + - name: Clone repository + uses: actions/checkout@v4 + + # still using Yarn since we specifically rely on Yarn workspaces + - name: Setup Node.js ${{ matrix.node }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node }} + + - name: Install Bun + uses: oven-sh/setup-bun@v2 + + - name: Disable Strict SSL + run: yarn config set strict-ssl false + + - name: Install Dependencies + run: yarn install --frozen-lockfile + + - name: Test + run: bun run --bun test:bun + + - name: Build + run: bun run --bun build diff --git a/.mocharc.cjs b/.mocharc.cjs index 299c579d5..a394cbad8 100644 --- a/.mocharc.cjs +++ b/.mocharc.cjs @@ -1,3 +1,3 @@ module.exports = { - timeout: 90000, + timeout: 540000, }; diff --git a/package.json b/package.json index 96f1ef357..1fb01b9e4 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,8 @@ "test": "cross-env BROWSERSLIST_IGNORE_OLD_DATA=true __GWD_ROLLUP_MODE__=strict NODE_NO_WARNINGS=1 c8 mocha --exclude \"./packages/**/test/cases/loaders-*/**\" \"./packages/**/**/*.spec.js\"", "test:loaders": "cross-env BROWSERSLIST_IGNORE_OLD_DATA=true __GWD_ROLLUP_MODE__=strict NODE_NO_WARNINGS=1 node --import $(pwd)/test/test-register.js ./node_modules/mocha/bin/mocha \"./packages/**/**/*.spec.js\"", "test:loaders:win": "cross-env BROWSERSLIST_IGNORE_OLD_DATA=true __GWD_ROLLUP_MODE__=strict NODE_NO_WARNINGS=1 node --import file:\\\\%cd%\\test\\test-register.js ./node_modules/mocha/bin/mocha --exclude \"./packages/init/test/cases/**\" \"./packages/**/**/*.spec.js\"", + "test:bun": "cross-env BROWSERSLIST_IGNORE_OLD_DATA=true __GWD_ROLLUP_MODE__=strict NODE_NO_WARNINGS=1 mocha --exclude \"./packages/**/test/cases/loaders-*/**\" \"./packages/**/**/*.spec.js\"", + "test:bun:loaders": "cross-env BROWSERSLIST_IGNORE_OLD_DATA=true __GWD_ROLLUP_MODE__=strict NODE_NO_WARNINGS=1 node --import $(pwd)/test/test-register.js ./node_modules/mocha/bin/mocha \"./packages/**/**/*.spec.js\"", "test:tdd": "yarn test --watch", "lint": "yarn run lint:ls && yarn run lint:js && yarn run lint:types", "lint:js": "eslint", @@ -34,6 +36,9 @@ "format:check": "prettier . --check", "prepare": "husky" }, + "trustedDependencies": [ + "puppeteer" + ], "devDependencies": { "@babel/core": "^7.24.4", "@babel/eslint-parser": "^7.25.7", diff --git a/packages/cli/src/lib/resource-utils.js b/packages/cli/src/lib/resource-utils.js index dee4dc1f7..b2a2772a8 100644 --- a/packages/cli/src/lib/resource-utils.js +++ b/packages/cli/src/lib/resource-utils.js @@ -84,6 +84,10 @@ function normalizePathnameForWindows(url) { } async function checkResourceExists(url) { + if (url.pathname === "/") { + return false; + } + try { await fs.access(url); return true; diff --git a/packages/cli/src/lib/walker-package-ranger.js b/packages/cli/src/lib/walker-package-ranger.js index b38c074f0..385946c7b 100644 --- a/packages/cli/src/lib/walker-package-ranger.js +++ b/packages/cli/src/lib/walker-package-ranger.js @@ -92,7 +92,7 @@ async function walkExportPatterns(dependency, condition, resolvedRoot) { // https://app.unpkg.com/three@0.180.0/files/package.json const needle = condition.endsWith("/*") ? `${condition}*` : condition; const matches = fs.promises.glob(needle.startsWith("/") ? needle.replace("/", "") : needle, { - cwd: new URL(resolvedRoot), + cwd: new URL(resolvedRoot).pathname, }); for await (const match of matches) { diff --git a/packages/cli/src/plugins/resource/plugin-active-content.js b/packages/cli/src/plugins/resource/plugin-active-content.js index d0edaf1f7..4a573e34c 100644 --- a/packages/cli/src/plugins/resource/plugin-active-content.js +++ b/packages/cli/src/plugins/resource/plugin-active-content.js @@ -138,7 +138,7 @@ class ContentAsDataResource { async shouldOptimize(url, response) { const { activeContent } = this.compilation.config; - return response.headers.get("Content-Type").indexOf(this.contentType[0]) >= 0 && activeContent; + return response.headers.get("Content-Type")?.indexOf(this.contentType[0]) >= 0 && activeContent; } async optimize(url, response) { diff --git a/packages/cli/src/plugins/resource/plugin-node-modules.js b/packages/cli/src/plugins/resource/plugin-node-modules.js index 9c983a2f3..b3c920fef 100644 --- a/packages/cli/src/plugins/resource/plugin-node-modules.js +++ b/packages/cli/src/plugins/resource/plugin-node-modules.js @@ -41,17 +41,22 @@ class NodeModulesResource { } async shouldServe(url) { - const { href, protocol } = url; + const { href, protocol, pathname } = url; - return protocol === "file:" && (await checkResourceExists(new URL(href))); + return ( + protocol === "file:" && + pathname.indexOf("/node_modules/") >= 0 && + (await checkResourceExists(new URL(href))) + ); } - async serve(url) { + async serve(url, request) { const body = await fs.readFile(url, "utf-8"); + const contentType = request.headers.get("content-type") ?? this.contentType; return new Response(body, { headers: new Headers({ - "Content-Type": this.contentType, + "Content-Type": contentType, }), }); } diff --git a/packages/cli/test/cases/build.config.prerender-collections/build.config.prerender-collections.spec.js b/packages/cli/test/cases/build.config.prerender-collections/build.config.prerender-collections.spec.js index bc9047bb0..e3f1e96a4 100644 --- a/packages/cli/test/cases/build.config.prerender-collections/build.config.prerender-collections.spec.js +++ b/packages/cli/test/cases/build.config.prerender-collections/build.config.prerender-collections.spec.js @@ -166,30 +166,38 @@ describe("Build Greenwood With: ", function () { expect(linkItems.length).to.equal(2); }); + // we _technically_ can't assume the order of pages but we can at least make sure all the files are there + // this could easily be solved by adding an `order` property to the page's frontmatter + // https://github.com/ProjectEvergreen/greenwood/pull/1308#issuecomment-3368603613 it("should have the expected link content from all pages in the collection", function () { - expect(linkItems[0].getAttribute("href")).to.equal("/blog/"); - expect(linkItems[0].getAttribute("title")).to.equal("Blog"); - expect(linkItems[0].textContent).to.equal("Blog"); + const blogLink = Array.from(linkItems).find( + (link) => link.getAttribute("href") === "/blog/", + ); + const tocLink = Array.from(linkItems).find( + (link) => link.getAttribute("href") === "/toc/", + ); - expect(linkItems[1].getAttribute("href")).to.equal("/toc/"); - expect(linkItems[1].getAttribute("title")).to.equal("Table of Contents"); - expect(linkItems[1].textContent).to.equal("Table of Contents"); + expect(blogLink.getAttribute("title")).to.equal("Blog"); + expect(blogLink.textContent).to.equal("Blog"); + + expect(tocLink.getAttribute("title")).to.equal("Table of Contents"); + expect(tocLink.textContent).to.equal("Table of Contents"); }); it("should have the expected inline active frontmatter collection data", function () { const collection = JSON.parse( dom.window.document.querySelector("body span#footer").textContent, ); + const blogItem = collection.find((page) => page.route === "/blog/"); + const tocItem = collection.find((page) => page.route === "/toc/"); - expect(collection[0].route).to.equal("/blog/"); - expect(collection[0].title).to.equal("Blog"); - expect(collection[0].label).to.equal(collection[0].title); - expect(collection[0].id).to.equal("blog-index"); + expect(blogItem.title).to.equal("Blog"); + expect(blogItem.label).to.equal("Blog"); + expect(blogItem.id).to.equal("blog-index"); - expect(collection[1].route).to.equal("/toc/"); - expect(collection[1].title).to.equal("Table of Contents"); - expect(collection[1].label).to.equal(collection[1].title); - expect(collection[1].id).to.equal("toc"); + expect(tocItem.title).to.equal("Table of Contents"); + expect(tocItem.label).to.equal("Table of Contents"); + expect(tocItem.id).to.equal("toc"); }); }); }); @@ -212,14 +220,22 @@ describe("Build Greenwood With: ", function () { expect(postLinks.length).to.equal(2); }); + // we _technically_ can't assume the order of pages but we can at least make sure all the files are there + // this could easily be solved by adding an `order` property to the page's frontmatter + // https://github.com/ProjectEvergreen/greenwood/pull/1308#issuecomment-3368603613 it("should have the expected link content from all pages in the collection", function () { - expect(postLinks[0].getAttribute("href")).to.equal("/blog/first-post/"); - expect(postLinks[0].getAttribute("title")).to.equal("First Post"); - expect(postLinks[0].textContent).to.equal("First Post"); + const firstPostLink = Array.from(postLinks).find( + (link) => link.getAttribute("href") === "/blog/first-post/", + ); + const secondPostLink = Array.from(postLinks).find( + (link) => link.getAttribute("href") === "/blog/second-post/", + ); + + expect(firstPostLink.getAttribute("title")).to.equal("First Post"); + expect(firstPostLink.textContent).to.equal("First Post"); - expect(postLinks[1].getAttribute("href")).to.equal("/blog/second-post/"); - expect(postLinks[1].getAttribute("title")).to.equal("Second Post"); - expect(postLinks[1].textContent).to.equal("Second Post"); + expect(secondPostLink.getAttribute("title")).to.equal("Second Post"); + expect(secondPostLink.textContent).to.equal("Second Post"); }); }); }); diff --git a/packages/cli/test/cases/build.default.static-asset-bundling/build.default.static-asset-bundling.spec.js b/packages/cli/test/cases/build.default.static-asset-bundling/build.default.static-asset-bundling.spec.js index 4655a075f..78320dcf3 100644 --- a/packages/cli/test/cases/build.default.static-asset-bundling/build.default.static-asset-bundling.spec.js +++ b/packages/cli/test/cases/build.default.static-asset-bundling/build.default.static-asset-bundling.spec.js @@ -59,7 +59,7 @@ describe("Build Greenwood With: ", function () { before(async function () { const headerScripts = await Array.fromAsync( - fs.glob("header.*.js", { cwd: new URL("./public/", import.meta.url) }), + fs.glob("header.*.js", { cwd: new URL("./public/", import.meta.url).pathname }), ); headerContents = await fs.readFile( @@ -87,7 +87,7 @@ describe("Build Greenwood With: ", function () { before(async function () { assets = ( await Array.fromAsync( - fs.glob("**", { cwd: new URL("./public/assets/", import.meta.url) }), + fs.glob("**", { cwd: new URL("./public/assets/", import.meta.url).pathname }), ) ).filter((assets) => assets.indexOf(".") > 0); }); diff --git a/packages/cli/test/cases/build.default.workspace-nested-graph/build.default.workspace-nested-graph.spec.js b/packages/cli/test/cases/build.default.workspace-nested-graph/build.default.workspace-nested-graph.spec.js new file mode 100644 index 000000000..4edfccef5 --- /dev/null +++ b/packages/cli/test/cases/build.default.workspace-nested-graph/build.default.workspace-nested-graph.spec.js @@ -0,0 +1,158 @@ +/* + * Use Case + * Run Greenwood with default config and nested directories in workspace with lots of nested pages. + * + * Result + * Test for correctly ordered graph.json and pages output, which by default should mimic + * the filesystem order by default. + * + * Command + * greenwood build + * + * User Config + * { + * plugins: [greenwoodPluginMarkdown()] + * } + * + * User Workspace + * src/ + * pages/ + * blog/ + * 2017/ + * 03/26/index.html + * 03/30/index.html + * 2019/ + * 11/11/index.html + * index.html + * index.html + * 404.html + */ +import chai from "chai"; +import fs from "node:fs"; +import path from "node:path"; +import { getOutputTeardownFiles } from "../../../../../test/utils.js"; +import { runSmokeTest } from "../../../../../test/smoke-test.js"; +import { Runner } from "gallinago"; +import { fileURLToPath } from "node:url"; + +const expect = chai.expect; + +function generatePageHref(pagePath) { + return new URL(`./src/pages/${pagePath}`, import.meta.url).href; +} + +describe("Build Greenwood With: ", function () { + const LABEL = "Default Greenwood Configuration and Workspace w/ Nested Directories"; + const cliPath = path.join(process.cwd(), "packages/cli/src/bin.js"); + const outputPath = fileURLToPath(new URL(".", import.meta.url)); + let runner; + + before(function () { + this.context = { + publicDir: path.join(outputPath, "public"), + }; + runner = new Runner(); + }); + + describe(LABEL, function () { + before(function () { + runner.setup(outputPath); + runner.runCommand(cliPath, "build"); + }); + + runSmokeTest(["public", "index"], LABEL); + + describe("Expected Graph Contents", function () { + let graph; + + before(async function () { + graph = JSON.parse( + await fs.promises.readFile(path.join(this.context.publicDir, "graph.json"), "utf-8"), + ); + }); + + // we _technically_ can't assume the order of pages but we can at least make sure all the files are there + // this could easily be solved by adding an `order` property to the page's frontmatter + // https://github.com/ProjectEvergreen/greenwood/pull/1308#issuecomment-3368603613 + it("should have the expected ordering of pages in graph.json", function () { + expect(graph.length).to.equal(6); + + const page404 = graph.find((page) => page.route === "/404/"); + expect(page404.pageHref).to.equal(generatePageHref("404.html")); + expect(page404.id).to.be.equal("404"); + + const homePage = graph.find((page) => page.route === "/"); + expect(homePage.pageHref).to.equal(generatePageHref("index.html")); + expect(homePage.id).to.be.equal("index"); + + const blogPage = graph.find((page) => page.route === "/blog/"); + expect(blogPage.pageHref).to.equal(generatePageHref("blog/index.html")); + expect(blogPage.id).to.be.equal("blog-index"); + + const nestedPage = graph.find((page) => page.route === "/blog/2019/11/11/"); + expect(nestedPage.pageHref).to.equal(generatePageHref("blog/2019/11/11/index.html")); + expect(nestedPage.id).to.be.equal("blog-2019-11-11-index"); + }); + }); + + describe("Blog Pages Directory", function () { + let graph; + + before(async function () { + graph = JSON.parse( + await fs.promises.readFile(path.join(this.context.publicDir, "graph.json"), "utf-8"), + ); + }); + + it("should create a top level blog pages directory", function () { + expect(fs.existsSync(path.join(this.context.publicDir, "./blog"))).to.be.true; + }); + + it("should create a directory for each year of blog pages", function () { + expect(fs.existsSync(path.join(this.context.publicDir, "blog/2017"))).to.be.true; + expect(fs.existsSync(path.join(this.context.publicDir, "blog/2019"))).to.be.true; + }); + + it("should have the expected pages for 2017 blog pages", function () { + graph + .filter((page) => { + return page.route.indexOf("2017") > 0; + }) + .forEach((page) => { + const outputPath = path.join(this.context.publicDir, page.route, "index.html"); + expect(fs.existsSync(outputPath)).to.be.true; + }); + }); + + it("should have the expected pages for 2019 blog pages", function () { + graph + .filter((page) => { + return page.route.indexOf("2019") > 0; + }) + .forEach((page) => { + const outputPath = path.join(this.context.publicDir, page.route, "index.html"); + expect(fs.existsSync(outputPath)).to.be.true; + }); + }); + + it("should have the expected content for each blog page", function () { + graph + .filter((page) => { + return page.route.indexOf(/\/blog\/[0-9]{4}/) > 0; + }) + .forEach((page) => { + const contents = fs.readFileSync( + path.join(this.context.publicDir, page.route, "index.html"), + "utf-8", + ); + + expect(contents).to.contain(`
This is the post for page ${page.data.date}.
`); + }); + }); + }); + }); + + after(function () { + runner.teardown(getOutputTeardownFiles(outputPath)); + }); +}); diff --git a/packages/cli/test/cases/build.default.workspace-nested-graph/src/pages/404.html b/packages/cli/test/cases/build.default.workspace-nested-graph/src/pages/404.html new file mode 100644 index 000000000..7cf14d2e5 --- /dev/null +++ b/packages/cli/test/cases/build.default.workspace-nested-graph/src/pages/404.html @@ -0,0 +1,16 @@ + + + +This is the post for page 03.26.2017.
+ diff --git a/packages/cli/test/cases/build.default.workspace-nested-graph/src/pages/blog/2017/03/30/index.html b/packages/cli/test/cases/build.default.workspace-nested-graph/src/pages/blog/2017/03/30/index.html new file mode 100644 index 000000000..cd13e0fcc --- /dev/null +++ b/packages/cli/test/cases/build.default.workspace-nested-graph/src/pages/blog/2017/03/30/index.html @@ -0,0 +1,8 @@ +--- +title: "Lorum Ipsum" +date: "03.30.2017" +--- + + +This is the post for page 03.30.2017.
+ diff --git a/packages/cli/test/cases/build.default.workspace-nested-graph/src/pages/blog/2019/11/11/index.html b/packages/cli/test/cases/build.default.workspace-nested-graph/src/pages/blog/2019/11/11/index.html new file mode 100644 index 000000000..39656933d --- /dev/null +++ b/packages/cli/test/cases/build.default.workspace-nested-graph/src/pages/blog/2019/11/11/index.html @@ -0,0 +1,8 @@ +--- +title: "Lorum Ipsum" +date: "11.11.2019" +--- + + +This is the post for page 11.11.2019.
+ diff --git a/packages/cli/test/cases/build.default.workspace-nested-graph/src/pages/blog/index.html b/packages/cli/test/cases/build.default.workspace-nested-graph/src/pages/blog/index.html new file mode 100644 index 000000000..da1524850 --- /dev/null +++ b/packages/cli/test/cases/build.default.workspace-nested-graph/src/pages/blog/index.html @@ -0,0 +1,4 @@ + +See our blog posts!
+ diff --git a/packages/cli/test/cases/build.default.workspace-nested-graph/src/pages/index.html b/packages/cli/test/cases/build.default.workspace-nested-graph/src/pages/index.html new file mode 100644 index 000000000..471c741df --- /dev/null +++ b/packages/cli/test/cases/build.default.workspace-nested-graph/src/pages/index.html @@ -0,0 +1,5 @@ + + +This is the home page built by Greenwood. Make your own pages in src/pages/index.js!
+ + diff --git a/packages/cli/test/cases/develop.default/develop.default.spec.js b/packages/cli/test/cases/develop.default/develop.default.spec.js index 6487752d9..23a3bf323 100644 --- a/packages/cli/test/cases/develop.default/develop.default.spec.js +++ b/packages/cli/test/cases/develop.default/develop.default.spec.js @@ -531,7 +531,11 @@ describe("Develop Greenwood With: ", function () { let body; before(async function () { - response = await fetch(`${hostname}:${port}/node_modules/lit-html/lit-html.js.map`); + response = await fetch(`${hostname}:${port}/node_modules/lit-html/lit-html.js.map`, { + headers: { + "Content-Type": "application/json", // Essential for JSON bodies + }, + }); body = await response.clone().text(); }); @@ -799,6 +803,9 @@ describe("Develop Greenwood With: ", function () { response = await fetch(`${hostname}:${port}/api/submit-json`, { method: "POST", body: JSON.stringify({ name: param }), + headers: { + "Content-Type": "application/json", // Essential for JSON bodies + }, }); data = await response.json(); }); diff --git a/packages/cli/test/cases/serve.default.api/serve.default.api.spec.js b/packages/cli/test/cases/serve.default.api/serve.default.api.spec.js index be48ac92f..3a8a5ac92 100644 --- a/packages/cli/test/cases/serve.default.api/serve.default.api.spec.js +++ b/packages/cli/test/cases/serve.default.api/serve.default.api.spec.js @@ -183,6 +183,9 @@ describe("Serve Greenwood With: ", function () { before(async function () { response = await fetch(`${hostname}/api/submit-json`, { method: "POST", + headers: { + "Content-Type": "application/json", // Essential for JSON bodies + }, body: JSON.stringify({ name: param }), }); data = await response.clone().json(); diff --git a/packages/cli/test/cases/serve.default.api/src/pages/api/submit-json.js b/packages/cli/test/cases/serve.default.api/src/pages/api/submit-json.js index c73c35813..bd59cd62f 100644 --- a/packages/cli/test/cases/serve.default.api/src/pages/api/submit-json.js +++ b/packages/cli/test/cases/serve.default.api/src/pages/api/submit-json.js @@ -1,6 +1,6 @@ export async function handler(request) { - const formData = await request.json(); - const { name } = formData; + const data = await request.json(); + const { name } = data; const body = { message: `Thank you ${name} for your submission!` }; return new Response(JSON.stringify(body), { diff --git a/packages/cli/test/cases/serve.default.error/serve.default.error.spec.js b/packages/cli/test/cases/serve.default.error/serve.default.error.spec.js index 29939bc66..bb4977ee8 100644 --- a/packages/cli/test/cases/serve.default.error/serve.default.error.spec.js +++ b/packages/cli/test/cases/serve.default.error/serve.default.error.spec.js @@ -36,14 +36,10 @@ describe("Serve Greenwood With: ", function () { describe("Running the serve command without running the build command first", function () { it("should throw an error that no build output was detected", async function () { - try { - await runner.setup(outputPath); - await runner.runCommand(cliPath, "serve"); - } catch (err) { - expect(err).to.contain( - "Error: No build output detected. Make sure you have run greenwood build", - ); - } + await runner.setup(outputPath); + await expect(runner.runCommand(cliPath, "serve")).to.be.rejectedWith( + "No build output detected. Make sure you have run greenwood build", + ); }); }); diff --git a/packages/plugin-adapter-netlify/test/cases/build.default/build.default.spec.js b/packages/plugin-adapter-netlify/test/cases/build.default/build.default.spec.js index e0c702d86..2475ff6f6 100644 --- a/packages/plugin-adapter-netlify/test/cases/build.default/build.default.spec.js +++ b/packages/plugin-adapter-netlify/test/cases/build.default/build.default.spec.js @@ -681,21 +681,33 @@ describe("Build Greenwood With: ", function () { ); }); + // we _technically_ can't assume the order of pages but we can at least make sure all the files are there + // this could easily be solved by adding an `order` property to the page's frontmatter + // https://github.com/ProjectEvergreen/greenwood/pull/1308#issuecomment-3368603613 it("should return the expected response when the serverless adapter entry point handler is invoked", async function () { - expect(redirectsFileContents).to.be.equal( - `/artists/ /.netlify/functions/artists 200 -/blog/first-post/ /.netlify/functions/blog-first-post 200 -/blog/ /.netlify/functions/blog-index 200 -/ /.netlify/functions/index 200 -/post/ /.netlify/functions/post 200 -/users/ /.netlify/functions/users 200 -/api/fragment /.netlify/functions/api-fragment 200 -/api/greeting /.netlify/functions/api-greeting 200 -/api/nested/endpoint /.netlify/functions/api-nested-endpoint 200 -/api/search /.netlify/functions/api-search 200 -/api/submit-form-data /.netlify/functions/api-submit-form-data 200 -/api/submit-json /.netlify/functions/api-submit-json 200 -`, + expect(redirectsFileContents).to.contain("/artists/ /.netlify/functions/artists 200"); + expect(redirectsFileContents).to.contain( + "/blog/first-post/ /.netlify/functions/blog-first-post 200", + ); + expect(redirectsFileContents).to.contain("/blog/ /.netlify/functions/blog-index 200"); + expect(redirectsFileContents).to.contain("/ /.netlify/functions/index 200"); + expect(redirectsFileContents).to.contain("/post/ /.netlify/functions/post 200"); + expect(redirectsFileContents).to.contain("/users/ /.netlify/functions/users 200"); + expect(redirectsFileContents).to.contain( + "/api/fragment /.netlify/functions/api-fragment 200", + ); + expect(redirectsFileContents).to.contain( + "/api/greeting /.netlify/functions/api-greeting 200", + ); + expect(redirectsFileContents).to.contain( + "/api/nested/endpoint /.netlify/functions/api-nested-endpoint 200", + ); + expect(redirectsFileContents).to.contain("/api/search /.netlify/functions/api-search 200"); + expect(redirectsFileContents).to.contain( + "/api/submit-form-data /.netlify/functions/api-submit-form-data 200", + ); + expect(redirectsFileContents).to.contain( + "/api/submit-json /.netlify/functions/api-submit-json 200", ); }); }); diff --git a/packages/plugin-css-modules/test/cases/develop.default/develop.default.spec.js b/packages/plugin-css-modules/test/cases/develop.default/develop.default.spec.js index a4107a67e..b025e4e93 100644 --- a/packages/plugin-css-modules/test/cases/develop.default/develop.default.spec.js +++ b/packages/plugin-css-modules/test/cases/develop.default/develop.default.spec.js @@ -219,7 +219,7 @@ describe("Develop Greenwood With: ", function () { headerModuleText = await response.text(); modulesMaps = await Array.fromAsync( fs.promises.glob("*.map.json", { - cwd: new URL("./.greenwood/__css-modules-map/", import.meta.url), + cwd: new URL("./.greenwood/__css-modules-map/", import.meta.url).pathname, }), ); }); diff --git a/packages/plugin-graphql/test/cases/query-graph/query-graph.spec.js b/packages/plugin-graphql/test/cases/query-graph/query-graph.spec.js index e39e1fdfb..b72518609 100644 --- a/packages/plugin-graphql/test/cases/query-graph/query-graph.spec.js +++ b/packages/plugin-graphql/test/cases/query-graph/query-graph.spec.js @@ -97,14 +97,16 @@ describe("Build Greenwood With: ", function () { expect(lists.length).to.be.equal(1); }); + // we _technically_ can't assume the order of pages but we can at least make sure all the files are there + // this could easily be solved by adding an `order` property to the page's frontmatter + // https://github.com/ProjectEvergreen/greenwood/pull/1308#issuecomment-3368603613 it("should have a expected navigation output in the