Repository: pmcelhaney/counterfact
Pull request #144 (2022-08-03 15:53:39)

128 simple api for simple response
- remove the reducer function, an early idea that was never documented
- clarification in test description
- support 'hello world' scenario returning just a string instead of a response object




Patch:
diff --git a/.changeset/purple-cups-greet.md b/.changeset/purple-cups-greet.md
new file mode 100644
index 0000000..896bef9
--- /dev/null
+++ b/.changeset/purple-cups-greet.md
@@ -0,0 +1,5 @@
+---
+"counterfact": minor
+---
+
+a function can now return "hello world" as shorthand for `{status: 200, contentType: "text/plain", body: "hello world"}`
diff --git a/src/dispatcher.js b/src/dispatcher.js
index 37499db..0895e11 100644
--- a/src/dispatcher.js
+++ b/src/dispatcher.js
@@ -8,20 +8,31 @@ export class Dispatcher {
   }
 
   request({ method, path, headers, body, query }) {
-    return this.registry.endpoint(
-      method,
-      path
-    )({
-      tools: new Tools({ headers }),
+    return this.wrapResponse(
+      this.registry.endpoint(
+        method,
+        path
+      )({
+        tools: new Tools({ headers }),
 
-      reduce: (reducer) => {
-        this.registry.context = reducer(this.registry.context);
-      },
+        context: this.registry.context,
+        body,
+        query,
+        headers,
+      })
+    );
+  }
+
+  wrapResponse(response) {
+    if (typeof response === "string") {
+      return {
+        status: 200,
+        headers: {},
+        contentType: "text/plain",
+        body: response,
+      };
+    }
 
-      context: this.registry.context,
-      body,
-      query,
-      headers,
-    });
+    return response;
   }
 }


Test patch:
diff --git a/test/dispatcher.test.js b/test/dispatcher.test.js
index ad8ab3c..4ea23e8 100644
--- a/test/dispatcher.test.js
+++ b/test/dispatcher.test.js
@@ -17,12 +17,34 @@ describe("a dispatcher", () => {
     const response = await dispatcher.request({
       method: "GET",
       path: "/hello",
-      body: "",
     });
 
     expect(response.body).toBe("hello");
   });
 
+  it("converts a string return value to a full response object with content-type text/plain", async () => {
+    const registry = new Registry();
+
+    registry.add("/hello", {
+      GET() {
+        return "hello";
+      },
+    });
+
+    const dispatcher = new Dispatcher(registry);
+    const response = await dispatcher.request({
+      method: "GET",
+      path: "/hello",
+    });
+
+    expect(response).toStrictEqual({
+      status: 200,
+      headers: {},
+      contentType: "text/plain",
+      body: "hello",
+    });
+  });
+
   it("passes the request body", async () => {
     const registry = new Registry();
 
@@ -155,41 +177,7 @@ describe("a dispatcher", () => {
     expect(response.status).toBe(201);
   });
 
-  it("passes a reducer function that can be used to read / update the store", async () => {
-    const registry = new Registry({ value: 0 });
-
-    registry.add("/increment/{value}", {
-      GET({ reduce, path }) {
-        const amountToIncrement = Number.parseInt(path.value, 10);
-
-        reduce((context) => ({
-          value: context.value + amountToIncrement,
-        }));
-
-        return { body: "incremented" };
-      },
-    });
-
-    const dispatcher = new Dispatcher(registry);
-
-    await dispatcher.request({
-      method: "GET",
-      path: "/increment/1",
-      body: "",
-    });
-
-    expect(registry.context.value).toBe(1);
-
-    await dispatcher.request({
-      method: "GET",
-      path: "/increment/2",
-      body: "",
-    });
-
-    expect(registry.context.value).toBe(3);
-  });
-
-  it("allows the store to be mutated directly", async () => {
+  it("allows the context object to be mutated directly", async () => {
     const registry = new Registry({ value: 0 });
 
     registry.add("/increment/{value}", {