counterfact 0.10.2 → 0.10.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # counterfact
2
2
 
3
+ ## 0.10.3
4
+
5
+ ### Patch Changes
6
+
7
+ - f1360ba: made the generated code a bit cleaner
8
+
3
9
  ## 0.10.2
4
10
 
5
11
  ### Patch Changes
package/README.md CHANGED
@@ -1,44 +1,99 @@
1
+
2
+ <div align="right">
3
+
4
+ [![Coverage Status](https://coveralls.io/repos/github/pmcelhaney/counterfact/badge.svg)](https://coveralls.io/github/pmcelhaney/counterfact) [![Mutation testing badge](https://img.shields.io/endpoint?style=flat&url=https%3A%2F%2Fbadge-api.stryker-mutator.io%2Fgithub.com%2Fpmcelhaney%2Fcounterfact%2Fmain)](https://dashboard.stryker-mutator.io/reports/github.com/pmcelhaney/counterfact/main) ![MIT License](https://img.shields.io/badge/license-MIT-blue)
5
+
6
+
7
+ </div>
8
+
9
+ <div align="center">
10
+
1
11
  # Counterfact
2
12
 
3
- [![Coverage Status](https://coveralls.io/repos/github/pmcelhaney/counterfact/badge.svg)](https://coveralls.io/github/pmcelhaney/counterfact)
13
+ _Front end development without back end headaches_
14
+
15
+
16
+
17
+
18
+ [Watch Demo](#watch-demo) | [Quick Start](#quick-start) | [Documentation](#documentation) | [Support](#support)
19
+
20
+
21
+
22
+ </div>
23
+
24
+
25
+
26
+ <div align="center">
27
+ Counterfact is a stand-in REST server powered by Node, TypeScript, and OpenAPI.<br>It simulates complex, stateful back end behavior without running the whole stack.
28
+ </div>
29
+
30
+ <br>
31
+
32
+ <table align="center" cols="2">
33
+
34
+ <tr>
35
+ <td>
36
+
37
+ 💪 build the UI before the API or build both in parallel<br>
38
+ 🏎️ quickly and cheaply prototype UX workflows<br>
39
+ 🎉 turn OpenAPI docs into functional code
40
+
41
+ </td>
42
+
43
+ <td>
44
+
45
+ ⛓️ write fast, repeatable UI integration tests<br>
46
+ 🧑‍🔬 test UI code against hard-to-recreate edge cases<br>
47
+ 🔌 plug into your existing toolchain
48
+
49
+ </td>
50
+
51
+ </tr>
52
+
53
+ </table>
54
+
55
+
56
+ <div id="watch-demo" align="center">
4
57
 
5
- [![Mutation testing badge](https://img.shields.io/endpoint?style=flat&url=https%3A%2F%2Fbadge-api.stryker-mutator.io%2Fgithub.com%2Fpmcelhaney%2Fcounterfact%2Fmain)](https://dashboard.stryker-mutator.io/reports/github.com/pmcelhaney/counterfact/main)
58
+ ```
6
59
 
7
- > This project is a work in progress. As of September 18, 2022, most of the plumbing is in place but the [APIs are still solidifying](https://github.com/pmcelhaney/counterfact/issues/204) and it's not quite ready for day-to-day use. See the [Version 1.0](https://github.com/pmcelhaney/counterfact/milestone/3) and [Future](https://github.com/pmcelhaney/counterfact/milestone/5) milestones.
8
60
 
9
61
 
10
- ## What is Counterfact?
11
62
 
12
- Counterfact automatically builds a reference implementation of your [OpenAPI](https://www.openapis.org/) document. It uses metadata from the OpenAPI document to generate random, valid responses.
13
63
 
14
- ## Okay, tools already exist that can do that. Why build another?
64
+ video will go here
15
65
 
16
- Counterfact generates **TypeScript** code that you can **edit** to replace the random responses with real implementations.
17
66
 
18
- ## What do you mean "real" implementation?
19
67
 
20
- That's up to you! You can build a fully functional back-end if you like. Connect to a MongoDB, call other APIs, etc.
21
68
 
22
- While it may be tempting to do so because it's so easy, we don't recommend using Counterfact for production. It's designed for building a **fake back end** so you can **test your front end**.
69
+ ```
70
+ </div>
23
71
 
24
- ## What do you mean by "fake" implementation?
25
72
 
26
- For example, say you want to make sure the UI behaves properly if the server returns a `503 Service Unavailable` response to a particular endpoint. That can be quite a hassle when production code. With Counterfact, it's a matter of changing the `POST()` function in `./paths/path/to/endpoint.ts` to `return {status: 503}`. Run your test and then back out the change. It doesn't take much longer than it took you to read this paragraph. _This can all be done without restarting the server._
73
+ ## Quick Start
27
74
 
28
- Say you want to implement just enough of `POST` and `GET` so that after the front end posts an item, it can get the same item. But you don't want to go to the trouble of building a database for testing. Counterfact has APIs that makes building a simple in-memory implementation easy.
75
+ Try it now with one command. The only prequisite is Node 16+.
29
76
 
30
- ## You said TypeScript. Does it use the OpenAPI data to generate types?
77
+ ```sh copy
78
+ npx counterfact@latest https://petstore3.swagger.io/api/v3/openapi.json api --open
79
+ ```
31
80
 
32
- It sure does!
81
+ ### What does it do?
33
82
 
34
- ## Can I use those types in my front end?
83
+ 1. installs the `@latest` version of `counterfact`
84
+ 2. reads an [OpenAPI 3](https://oai.github.io/Documentation/) document (`https://petstore3.swagger.io/api/v3/openapi.json`)
85
+ 3. generates TypeScript files in the `api` directory
86
+ 4. starts a server which implements the API
87
+ 5. opens your browser to [Swagger UI](https://swagger.io/tools/swagger-ui/) (`--open`)
35
88
 
36
- You sure can!
89
+ You can use Swagger to try out the auto-generated API. Out of the box, it returns random responses using metadata from the OpenAPI document. You can edit the files under `./api/paths` to add more realistic behavior. There's no need to restart the server.
37
90
 
38
- ## What else does it do!
39
91
 
40
- So much more! We've barely scratched the surface. Stay tuned for detailed documentation and screen casts.
92
+ ## Documentation
41
93
 
94
+ Coming soon!
42
95
 
43
96
 
97
+ ## Support
44
98
 
99
+ Counterfact is brand new as of October 3, 2022. Please send feedback / questions to pmcelhaney@gmail.com or [create a new issue](https://github.com/pmcelhaney/counterfact/issues/new). If you like what you see, please give this project a star!
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "counterfact",
3
- "version": "0.10.2",
3
+ "version": "0.10.3",
4
4
  "description": "a library for building a fake REST API for testing",
5
5
  "type": "module",
6
6
  "main": "./src/counterfact.js",
@@ -23,8 +23,8 @@ export class OperationCoder extends Coder {
23
23
  return "() => { /* no response content specified in the OpenAPI document */ }";
24
24
  }
25
25
 
26
- return `({ response}) => {
27
- return response[${
26
+ return `($) => {
27
+ return $.response[${
28
28
  firstStatusCode === "default" ? 200 : firstStatusCode
29
29
  }].random();
30
30
  }`;
@@ -181,9 +181,10 @@ export class Script {
181
181
 
182
182
  contents() {
183
183
  return [
184
- ...this.externalImportsStatements(),
185
- ...this.importStatements(),
186
- ...this.exportStatements(),
187
- ].join("\n");
184
+ this.externalImportsStatements().join("\n"),
185
+ this.importStatements().join("\n"),
186
+ "\n\n",
187
+ this.exportStatements().join("\n\n"),
188
+ ].join("");
188
189
  }
189
190
  }
@@ -11,8 +11,8 @@ Map {
11
11
  },
12
12
  "exports": Map {
13
13
  "POST" => Object {
14
- "code": "({ response}) => {
15
- return response[200].random();
14
+ "code": "($) => {
15
+ return $.response[200].random();
16
16
  }",
17
17
  "done": true,
18
18
  "id": "OperationCoder@petstore.yaml#/paths/~1pet/post",
@@ -23,8 +23,8 @@ Map {
23
23
  "typeDeclaration": "HTTP_POST",
24
24
  },
25
25
  "PUT" => Object {
26
- "code": "({ response}) => {
27
- return response[200].random();
26
+ "code": "($) => {
27
+ return $.response[200].random();
28
28
  }",
29
29
  "done": true,
30
30
  "id": "OperationCoder@petstore.yaml#/paths/~1pet/put",
@@ -926,8 +926,8 @@ Map {
926
926
  },
927
927
  "exports": Map {
928
928
  "GET" => Object {
929
- "code": "({ response}) => {
930
- return response[200].random();
929
+ "code": "($) => {
930
+ return $.response[200].random();
931
931
  }",
932
932
  "done": true,
933
933
  "id": "OperationCoder@petstore.yaml#/paths/~1pet~1findByStatus/get",
@@ -1350,8 +1350,8 @@ Map {
1350
1350
  },
1351
1351
  "exports": Map {
1352
1352
  "GET" => Object {
1353
- "code": "({ response}) => {
1354
- return response[200].random();
1353
+ "code": "($) => {
1354
+ return $.response[200].random();
1355
1355
  }",
1356
1356
  "done": true,
1357
1357
  "id": "OperationCoder@petstore.yaml#/paths/~1pet~1findByTags/get",
@@ -1778,8 +1778,8 @@ Map {
1778
1778
  },
1779
1779
  "exports": Map {
1780
1780
  "GET" => Object {
1781
- "code": "({ response}) => {
1782
- return response[200].random();
1781
+ "code": "($) => {
1782
+ return $.response[200].random();
1783
1783
  }",
1784
1784
  "done": true,
1785
1785
  "id": "OperationCoder@petstore.yaml#/paths/~1pet~1{petId}/get",
@@ -3118,8 +3118,8 @@ Map {
3118
3118
  },
3119
3119
  "exports": Map {
3120
3120
  "POST" => Object {
3121
- "code": "({ response}) => {
3122
- return response[200].random();
3121
+ "code": "($) => {
3122
+ return $.response[200].random();
3123
3123
  }",
3124
3124
  "done": true,
3125
3125
  "id": "OperationCoder@petstore.yaml#/paths/~1pet~1{petId}~1uploadImage/post",
@@ -3380,8 +3380,8 @@ Map {
3380
3380
  },
3381
3381
  "exports": Map {
3382
3382
  "GET" => Object {
3383
- "code": "({ response}) => {
3384
- return response[200].random();
3383
+ "code": "($) => {
3384
+ return $.response[200].random();
3385
3385
  }",
3386
3386
  "done": true,
3387
3387
  "id": "OperationCoder@petstore.yaml#/paths/~1store~1inventory/get",
@@ -3580,8 +3580,8 @@ Map {
3580
3580
  },
3581
3581
  "exports": Map {
3582
3582
  "POST" => Object {
3583
- "code": "({ response}) => {
3584
- return response[200].random();
3583
+ "code": "($) => {
3584
+ return $.response[200].random();
3585
3585
  }",
3586
3586
  "done": true,
3587
3587
  "id": "OperationCoder@petstore.yaml#/paths/~1store~1order/post",
@@ -3864,8 +3864,8 @@ Map {
3864
3864
  },
3865
3865
  "exports": Map {
3866
3866
  "GET" => Object {
3867
- "code": "({ response}) => {
3868
- return response[200].random();
3867
+ "code": "($) => {
3868
+ return $.response[200].random();
3869
3869
  }",
3870
3870
  "done": true,
3871
3871
  "id": "OperationCoder@petstore.yaml#/paths/~1store~1order~1{orderId}/get",
@@ -4540,8 +4540,8 @@ Map {
4540
4540
  },
4541
4541
  "exports": Map {
4542
4542
  "POST" => Object {
4543
- "code": "({ response}) => {
4544
- return response[200].random();
4543
+ "code": "($) => {
4544
+ return $.response[200].random();
4545
4545
  }",
4546
4546
  "done": true,
4547
4547
  "id": "OperationCoder@petstore.yaml#/paths/~1user/post",
@@ -4814,8 +4814,8 @@ Map {
4814
4814
  },
4815
4815
  "exports": Map {
4816
4816
  "POST" => Object {
4817
- "code": "({ response}) => {
4818
- return response[200].random();
4817
+ "code": "($) => {
4818
+ return $.response[200].random();
4819
4819
  }",
4820
4820
  "done": true,
4821
4821
  "id": "OperationCoder@petstore.yaml#/paths/~1user~1createWithList/post",
@@ -5112,8 +5112,8 @@ Map {
5112
5112
  },
5113
5113
  "exports": Map {
5114
5114
  "GET" => Object {
5115
- "code": "({ response}) => {
5116
- return response[200].random();
5115
+ "code": "($) => {
5116
+ return $.response[200].random();
5117
5117
  }",
5118
5118
  "done": true,
5119
5119
  "id": "OperationCoder@petstore.yaml#/paths/~1user~1login/get",
@@ -5546,8 +5546,8 @@ Map {
5546
5546
  },
5547
5547
  "exports": Map {
5548
5548
  "GET" => Object {
5549
- "code": "({ response}) => {
5550
- return response[200].random();
5549
+ "code": "($) => {
5550
+ return $.response[200].random();
5551
5551
  }",
5552
5552
  "done": true,
5553
5553
  "id": "OperationCoder@petstore.yaml#/paths/~1user~1{username}/get",
@@ -1,15 +1,15 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
3
  exports[`an OperationCoder generates a complex get operation 1`] = `
4
- "({ response }) => {
5
- return response[200].random();
4
+ "($) => {
5
+ return $.response[200].random();
6
6
  };
7
7
  "
8
8
  `;
9
9
 
10
10
  exports[`an OperationCoder generates a simple post operation 1`] = `
11
- "({ response }) => {
12
- return response[200].random();
11
+ "($) => {
12
+ return $.response[200].random();
13
13
  };
14
14
  "
15
15
  `;
@@ -47,10 +47,10 @@ describe("integration Test", () => {
47
47
  await account.finished();
48
48
 
49
49
  expect(account.contents()).toBe(
50
- "export const HTTP_GET = () => {};\nexport const HTTP_POST = () => {};"
50
+ "\n\nexport const HTTP_GET = () => {};\n\nexport const HTTP_POST = () => {};"
51
51
  );
52
52
  expect(accountId.contents()).toBe(
53
- "export const HTTP_GET = () => {};\nexport const HTTP_PUT = () => {};"
53
+ "\n\nexport const HTTP_GET = () => {};\n\nexport const HTTP_PUT = () => {};"
54
54
  );
55
55
  });
56
56
  });
@@ -147,7 +147,7 @@ describe("a Script", () => {
147
147
  ];
148
148
 
149
149
  expect(script.contents()).toBe(
150
- 'import { foo } from \'./foo.js;\nexport const bar = "Bar";\nexport default class {};'
150
+ 'import { foo } from \'./foo.js;\n\nexport const bar = "Bar";\n\nexport default class {};'
151
151
  );
152
152
  });
153
153
  });