Repository: tatethurston/nextjs-routes
Pull request #54 (2022-08-08 17:03:07)

fix: strip double extensions
Previously, extensions such as `.test.tsx` would result in generated
paths that included the `.test` extension. Now, multiple levels of extensions are stripped and only one route is generated for any path overlaps.


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 325fcd1..5b9ce3d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@
 
 - Bug Fix: quote query segments in generated types. See [#49](https://github.com/tatethurston/nextjs-routes/issues/49) for more context.
 - Bug Fix: don't generate routes for non navigable routes (`_error`, `_app`, `_document`).
+- Bug Fix: don't generate routes for test files that are co-located in pages directory. See [#50](https://github.com/tatethurston/nextjs-routes/pull/50) for more context.
 
 ## 0.0.18
 
diff --git a/src/core.ts b/src/core.ts
index 20f0b1f..33a8b3f 100644
--- a/src/core.ts
+++ b/src/core.ts
@@ -1,5 +1,5 @@
 import { writeFileSync } from "fs";
-import { join, parse } from "path";
+import { join } from "path";
 import { findFiles, getPagesDirectory } from "./utils.js";
 
 const NEXTJS_NON_ROUTABLE = ["/_app", "/_document", "/_error", "/middleware"];
@@ -20,11 +20,13 @@ export function nextRoutes(files: string[], pagesDirectory: string): Route[] {
   const pathnames = files
     // remove page directory path
     .map((file) => file.replace(pagesDirectory, ""))
-    // remove file extension
-    .map((file) => file.replace(parse(file).ext, ""))
+    // remove file extensions (.tsx, .test.tsx)
+    .map((file) => file.replace(/(\.\w+)+$/, ""))
+    // remove duplicates from file extension removal (eg foo.ts and foo.test.ts)
+    .filter((file, idx, array) => array.indexOf(file) === idx)
     // normalize paths from windows users
     .map(convertWindowsPathToUnix)
-    // remove trailign slash
+    // remove index if present (/foos/index.ts is the same as /foos.ts)
     .map((file) => file.replace(/index$/, ""))
     // remove trailing slash if present
     .map((file) =>


Test patch:
diff --git a/e2e/package-lock.json b/e2e/package-lock.json
index d6e523e..4de423c 100644
--- a/e2e/package-lock.json
+++ b/e2e/package-lock.json
@@ -20,12 +20,15 @@
     },
     "../dist": {
       "name": "nextjs-routes",
-      "version": "0.0.17",
+      "version": "0.0.19",
       "dev": true,
       "license": "MIT",
       "bin": {
         "nextjs-routes": "cli.js"
       },
+      "devDependencies": {
+        "chokidar": "^3.5.3"
+      },
       "peerDependencies": {
         "next": "*"
       }
@@ -300,7 +303,9 @@
     },
     "nextjs-routes": {
       "version": "file:../dist",
-      "requires": {}
+      "requires": {
+        "chokidar": "^3.5.3"
+      }
     },
     "picocolors": {
       "version": "1.0.0"
diff --git a/src/core.test.ts b/src/core.test.ts
index 5dec838..02ca42f 100644
--- a/src/core.test.ts
+++ b/src/core.test.ts
@@ -24,6 +24,18 @@ describe("nextRoutes", () => {
     const { pathname } = nextRoutes(pages, "src\\pages")[0];
     expect(pathname).toEqual("/[foo]/bar");
   });
+
+  it("colocated test files", () => {
+    const pages = ["pages/index.tsx", "pages/index.test.tsx"];
+    expect(nextRoutes(pages, "pages")).toMatchInlineSnapshot(`
+      Array [
+        Object {
+          "pathname": "/",
+          "query": Object {},
+        },
+      ]
+    `);
+  });
 });
 
 describe("route generation", () => {