Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
abe09ac
chore: setup end of line git config for the project
Jan 17, 2023
3f0f112
chore: add @types for node-fetch
Jan 17, 2023
a62836c
chore: add packages for Jest testing
Jan 17, 2023
586b2f6
chore: refactor test code
Jan 18, 2023
f784354
chore: add forge Jest tests to continous integration
Jan 18, 2023
ced85a2
fix: file encoding of binary files in template (#155)
gkocak-scottlogic Feb 1, 2023
0b6ce91
chore: fix link and standardise links (#153)
Feb 1, 2023
bf7ea54
feat: adding support for generators with additional options
ColinEberhardt Jan 20, 2023
4fa5e8c
refactor: we can actually re-cycle the forge command
ColinEberhardt Jan 20, 2023
fbd3a8a
fix: correct order of generator cleanup
Jan 26, 2023
d458b27
chore: update README for generator-options command
Jan 26, 2023
ea91b60
chore: use log library
Jan 26, 2023
c5f75d5
chore: refactor commands into their own files
Jan 26, 2023
8947dd8
chore: fix test
Jan 26, 2023
77a813e
chore: rearrange file structure
Jan 27, 2023
b82121a
chore: use console.log where appropriate. Move log.js
Jan 31, 2023
bfa18e3
fix: test-generator command
Feb 1, 2023
2a8a4e6
chore: expand docs for generator testing
Feb 1, 2023
2d63fdb
fix: test-generators command by reverting generate
Feb 3, 2023
b56afac
refactor: function rename
ColinEberhardt Feb 3, 2023
f309cdd
feat: support default values for generator options.
ColinEberhardt Feb 3, 2023
a1c4c1b
feat: add post-processing to generation (#172)
gkocak-scottlogic Mar 2, 2023
06b6ed3
test: fixed indentation (#179)
ColinEberhardt Mar 7, 2023
733af31
feat: change file exclude option to allow multiple exclude globs (#170)
Mar 7, 2023
a8fca00
test: add test to verify headers are supported (#181)
ColinEberhardt Mar 8, 2023
45198d8
chore: add instructions for implementing the Gherkin tests for a new …
Mar 22, 2023
5038636
chore: add smoke test for generator-options command - stdout echoed (…
Feb 10, 2023
9d2b9d8
chore: generator-options smoke test added (#163)
Mar 27, 2023
d74ac04
chore: wip smoke test-generators (#163)
Mar 27, 2023
29117a4
chore: write smoke test in JS, all three commands pass
Mar 28, 2023
f78026c
chore: pass smoke test work to JS instead of Github Actions
Mar 28, 2023
325db45
chore: move noisy logs to log file
Mar 28, 2023
7263026
chore: log available on step failure, clean up comments
Mar 28, 2023
2bf9acc
chore: revert delete of workflow files
Mar 29, 2023
8c6c9a2
fix: incorrectly removed line
Mar 29, 2023
2bf1744
chore: print installed JS and TS generator versions in smoke test
Mar 29, 2023
21c9eee
chore: pass test-generators if it has >= passes cpw master
Mar 30, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ node_modules
.eslintignore
.prettierrc.js
.prettierignore
.vscode
.vscode
test
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Needed for Prettier
* text eol=lf
39 changes: 39 additions & 0 deletions .github/workflows/smoke.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Smoke Tests

on:
push:
branches:
- "**"
pull_request:
branches:
- "**"

jobs:
smoke-tests:
name: Smoke Tests
runs-on: ubuntu-latest

steps:
- name: Check out Git repository
uses: actions/checkout@v3

- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: 16.x
cache: 'npm'

- name: Install Node.js dependencies
run: |
npm install

- id: smoke_test
name: Smoke Test generator-options, test-generators and forge commands
run: |
npm run test:smoke

- id: show_full_log
name: Show Full Log
if: success() || failure()
run: |
cat log.txt
32 changes: 32 additions & 0 deletions .github/workflows/test-forge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Test Forge

on:
push:
branches:
- "**"
pull_request:
branches:
- "**"

jobs:
test-forge:
name: Test Forge
runs-on: ubuntu-latest

steps:
- name: Check out Git repository
uses: actions/checkout@v3

- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: 16.x
cache: 'npm'

- name: Install Node.js dependencies
run: |
npm install

- name: Test Forge
run: |
npm test
2 changes: 1 addition & 1 deletion CICD/compareTestResults.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const fs = require("fs");

const log = require("../src/log.js");
const log = require("../src/common/log");

log.setLogLevel(log.logLevels.verbose);

Expand Down
2 changes: 1 addition & 1 deletion CICD/updateWebpage.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const fs = require("fs");

const log = require("../src/log.js");
const log = require("../src/common/log");

// This regex extracts the generator table from README.md.
const tableRegex =
Expand Down
53 changes: 49 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,26 +67,71 @@ Options:
-h, --help display help for command
```

If the testing doesn't work you may be using the wrong script-shell configuration in npm. To keep scripts working in both Unix and Windows machines the shell expected in the project is git-bash. To change your shell type you can run the command below, changing the file location if you have your git-bash executable is in a different location:
### OpenAPI Forge Package

Install openapi-forge as a global package (this is required for running the tests even if you have it git-cloned locally):

```
npm config set script-shell "C:\\Program Files\\Git\\bin\\bash.exe"
$ npm install openapi-forge --global
```

### Dependencies on the Forge Project

The generators hardcode the relative path to the generate.js in order to run test-generators. Currently these must be changed manually if the path of generate.js is changed. See this issue: #158.

### GitHub Workflows

The Gherkin tests are run as part of Continuous Integration using `.github/workflows/test.yml`. It runs the tests on every generator, checking for the presence of a generated test results file. It does not check for passing/failing tests. See this issue: #157.

<br>

# Example directory structure for testing to work using default locations

You can have the locations of the forge and generators in custom locations with custom names but you will need to input the relative file paths into the testing commands of the forge nad generators.
You can have the locations of the forge and generators in custom locations with custom names but you will need to input the relative file paths into the testing commands of the forge and generators.
Below is the file structure needed to use the testing commands with the default locations:

```
|-openapi-forge
openapi-forge
|
|-openapi-forge-typescript
|-openapi-forge-csharp
|-openapi-forge-...
```

For example, run:

```
$ openapi-forge test-generators --format json --generators openapi-forge-csharp
```

You should see an output that looks like this:

```
{
logLevel: '1',
format: 'json',
generators: [ 'openapi-forge-csharp' ]
}
<path>\openapi-forge-csharp
Starting tests for generator openapi-forge-csharp
[
{ testRunStarted: { timestamp: [Object] } },
{ testCaseStarted: {} },
{ testCaseFinished: {} },
// ....
{ testRunFinished: { timestamp: [Object] } }
]
{
"openapi-forge-csharp": {
"scenarios": 44,
"failed": 0,
"passed": 44,
"time": 47
}
}

```

<br>

## Points to remember when contributing
Expand Down
53 changes: 51 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,26 @@ Options:
-h, --help Display help for command
```

Individual generators may have their own options. Try it out:

```
% openapi-forge generator-options https://github.com/ScottLogic/openapi-forge-javascript.git
Usage: openapi-forge generator-options <generator>

This generator has a number of additional options which can be supplied when executing the 'forge' command.

Options:
--generator.moduleFormat <value> The module format to use for the generated
code. (choices: "commonjs", "esmodule",
default: "commonjs")
```

and then

```
% openapi-forge forge https://petstore3.swagger.io/api/v3/openapi.json https://github.com/ScottLogic/openapi-forge-javascript.git --generator.moduleFormat "esmodule"
```

## Client generation

In order to generate a client you need a suitable API specification, this can be supplied as a URL or a local file and can be in JSON or YML format. For this tutorial, we’ll use the Swagger Petstore API:
Expand Down Expand Up @@ -134,8 +154,8 @@ And that’s it, you’ve successfully generated and used your first client libr
OpenAPI Forge currently has the following language generators:

- TypeScript - https://github.com/ScottLogic/openapi-forge-typescript
- C# - https://github.com/murcikan-scottlogic/openapi-forge-csharp
- JavaScript - https://github.com/murcikan-scottlogic/openapi-forge-javascript
- C# - https://github.com/ScottLogic/openapi-forge-csharp
- JavaScript - https://github.com/Scottlogic/openapi-forge-javascript

# Generator development

Expand Down Expand Up @@ -248,6 +268,35 @@ A primary goal of OpenAPI Forge is to provide robust and extensively tested clie

In order to test your generator you'll need to choose a suitable test runner (e.g. [Cucumber](https://www.npmjs.com/package/@cucumber/cucumber) for JavaScript). The standard pattern for each test is that it generates a client API using a schema snippet, then validates the generated output.

### Walkthrough for implementing the BDD tests for a new generator

Test implementations must:

1. Start with the `test:generators` script in the `package.json` and do these steps in JS:
1. Move the BDD tests to where they can be read by the rest of the test code.
1. Pass over control to the target language's implementation of the Gherkin tests.
1. In the target language, implement the step definitions for each of the `.feature` files. Each test must:
1. Run the openapi-forge command with the schema snippet in each test to produce the generated code.
1. Prepare the generated code for dynamic use (language dependent). For example:
1. JS uses dynamic require statements.
1. Java needs to compile the classes, add them to the classpath, and access them with Reflection.
1. Implement the rest of the step definitions for the scenario.
1. Output the results in the format expected by the main forge project `generator-tests` command.

Recommendations for easier development:

1. Start by looking at just one test in one feature file. The main complexity is getting the generation working. Each subsequent test will be easier to write.
1. To begin with, clean the generated schemas and code manually. Being able to see the generated code for each test will help with debugging.
1. Write the generator first, or in parallel. It would be a hard task to write the Gherkin implementations without a nearly-done generator.
1. Use what the existing generators have done as a guide (noting that the JS and TS ones are easier, and so may not be representative).

Existing generators:

1. The JS implementations are easier because we don't need to switch between languages or compile any code: https://github.com/ScottLogic/openapi-forge-javascript/ and
https://github.com/ScottLogic/openapi-forge-typescript both at `features/support/`.
1. C#: https://github.com/ScottLogic/openapi-forge-csharp at `tests/FeaturesTests/`.
1. Java - coming soon!

## Formatting

Ideally the generated output should be 'neatly' formatted in an idiomatic way for the target language. There are a couple of ways to achieve this:
Expand Down
26 changes: 26 additions & 0 deletions features/response.feature
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,32 @@ Feature: API responses, including model object deserialization
Then the response should have a property dateOne with value 2013-07-21T00:00:00.000Z
And the response should have a property dateTwo with value 2012-07-21T00:00:00.000Z

Scenario: the API returns headers
Given an API with the following specification
"""
{
"openapi":"3.0.2",
"info" : {"title": "test", "version": "0.0.0"},
"paths": {
"/test/get": {
"get": {
"operationId": "getResponse",
"responses": {
"200": {
"description": "successful operation"
}
}
}
}
}
}
"""
When calling the method getResponse and the server responds with headers
"""
{"foo": "bar"}
"""
Then the response should have a header foo with value bar

Scenario: a response that lacks content
Given an API with the following specification
"""
Expand Down
10 changes: 5 additions & 5 deletions features/tags.feature
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Feature: Grouping of paths by tags
Then the api file with tag "" exists
And the method "getResponse" should be present in the api file with tag ""

Scenario: Path with a tag = "" is present in a tagless API file
Scenario: Path with a tag = "" is present in a tagless API file
Given an API with the following specification
"""
{
Expand Down Expand Up @@ -58,7 +58,7 @@ Feature: Grouping of paths by tags
Then the api file with tag "" exists
And the method "getResponse" should be present in the api file with tag ""

Scenario: Path with no tag array is present in a tagless API file
Scenario: Path with no tag array is present in a tagless API file
Given an API with the following specification
"""
{
Expand Down Expand Up @@ -86,7 +86,7 @@ Feature: Grouping of paths by tags
Then the api file with tag "" exists
And the method "getResponse" should be present in the api file with tag ""

Scenario: Path with no tag is not present in a tagged API file
Scenario: Path with no tag is not present in a tagged API file
Given an API with the following specification
"""
{
Expand Down Expand Up @@ -170,7 +170,7 @@ Feature: Grouping of paths by tags
And the method "doNotGetResponse3" should be present in the api file with tag ""
And the method "doNotGetResponse3" should not be present in the api file with tag "tag"

Scenario: Path with multiple tags is present in first tag's API file
Scenario: Path with multiple tags is present in first tag's API file
Given an API with the following specification
"""
{
Expand Down Expand Up @@ -201,7 +201,7 @@ Feature: Grouping of paths by tags
And the api file with tag "" does not exist
Then the method "getResponse" should be present in the api file with tag "tag"

Scenario: Path with multiple tags is not present in second tag's API file
Scenario: Path with multiple tags is not present in second tag's API file
Given an API with the following specification
"""
{
Expand Down
Loading