Repository: pmcelhaney/counterfact
Pull request #556 (2023-09-06 19:35:31)

put generated files in a .cache directory
Counterfact traspiles code in the paths directory to another parallel directory. That directory was previously named "paths-js". There's no reason anyone should open that directory, but I can't put it in a temp directory because all of the relative paths would be messed up. In order to "hide" it, I renamed the directory to ".cache", added it to .gitignore, and added a README instructing users to pay no attention to the man behind the curtain. 


Patch:
diff --git a/.changeset/sweet-flies-play.md b/.changeset/sweet-flies-play.md
new file mode 100644
index 0000000..a966637
--- /dev/null
+++ b/.changeset/sweet-flies-play.md
@@ -0,0 +1,5 @@
+---
+"counterfact": minor
+---
+
+put generated JS code under a .cache directory and add that directory to .gitignore
diff --git a/package.json b/package.json
index 15b1ad1..55057d1 100644
--- a/package.json
+++ b/package.json
@@ -28,8 +28,8 @@
     "dist"
   ],
   "scripts": {
-    "test": "yarn node --experimental-vm-modules ./node_modules/jest-cli/bin/jest --testPathIgnorePatterns=black-box --detectOpenHandles",
-    "test:black-box": "rimraf dist && rimraf out && yarn build && yarn node --experimental-vm-modules ./node_modules/jest-cli/bin/jest black-box --detectOpenHandles --coverage=false",
+    "test": "yarn node --experimental-vm-modules ./node_modules/jest-cli/bin/jest --testPathIgnorePatterns=black-box --forceExit",
+    "test:black-box": "rimraf dist && rimraf out && yarn build && yarn node --experimental-vm-modules ./node_modules/jest-cli/bin/jest black-box --forceExit --coverage=false",
     "test:mutants": "stryker run stryker.config.json",
     "build": "tsc && copyfiles src/client/** dist && copyfiles templates/** dist",
     "prepack": "yarn build",
@@ -37,9 +37,9 @@
     "prepare": "husky install",
     "lint": "eslint . --plugin file-progress --rule 'file-progress/activate: 1'",
     "lint:quickfix": "eslint --fix . eslint --fix demo-ts --rule=\"import/namespace: 0,etc/no-deprecated:0,import/no-cycle:0,no-explicit-type-exports/no-explicit-type-exports:0,import/no-deprecated:0,import/no-self-import:0,import/default:0,import/no-named-as-default:0\"",
-    "go:petstore": "yarn counterfact https://petstore3.swagger.io/api/v3/openapi.json out",
-    "go:petstore2": "yarn counterfact  https://petstore.swagger.io/v2/swagger.json out",
-    "go:example": "yarn counterfact ./openapi-example.yaml out --open",
+    "go:petstore": "yarn build && yarn counterfact https://petstore3.swagger.io/api/v3/openapi.json out",
+    "go:petstore2": "yarn build && yarn counterfact  https://petstore.swagger.io/v2/swagger.json out",
+    "go:example": "yarn build && yarn counterfact ./openapi-example.yaml out",
     "counterfact": "./bin/counterfact.js",
     "postinstall": "patch-package"
   },
diff --git a/src/server/counterfact.ts b/src/server/counterfact.ts
index 5a7edd9..296d3a4 100644
--- a/src/server/counterfact.ts
+++ b/src/server/counterfact.ts
@@ -43,7 +43,7 @@ export async function counterfact(
   const dispatcher = new Dispatcher(registry, contextRegistry, openApiDocument);
 
   const compiledPathsDirectory = nodePath
-    .join(modulesPath, "paths-js")
+    .join(modulesPath, ".cache")
     .replaceAll("\\", "/");
 
   const transpiler = new Transpiler(
diff --git a/src/server/transpiler.ts b/src/server/transpiler.ts
index b9c8997..373f37d 100644
--- a/src/server/transpiler.ts
+++ b/src/server/transpiler.ts
@@ -1,25 +1,15 @@
 // Stryker disable all
 
 import { once } from "node:events";
-import { constants as fsConstants } from "node:fs";
 import fs from "node:fs/promises";
 import nodePath from "node:path";
 
 import { type FSWatcher, watch as chokidarWatch } from "chokidar";
 import ts from "typescript";
 
+import { ensureDirectoryExists } from "../util/ensure-directory-exists.js";
 import { CHOKIDAR_OPTIONS } from "./constants.js";
 
-async function ensureDirectoryExists(filePath: string): Promise<void> {
-  const directory = nodePath.dirname(filePath);
-
-  try {
-    await fs.access(directory, fsConstants.W_OK);
-  } catch {
-    await fs.mkdir(directory, { recursive: true });
-  }
-}
-
 export class Transpiler extends EventTarget {
   private readonly sourcePath: string;
 
@@ -88,7 +78,7 @@ export class Transpiler extends EventTarget {
     sourcePath: string,
     destinationPath: string,
   ): Promise<void> {
-    await ensureDirectoryExists(destinationPath);
+    ensureDirectoryExists(destinationPath);
 
     const source = await fs.readFile(sourcePath, "utf8");
 
@@ -107,6 +97,7 @@ export class Transpiler extends EventTarget {
       .replaceAll("\\", "/");
 
     try {
+      // eslint-disable-next-line total-functions/no-unsafe-readonly-mutable-assignment
       await fs.writeFile(fullDestination, result);
     } catch {
       throw new Error("could not transpile");
diff --git a/src/typescript-generator/generate.js b/src/typescript-generator/generate.js
index 18c891d..702e21b 100644
--- a/src/typescript-generator/generate.js
+++ b/src/typescript-generator/generate.js
@@ -1,11 +1,40 @@
+import { existsSync } from "node:fs";
+import fs from "node:fs/promises";
+import nodePath from "node:path";
+
 import createDebug from "debug";
 
+import { ensureDirectoryExists } from "../util/ensure-directory-exists.js";
 import { OperationCoder } from "./operation-coder.js";
 import { Repository } from "./repository.js";
 import { Specification } from "./specification.js";
 
 const debug = createDebug("counterfact:typescript-generator:generate");
 
+async function buildCacheDirectory(destination) {
+  const gitignorePath = nodePath.join(destination, ".gitignore");
+  const cacheReadmePath = nodePath.join(destination, ".cache", "README.md");
+
+  debug("got here");
+
+  await ensureDirectoryExists(gitignorePath);
+
+  debug("got here too");
+
+  if (!existsSync(gitignorePath)) {
+    await fs.writeFile(gitignorePath, ".cache\n", "utf8");
+  }
+
+  if (!existsSync(cacheReadmePath)) {
+    ensureDirectoryExists(cacheReadmePath);
+    await fs.writeFile(
+      cacheReadmePath,
+      "This directory contains compiled JS files from the paths directory. Do not edit these files directly.\n",
+      "utf8",
+    );
+  }
+}
+
 // eslint-disable-next-line max-statements
 export async function generate(
   source,
@@ -14,6 +43,10 @@ export async function generate(
 ) {
   debug("generating code from %s to %s", source, destination);
 
+  debug("initializing the .cache directory");
+  await buildCacheDirectory(destination);
+  debug("done initializing the .cache directory");
+
   debug("creating specification from %s", source);
 
   const specification = new Specification(source);
diff --git a/src/typescript-generator/repository.js b/src/typescript-generator/repository.js
index 6a70299..4f5c5af 100644
--- a/src/typescript-generator/repository.js
+++ b/src/typescript-generator/repository.js
@@ -1,10 +1,10 @@
-import { constants as fsConstants } from "node:fs";
 import fs from "node:fs/promises";
 import nodePath, { dirname } from "node:path";
 import { fileURLToPath } from "node:url";
 
 import createDebug from "debug";
 
+import { ensureDirectoryExists } from "../util/ensure-directory-exists.js";
 import { Script } from "./script.js";
 
 const debug = createDebug("counterfact:server:repository");
@@ -14,16 +14,6 @@ const __dirname = dirname(fileURLToPath(import.meta.url)).replaceAll("\\", "/");
 
 debug("dirname is %s", __dirname);
 
-async function ensureDirectoryExists(filePath) {
-  const directory = nodePath.dirname(filePath);
-
-  try {
-    await fs.access(directory, fsConstants.W_OK);
-  } catch {
-    await fs.mkdir(directory, { recursive: true });
-  }
-}
-
 export class Repository {
   constructor() {
     this.scripts = new Map();
diff --git a/src/util/ensure-directory-exists.js b/src/util/ensure-directory-exists.js
new file mode 100644
index 0000000..65d7e16
--- /dev/null
+++ b/src/util/ensure-directory-exists.js
@@ -0,0 +1,14 @@
+/* eslint-disable n/no-sync */
+import fs from "node:fs";
+import nodePath from "node:path";
+
+export function ensureDirectoryExists(filePath) {
+  const directory = nodePath.dirname(filePath);
+
+  try {
+    fs.accessSync(directory, fs.fsConstants.W_OK);
+  } catch {
+    // with the async option, await doesn't seem to wait for the directory to be created
+    fs.mkdirSync(directory, { recursive: true });
+  }
+}


Test patch:
diff --git a/test/black-box.test.js b/test/black-box.test.js
index 1f49e9e..986d4d4 100644
--- a/test/black-box.test.js
+++ b/test/black-box.test.js
@@ -62,7 +62,7 @@ describe("black box test", () => {
   });
 
   it("compiles kitty.ts", () => {
-    expect(fs.readFileSync("./out/paths-js/hello/kitty.mjs")).toMatchSnapshot();
+    expect(fs.readFileSync("./out/.cache/hello/kitty.mjs")).toMatchSnapshot();
   });
 
   it("responds to a GET request", async () => {
diff --git a/test/typescript-generator/__snapshots__/end-to-end.test.js.snap b/test/typescript-generator/__snapshots__/generate.test.ts.snap
similarity index 96%
rename from test/typescript-generator/__snapshots__/end-to-end.test.js.snap
rename to test/typescript-generator/__snapshots__/generate.test.ts.snap
index edcfd08..b52b741 100644
--- a/test/typescript-generator/__snapshots__/end-to-end.test.js.snap
+++ b/test/typescript-generator/__snapshots__/generate.test.ts.snap
@@ -202,7 +202,7 @@ class Context {
                 "exports": Map {
                   "Pet" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
+                    "code": "{\\"id\\"?: number,\\"name\\": string,\\"category\\"?: Category,\\"photoUrls\\": Array<string>,\\"tags\\"?: Array<Tag>,\\"status\\"?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -225,7 +225,7 @@ class Context {
                       "exports": Map {
                         "Category" => Object {
                           "beforeExport": "",
-                          "code": "{id?: number,name?: string}",
+                          "code": "{\\"id\\"?: number,\\"name\\"?: string}",
                           "done": true,
                           "id": "SchemaTypeCoder@undefined",
                           "isDefault": false,
@@ -256,7 +256,7 @@ class Context {
                       "exports": Map {
                         "Tag" => Object {
                           "beforeExport": "",
-                          "code": "{id?: number,name?: string}",
+                          "code": "{\\"id\\"?: number,\\"name\\"?: string}",
                           "done": true,
                           "id": "SchemaTypeCoder@undefined",
                           "isDefault": false,
@@ -457,7 +457,7 @@ class Context {
                 "exports": Map {
                   "Pet" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
+                    "code": "{\\"id\\"?: number,\\"name\\": string,\\"category\\"?: Category,\\"photoUrls\\": Array<string>,\\"tags\\"?: Array<Tag>,\\"status\\"?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -480,7 +480,7 @@ class Context {
                       "exports": Map {
                         "Category" => Object {
                           "beforeExport": "",
-                          "code": "{id?: number,name?: string}",
+                          "code": "{\\"id\\"?: number,\\"name\\"?: string}",
                           "done": true,
                           "id": "SchemaTypeCoder@undefined",
                           "isDefault": false,
@@ -511,7 +511,7 @@ class Context {
                       "exports": Map {
                         "Tag" => Object {
                           "beforeExport": "",
-                          "code": "{id?: number,name?: string}",
+                          "code": "{\\"id\\"?: number,\\"name\\"?: string}",
                           "done": true,
                           "id": "SchemaTypeCoder@undefined",
                           "isDefault": false,
@@ -716,7 +716,7 @@ class Context {
           "exports": Map {
             "Pet" => Object {
               "beforeExport": "",
-              "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
+              "code": "{\\"id\\"?: number,\\"name\\": string,\\"category\\"?: Category,\\"photoUrls\\": Array<string>,\\"tags\\"?: Array<Tag>,\\"status\\"?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
               "done": true,
               "id": "SchemaTypeCoder@undefined",
               "isDefault": false,
@@ -739,7 +739,7 @@ class Context {
                 "exports": Map {
                   "Category" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,name?: string}",
+                    "code": "{\\"id\\"?: number,\\"name\\"?: string}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -770,7 +770,7 @@ class Context {
                 "exports": Map {
                   "Tag" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,name?: string}",
+                    "code": "{\\"id\\"?: number,\\"name\\"?: string}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -910,7 +910,7 @@ class Context {
 }
 ",
                     "code": Object {
-                      "raw": "export { default } from \\"../$.context.js\\"",
+                      "raw": "export { default } from \\"../$.context.mjs\\"",
                     },
                     "done": true,
                     "id": "ContextCoder",
@@ -944,7 +944,7 @@ class Context {
                 "exports": Map {
                   "Pet" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
+                    "code": "{\\"id\\"?: number,\\"name\\": string,\\"category\\"?: Category,\\"photoUrls\\": Array<string>,\\"tags\\"?: Array<Tag>,\\"status\\"?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -967,7 +967,7 @@ class Context {
                       "exports": Map {
                         "Category" => Object {
                           "beforeExport": "",
-                          "code": "{id?: number,name?: string}",
+                          "code": "{\\"id\\"?: number,\\"name\\"?: string}",
                           "done": true,
                           "id": "SchemaTypeCoder@undefined",
                           "isDefault": false,
@@ -998,7 +998,7 @@ class Context {
                       "exports": Map {
                         "Tag" => Object {
                           "beforeExport": "",
-                          "code": "{id?: number,name?: string}",
+                          "code": "{\\"id\\"?: number,\\"name\\"?: string}",
                           "done": true,
                           "id": "SchemaTypeCoder@undefined",
                           "isDefault": false,
@@ -1121,7 +1121,7 @@ class Context {
 }
 ",
               "code": Object {
-                "raw": "export { default } from \\"../$.context.js\\"",
+                "raw": "export { default } from \\"../$.context.mjs\\"",
               },
               "done": true,
               "id": "ContextCoder",
@@ -1155,7 +1155,7 @@ class Context {
           "exports": Map {
             "Pet" => Object {
               "beforeExport": "",
-              "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
+              "code": "{\\"id\\"?: number,\\"name\\": string,\\"category\\"?: Category,\\"photoUrls\\": Array<string>,\\"tags\\"?: Array<Tag>,\\"status\\"?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
               "done": true,
               "id": "SchemaTypeCoder@undefined",
               "isDefault": false,
@@ -1178,7 +1178,7 @@ class Context {
                 "exports": Map {
                   "Category" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,name?: string}",
+                    "code": "{\\"id\\"?: number,\\"name\\"?: string}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -1209,7 +1209,7 @@ class Context {
                 "exports": Map {
                   "Tag" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,name?: string}",
+                    "code": "{\\"id\\"?: number,\\"name\\"?: string}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -1349,7 +1349,7 @@ class Context {
 }
 ",
                     "code": Object {
-                      "raw": "export { default } from \\"../$.context.js\\"",
+                      "raw": "export { default } from \\"../$.context.mjs\\"",
                     },
                     "done": true,
                     "id": "ContextCoder",
@@ -1383,7 +1383,7 @@ class Context {
                 "exports": Map {
                   "Pet" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
+                    "code": "{\\"id\\"?: number,\\"name\\": string,\\"category\\"?: Category,\\"photoUrls\\": Array<string>,\\"tags\\"?: Array<Tag>,\\"status\\"?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -1406,7 +1406,7 @@ class Context {
                       "exports": Map {
                         "Category" => Object {
                           "beforeExport": "",
-                          "code": "{id?: number,name?: string}",
+                          "code": "{\\"id\\"?: number,\\"name\\"?: string}",
                           "done": true,
                           "id": "SchemaTypeCoder@undefined",
                           "isDefault": false,
@@ -1437,7 +1437,7 @@ class Context {
                       "exports": Map {
                         "Tag" => Object {
                           "beforeExport": "",
-                          "code": "{id?: number,name?: string}",
+                          "code": "{\\"id\\"?: number,\\"name\\"?: string}",
                           "done": true,
                           "id": "SchemaTypeCoder@undefined",
                           "isDefault": false,
@@ -1560,7 +1560,7 @@ class Context {
 }
 ",
               "code": Object {
-                "raw": "export { default } from \\"../$.context.js\\"",
+                "raw": "export { default } from \\"../$.context.mjs\\"",
               },
               "done": true,
               "id": "ContextCoder",
@@ -1594,7 +1594,7 @@ class Context {
           "exports": Map {
             "Pet" => Object {
               "beforeExport": "",
-              "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
+              "code": "{\\"id\\"?: number,\\"name\\": string,\\"category\\"?: Category,\\"photoUrls\\": Array<string>,\\"tags\\"?: Array<Tag>,\\"status\\"?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
               "done": true,
               "id": "SchemaTypeCoder@undefined",
               "isDefault": false,
@@ -1617,7 +1617,7 @@ class Context {
                 "exports": Map {
                   "Category" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,name?: string}",
+                    "code": "{\\"id\\"?: number,\\"name\\"?: string}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -1648,7 +1648,7 @@ class Context {
                 "exports": Map {
                   "Tag" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,name?: string}",
+                    "code": "{\\"id\\"?: number,\\"name\\"?: string}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -1858,7 +1858,7 @@ class Context {
 }
 ",
                     "code": Object {
-                      "raw": "export { default } from \\"../$.context.js\\"",
+                      "raw": "export { default } from \\"../$.context.mjs\\"",
                     },
                     "done": true,
                     "id": "ContextCoder",
@@ -1892,7 +1892,7 @@ class Context {
                 "exports": Map {
                   "Pet" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
+                    "code": "{\\"id\\"?: number,\\"name\\": string,\\"category\\"?: Category,\\"photoUrls\\": Array<string>,\\"tags\\"?: Array<Tag>,\\"status\\"?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -1915,7 +1915,7 @@ class Context {
                       "exports": Map {
                         "Category" => Object {
                           "beforeExport": "",
-                          "code": "{id?: number,name?: string}",
+                          "code": "{\\"id\\"?: number,\\"name\\"?: string}",
                           "done": true,
                           "id": "SchemaTypeCoder@undefined",
                           "isDefault": false,
@@ -1946,7 +1946,7 @@ class Context {
                       "exports": Map {
                         "Tag" => Object {
                           "beforeExport": "",
-                          "code": "{id?: number,name?: string}",
+                          "code": "{\\"id\\"?: number,\\"name\\"?: string}",
                           "done": true,
                           "id": "SchemaTypeCoder@undefined",
                           "isDefault": false,
@@ -2109,7 +2109,7 @@ class Context {
 }
 ",
                     "code": Object {
-                      "raw": "export { default } from \\"../$.context.js\\"",
+                      "raw": "export { default } from \\"../$.context.mjs\\"",
                     },
                     "done": true,
                     "id": "ContextCoder",
@@ -2143,7 +2143,7 @@ class Context {
                 "exports": Map {
                   "Pet" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
+                    "code": "{\\"id\\"?: number,\\"name\\": string,\\"category\\"?: Category,\\"photoUrls\\": Array<string>,\\"tags\\"?: Array<Tag>,\\"status\\"?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -2166,7 +2166,7 @@ class Context {
                       "exports": Map {
                         "Category" => Object {
                           "beforeExport": "",
-                          "code": "{id?: number,name?: string}",
+                          "code": "{\\"id\\"?: number,\\"name\\"?: string}",
                           "done": true,
                           "id": "SchemaTypeCoder@undefined",
                           "isDefault": false,
@@ -2197,7 +2197,7 @@ class Context {
                       "exports": Map {
                         "Tag" => Object {
                           "beforeExport": "",
-                          "code": "{id?: number,name?: string}",
+                          "code": "{\\"id\\"?: number,\\"name\\"?: string}",
                           "done": true,
                           "id": "SchemaTypeCoder@undefined",
                           "isDefault": false,
@@ -2360,7 +2360,7 @@ class Context {
 }
 ",
                     "code": Object {
-                      "raw": "export { default } from \\"../$.context.js\\"",
+                      "raw": "export { default } from \\"../$.context.mjs\\"",
                     },
                     "done": true,
                     "id": "ContextCoder",
@@ -2394,7 +2394,7 @@ class Context {
                 "exports": Map {
                   "Pet" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
+                    "code": "{\\"id\\"?: number,\\"name\\": string,\\"category\\"?: Category,\\"photoUrls\\": Array<string>,\\"tags\\"?: Array<Tag>,\\"status\\"?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -2417,7 +2417,7 @@ class Context {
                       "exports": Map {
                         "Category" => Object {
                           "beforeExport": "",
-                          "code": "{id?: number,name?: string}",
+                          "code": "{\\"id\\"?: number,\\"name\\"?: string}",
                           "done": true,
                           "id": "SchemaTypeCoder@undefined",
                           "isDefault": false,
@@ -2448,7 +2448,7 @@ class Context {
                       "exports": Map {
                         "Tag" => Object {
                           "beforeExport": "",
-                          "code": "{id?: number,name?: string}",
+                          "code": "{\\"id\\"?: number,\\"name\\"?: string}",
                           "done": true,
                           "id": "SchemaTypeCoder@undefined",
                           "isDefault": false,
@@ -2615,7 +2615,7 @@ class Context {
 }
 ",
               "code": Object {
-                "raw": "export { default } from \\"../$.context.js\\"",
+                "raw": "export { default } from \\"../$.context.mjs\\"",
               },
               "done": true,
               "id": "ContextCoder",
@@ -2649,7 +2649,7 @@ class Context {
           "exports": Map {
             "Pet" => Object {
               "beforeExport": "",
-              "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
+              "code": "{\\"id\\"?: number,\\"name\\": string,\\"category\\"?: Category,\\"photoUrls\\": Array<string>,\\"tags\\"?: Array<Tag>,\\"status\\"?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
               "done": true,
               "id": "SchemaTypeCoder@undefined",
               "isDefault": false,
@@ -2672,7 +2672,7 @@ class Context {
                 "exports": Map {
                   "Category" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,name?: string}",
+                    "code": "{\\"id\\"?: number,\\"name\\"?: string}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -2703,7 +2703,7 @@ class Context {
                 "exports": Map {
                   "Tag" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,name?: string}",
+                    "code": "{\\"id\\"?: number,\\"name\\"?: string}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -2830,7 +2830,7 @@ class Context {
 }
 ",
                     "code": Object {
-                      "raw": "export { default } from \\"../$.context.js\\"",
+                      "raw": "export { default } from \\"../$.context.mjs\\"",
                     },
                     "done": true,
                     "id": "ContextCoder",
@@ -2862,7 +2862,7 @@ class Context {
                 "exports": Map {
                   "ApiResponse" => Object {
                     "beforeExport": "",
-                    "code": "{code?: number,type?: string,message?: string}",
+                    "code": "{\\"code\\"?: number,\\"type\\"?: string,\\"message\\"?: string}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -2963,7 +2963,7 @@ class Context {
 }
 ",
               "code": Object {
-                "raw": "export { default } from \\"../$.context.js\\"",
+                "raw": "export { default } from \\"../$.context.mjs\\"",
               },
               "done": true,
               "id": "ContextCoder",
@@ -2995,7 +2995,7 @@ class Context {
           "exports": Map {
             "ApiResponse" => Object {
               "beforeExport": "",
-              "code": "{code?: number,type?: string,message?: string}",
+              "code": "{\\"code\\"?: number,\\"type\\"?: string,\\"message\\"?: string}",
               "done": true,
               "id": "SchemaTypeCoder@undefined",
               "isDefault": false,
@@ -3112,7 +3112,7 @@ class Context {
 }
 ",
                     "code": Object {
-                      "raw": "export { default } from \\"../$.context.js\\"",
+                      "raw": "export { default } from \\"../$.context.mjs\\"",
                     },
                     "done": true,
                     "id": "ContextCoder",
@@ -3213,7 +3213,7 @@ class Context {
 }
 ",
               "code": Object {
-                "raw": "export { default } from \\"../$.context.js\\"",
+                "raw": "export { default } from \\"../$.context.mjs\\"",
               },
               "done": true,
               "id": "ContextCoder",
@@ -3338,7 +3338,7 @@ class Context {
 }
 ",
                     "code": Object {
-                      "raw": "export { default } from \\"../$.context.js\\"",
+                      "raw": "export { default } from \\"../$.context.mjs\\"",
                     },
                     "done": true,
                     "id": "ContextCoder",
@@ -3370,7 +3370,7 @@ class Context {
                 "exports": Map {
                   "Order" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,petId?: number,quantity?: number,shipDate?: string,status?: \\"placed\\" | \\"approved\\" | \\"delivered\\",complete?: boolean}",
+                    "code": "{\\"id\\"?: number,\\"petId\\"?: number,\\"quantity\\"?: number,\\"shipDate\\"?: string,\\"status\\"?: \\"placed\\" | \\"approved\\" | \\"delivered\\",\\"complete\\"?: boolean}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -3477,7 +3477,7 @@ class Context {
 }
 ",
               "code": Object {
-                "raw": "export { default } from \\"../$.context.js\\"",
+                "raw": "export { default } from \\"../$.context.mjs\\"",
               },
               "done": true,
               "id": "ContextCoder",
@@ -3509,7 +3509,7 @@ class Context {
           "exports": Map {
             "Order" => Object {
               "beforeExport": "",
-              "code": "{id?: number,petId?: number,quantity?: number,shipDate?: string,status?: \\"placed\\" | \\"approved\\" | \\"delivered\\",complete?: boolean}",
+              "code": "{\\"id\\"?: number,\\"petId\\"?: number,\\"quantity\\"?: number,\\"shipDate\\"?: string,\\"status\\"?: \\"placed\\" | \\"approved\\" | \\"delivered\\",\\"complete\\"?: boolean}",
               "done": true,
               "id": "SchemaTypeCoder@undefined",
               "isDefault": false,
@@ -3684,7 +3684,7 @@ class Context {
 }
 ",
                     "code": Object {
-                      "raw": "export { default } from \\"../$.context.js\\"",
+                      "raw": "export { default } from \\"../$.context.mjs\\"",
                     },
                     "done": true,
                     "id": "ContextCoder",
@@ -3716,7 +3716,7 @@ class Context {
                 "exports": Map {
                   "Order" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,petId?: number,quantity?: number,shipDate?: string,status?: \\"placed\\" | \\"approved\\" | \\"delivered\\",complete?: boolean}",
+                    "code": "{\\"id\\"?: number,\\"petId\\"?: number,\\"quantity\\"?: number,\\"shipDate\\"?: string,\\"status\\"?: \\"placed\\" | \\"approved\\" | \\"delivered\\",\\"complete\\"?: boolean}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -3857,7 +3857,7 @@ class Context {
 }
 ",
                     "code": Object {
-                      "raw": "export { default } from \\"../$.context.js\\"",
+                      "raw": "export { default } from \\"../$.context.mjs\\"",
                     },
                     "done": true,
                     "id": "ContextCoder",
@@ -3889,7 +3889,7 @@ class Context {
                 "exports": Map {
                   "Order" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,petId?: number,quantity?: number,shipDate?: string,status?: \\"placed\\" | \\"approved\\" | \\"delivered\\",complete?: boolean}",
+                    "code": "{\\"id\\"?: number,\\"petId\\"?: number,\\"quantity\\"?: number,\\"shipDate\\"?: string,\\"status\\"?: \\"placed\\" | \\"approved\\" | \\"delivered\\",\\"complete\\"?: boolean}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -4034,7 +4034,7 @@ class Context {
 }
 ",
               "code": Object {
-                "raw": "export { default } from \\"../$.context.js\\"",
+                "raw": "export { default } from \\"../$.context.mjs\\"",
               },
               "done": true,
               "id": "ContextCoder",
@@ -4066,7 +4066,7 @@ class Context {
           "exports": Map {
             "Order" => Object {
               "beforeExport": "",
-              "code": "{id?: number,petId?: number,quantity?: number,shipDate?: string,status?: \\"placed\\" | \\"approved\\" | \\"delivered\\",complete?: boolean}",
+              "code": "{\\"id\\"?: number,\\"petId\\"?: number,\\"quantity\\"?: number,\\"shipDate\\"?: string,\\"status\\"?: \\"placed\\" | \\"approved\\" | \\"delivered\\",\\"complete\\"?: boolean}",
               "done": true,
               "id": "SchemaTypeCoder@undefined",
               "isDefault": false,
@@ -4221,7 +4221,7 @@ class Context {
                 "exports": Map {
                   "User" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,username?: string,firstName?: string,lastName?: string,email?: string,password?: string,phone?: string,userStatus?: number}",
+                    "code": "{\\"id\\"?: number,\\"username\\"?: string,\\"firstName\\"?: string,\\"lastName\\"?: string,\\"email\\"?: string,\\"password\\"?: string,\\"phone\\"?: string,\\"userStatus\\"?: number}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -4359,7 +4359,7 @@ class Context {
           "exports": Map {
             "User" => Object {
               "beforeExport": "",
-              "code": "{id?: number,username?: string,firstName?: string,lastName?: string,email?: string,password?: string,phone?: string,userStatus?: number}",
+              "code": "{\\"id\\"?: number,\\"username\\"?: string,\\"firstName\\"?: string,\\"lastName\\"?: string,\\"email\\"?: string,\\"password\\"?: string,\\"phone\\"?: string,\\"userStatus\\"?: number}",
               "done": true,
               "id": "SchemaTypeCoder@undefined",
               "isDefault": false,
@@ -4490,7 +4490,7 @@ class Context {
 }
 ",
                     "code": Object {
-                      "raw": "export { default } from \\"../$.context.js\\"",
+                      "raw": "export { default } from \\"../$.context.mjs\\"",
                     },
                     "done": true,
                     "id": "ContextCoder",
@@ -4522,7 +4522,7 @@ class Context {
                 "exports": Map {
                   "User" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,username?: string,firstName?: string,lastName?: string,email?: string,password?: string,phone?: string,userStatus?: number}",
+                    "code": "{\\"id\\"?: number,\\"username\\"?: string,\\"firstName\\"?: string,\\"lastName\\"?: string,\\"email\\"?: string,\\"password\\"?: string,\\"phone\\"?: string,\\"userStatus\\"?: number}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -4636,7 +4636,7 @@ class Context {
 }
 ",
               "code": Object {
-                "raw": "export { default } from \\"../$.context.js\\"",
+                "raw": "export { default } from \\"../$.context.mjs\\"",
               },
               "done": true,
               "id": "ContextCoder",
@@ -4668,7 +4668,7 @@ class Context {
           "exports": Map {
             "User" => Object {
               "beforeExport": "",
-              "code": "{id?: number,username?: string,firstName?: string,lastName?: string,email?: string,password?: string,phone?: string,userStatus?: number}",
+              "code": "{\\"id\\"?: number,\\"username\\"?: string,\\"firstName\\"?: string,\\"lastName\\"?: string,\\"email\\"?: string,\\"password\\"?: string,\\"phone\\"?: string,\\"userStatus\\"?: number}",
               "done": true,
               "id": "SchemaTypeCoder@undefined",
               "isDefault": false,
@@ -4801,7 +4801,7 @@ class Context {
 }
 ",
                     "code": Object {
-                      "raw": "export { default } from \\"../$.context.js\\"",
+                      "raw": "export { default } from \\"../$.context.mjs\\"",
                     },
                     "done": true,
                     "id": "ContextCoder",
@@ -4918,7 +4918,7 @@ class Context {
 }
 ",
               "code": Object {
-                "raw": "export { default } from \\"../$.context.js\\"",
+                "raw": "export { default } from \\"../$.context.mjs\\"",
               },
               "done": true,
               "id": "ContextCoder",
@@ -5028,7 +5028,7 @@ class Context {
 }
 ",
                     "code": Object {
-                      "raw": "export { default } from \\"../$.context.js\\"",
+                      "raw": "export { default } from \\"../$.context.mjs\\"",
                     },
                     "done": true,
                     "id": "ContextCoder",
@@ -5123,7 +5123,7 @@ class Context {
 }
 ",
               "code": Object {
-                "raw": "export { default } from \\"../$.context.js\\"",
+                "raw": "export { default } from \\"../$.context.mjs\\"",
               },
               "done": true,
               "id": "ContextCoder",
@@ -5331,7 +5331,7 @@ class Context {
 }
 ",
                     "code": Object {
-                      "raw": "export { default } from \\"../$.context.js\\"",
+                      "raw": "export { default } from \\"../$.context.mjs\\"",
                     },
                     "done": true,
                     "id": "ContextCoder",
@@ -5363,7 +5363,7 @@ class Context {
                 "exports": Map {
                   "User" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,username?: string,firstName?: string,lastName?: string,email?: string,password?: string,phone?: string,userStatus?: number}",
+                    "code": "{\\"id\\"?: number,\\"username\\"?: string,\\"firstName\\"?: string,\\"lastName\\"?: string,\\"email\\"?: string,\\"password\\"?: string,\\"phone\\"?: string,\\"userStatus\\"?: number}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -5523,7 +5523,7 @@ class Context {
 }
 ",
                     "code": Object {
-                      "raw": "export { default } from \\"../$.context.js\\"",
+                      "raw": "export { default } from \\"../$.context.mjs\\"",
                     },
                     "done": true,
                     "id": "ContextCoder",
@@ -5555,7 +5555,7 @@ class Context {
                 "exports": Map {
                   "User" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,username?: string,firstName?: string,lastName?: string,email?: string,password?: string,phone?: string,userStatus?: number}",
+                    "code": "{\\"id\\"?: number,\\"username\\"?: string,\\"firstName\\"?: string,\\"lastName\\"?: string,\\"email\\"?: string,\\"password\\"?: string,\\"phone\\"?: string,\\"userStatus\\"?: number}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -5715,7 +5715,7 @@ class Context {
 }
 ",
                     "code": Object {
-                      "raw": "export { default } from \\"../$.context.js\\"",
+                      "raw": "export { default } from \\"../$.context.mjs\\"",
                     },
                     "done": true,
                     "id": "ContextCoder",
@@ -5747,7 +5747,7 @@ class Context {
                 "exports": Map {
                   "User" => Object {
                     "beforeExport": "",
-                    "code": "{id?: number,username?: string,firstName?: string,lastName?: string,email?: string,password?: string,phone?: string,userStatus?: number}",
+                    "code": "{\\"id\\"?: number,\\"username\\"?: string,\\"firstName\\"?: string,\\"lastName\\"?: string,\\"email\\"?: string,\\"password\\"?: string,\\"phone\\"?: string,\\"userStatus\\"?: number}",
                     "done": true,
                     "id": "SchemaTypeCoder@undefined",
                     "isDefault": false,
@@ -5911,7 +5911,7 @@ class Context {
 }
 ",
               "code": Object {
-                "raw": "export { default } from \\"../$.context.js\\"",
+                "raw": "export { default } from \\"../$.context.mjs\\"",
               },
               "done": true,
               "id": "ContextCoder",
@@ -5943,7 +5943,7 @@ class Context {
           "exports": Map {
             "User" => Object {
               "beforeExport": "",
-              "code": "{id?: number,username?: string,firstName?: string,lastName?: string,email?: string,password?: string,phone?: string,userStatus?: number}",
+              "code": "{\\"id\\"?: number,\\"username\\"?: string,\\"firstName\\"?: string,\\"lastName\\"?: string,\\"email\\"?: string,\\"password\\"?: string,\\"phone\\"?: string,\\"userStatus\\"?: number}",
               "done": true,
               "id": "SchemaTypeCoder@undefined",
               "isDefault": false,
@@ -6019,7 +6019,7 @@ class Context {
     "exports": Map {
       "Pet" => Object {
         "beforeExport": "",
-        "code": "{id?: number,name: string,category?: Category,photoUrls: Array<string>,tags?: Array<Tag>,status?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
+        "code": "{\\"id\\"?: number,\\"name\\": string,\\"category\\"?: Category,\\"photoUrls\\": Array<string>,\\"tags\\"?: Array<Tag>,\\"status\\"?: \\"available\\" | \\"pending\\" | \\"sold\\"}",
         "done": true,
         "id": "SchemaTypeCoder@undefined",
         "isDefault": false,
@@ -6042,7 +6042,7 @@ class Context {
           "exports": Map {
             "Category" => Object {
               "beforeExport": "",
-              "code": "{id?: number,name?: string}",
+              "code": "{\\"id\\"?: number,\\"name\\"?: string}",
               "done": true,
               "id": "SchemaTypeCoder@undefined",
               "isDefault": false,
@@ -6073,7 +6073,7 @@ class Context {
           "exports": Map {
             "Tag" => Object {
               "beforeExport": "",
-              "code": "{id?: number,name?: string}",
+              "code": "{\\"id\\"?: number,\\"name\\"?: string}",
               "done": true,
               "id": "SchemaTypeCoder@undefined",
               "isDefault": false,
@@ -6122,7 +6122,7 @@ class Context {
 }
 ",
         "code": Object {
-          "raw": "export { default } from \\"../$.context.js\\"",
+          "raw": "export { default } from \\"../$.context.mjs\\"",
         },
         "done": true,
         "id": "ContextCoder",
@@ -6163,7 +6163,7 @@ class Context {
 }
 ",
         "code": Object {
-          "raw": "export { default } from \\"../$.context.js\\"",
+          "raw": "export { default } from \\"../$.context.mjs\\"",
         },
         "done": true,
         "id": "ContextCoder",
@@ -6190,7 +6190,7 @@ class Context {
     "exports": Map {
       "ApiResponse" => Object {
         "beforeExport": "",
-        "code": "{code?: number,type?: string,message?: string}",
+        "code": "{\\"code\\"?: number,\\"type\\"?: string,\\"message\\"?: string}",
         "done": true,
         "id": "SchemaTypeCoder@undefined",
         "isDefault": false,
@@ -6230,7 +6230,7 @@ class Context {
 }
 ",
         "code": Object {
-          "raw": "export { default } from \\"../$.context.js\\"",
+          "raw": "export { default } from \\"../$.context.mjs\\"",
         },
         "done": true,
         "id": "ContextCoder",
@@ -6257,7 +6257,7 @@ class Context {
     "exports": Map {
       "Order" => Object {
         "beforeExport": "",
-        "code": "{id?: number,petId?: number,quantity?: number,shipDate?: string,status?: \\"placed\\" | \\"approved\\" | \\"delivered\\",complete?: boolean}",
+        "code": "{\\"id\\"?: number,\\"petId\\"?: number,\\"quantity\\"?: number,\\"shipDate\\"?: string,\\"status\\"?: \\"placed\\" | \\"approved\\" | \\"delivered\\",\\"complete\\"?: boolean}",
         "done": true,
         "id": "SchemaTypeCoder@undefined",
         "isDefault": false,
@@ -6297,7 +6297,7 @@ class Context {
 }
 ",
         "code": Object {
-          "raw": "export { default } from \\"../$.context.js\\"",
+          "raw": "export { default } from \\"../$.context.mjs\\"",
         },
         "done": true,
         "id": "ContextCoder",
@@ -6324,7 +6324,7 @@ class Context {
     "exports": Map {
       "User" => Object {
         "beforeExport": "",
-        "code": "{id?: number,username?: string,firstName?: string,lastName?: string,email?: string,password?: string,phone?: string,userStatus?: number}",
+        "code": "{\\"id\\"?: number,\\"username\\"?: string,\\"firstName\\"?: string,\\"lastName\\"?: string,\\"email\\"?: string,\\"password\\"?: string,\\"phone\\"?: string,\\"userStatus\\"?: number}",
         "done": true,
         "id": "SchemaTypeCoder@undefined",
         "isDefault": false,
@@ -6364,7 +6364,7 @@ class Context {
 }
 ",
         "code": Object {
-          "raw": "export { default } from \\"../$.context.js\\"",
+          "raw": "export { default } from \\"../$.context.mjs\\"",
         },
         "done": true,
         "id": "ContextCoder",
@@ -6391,7 +6391,7 @@ class Context {
     "exports": Map {
       "Category" => Object {
         "beforeExport": "",
-        "code": "{id?: number,name?: string}",
+        "code": "{\\"id\\"?: number,\\"name\\"?: string}",
         "done": true,
         "id": "SchemaTypeCoder@undefined",
         "isDefault": false,
@@ -6417,7 +6417,7 @@ class Context {
     "exports": Map {
       "Tag" => Object {
         "beforeExport": "",
-        "code": "{id?: number,name?: string}",
+        "code": "{\\"id\\"?: number,\\"name\\"?: string}",
         "done": true,
         "id": "SchemaTypeCoder@undefined",
         "isDefault": false,
@@ -6438,3 +6438,13 @@ class Context {
   },
 }
 `;
+
+exports[`end-to-end test generates the same code for pet store that it did on the last test run 2`] = `
+".cache
+"
+`;
+
+exports[`end-to-end test generates the same code for pet store that it did on the last test run 3`] = `
+"This directory contains compiled JS files from the paths directory. Do not edit these files directly.
+"
+`;
diff --git a/test/typescript-generator/end-to-end.test.js b/test/typescript-generator/end-to-end.test.js
deleted file mode 100644
index e83087b..0000000
--- a/test/typescript-generator/end-to-end.test.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/* eslint-disable jest/no-disabled-tests */
-/* eslint-disable jest/no-restricted-matchers */
-
-import { generate } from "../../src/typescript-generator/generate.js";
-import { Repository } from "../../src/typescript-generator/repository.js";
-
-describe("end-to-end test", () => {
-  // Skip because it fails on Windows and I can't figure out why
-
-  it.skip("generates the same code for pet store that it did on the last test run", async () => {
-    const repository = new Repository();
-
-    repository.writeFiles = () => "noop";
-
-    await generate("./petstore.yaml", "./dist", repository);
-    await repository.finished();
-
-    expect(repository.scripts).toMatchSnapshot();
-  });
-});
diff --git a/test/typescript-generator/generate.test.ts b/test/typescript-generator/generate.test.ts
new file mode 100644
index 0000000..34698ae
--- /dev/null
+++ b/test/typescript-generator/generate.test.ts
@@ -0,0 +1,36 @@
+import fs from "node:fs/promises";
+import nodePath from "node:path";
+
+import { generate } from "../../src/typescript-generator/generate.js";
+import { Repository } from "../../src/typescript-generator/repository.js";
+import { withTemporaryFiles } from "../lib/with-temporary-files.js";
+
+describe("end-to-end test", () => {
+  // Skip because it fails on Windows and I can't figure out why
+
+  it("generates the same code for pet store that it did on the last test run", async () => {
+    await withTemporaryFiles({}, async (basePath) => {
+      const repository = new Repository();
+
+      repository.writeFiles = async () => {
+        await Promise.resolve(undefined);
+      };
+
+      await generate("./petstore.yaml", basePath, repository);
+      await repository.finished();
+
+      expect(repository.scripts).toMatchSnapshot();
+
+      expect(
+        await fs.readFile(nodePath.join(basePath, ".gitignore"), "utf8"),
+      ).toMatchSnapshot();
+
+      expect(
+        await fs.readFile(
+          nodePath.join(basePath, ".cache", "README.md"),
+          "utf8",
+        ),
+      ).toMatchSnapshot();
+    });
+  });
+});