Skip to content

Commit

Permalink
📝 Add a "simple" example
Browse files Browse the repository at this point in the history
  • Loading branch information
ouvreboite committed Jun 14, 2024
1 parent 13f3cf8 commit 22f1dc6
Show file tree
Hide file tree
Showing 14 changed files with 172 additions and 55 deletions.
18 changes: 10 additions & 8 deletions .github/workflows/poltergust.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:
branches: [ main ]

jobs:
build-and-test-valid-example:
build-and-test-valid-examples:
permissions:
contents: write
runs-on: ubuntu-latest
Expand All @@ -22,19 +22,21 @@ jobs:
- name: Install poltergust
run: npm ci

- name: Test the valid example ruleset
run: npx poltergust ./examples/valid
- name: Run the simple example
run: npx poltergust ./examples/simple

- name: Commit updated valid ruleset
- name: Run the complex example
run: npx poltergust ./examples/complex

- name: Commit aggregated rulesets
run: |
git config --global user.name '👻poltergust'
git config --global user.email '[email protected]'
git commit -am "👻 Auto-update valid ruleset"
git push
git diff --quiet || ( git commit -am "👻 Auto-update valid ruleset" && git push)
build-and-test-invalid-example:
needs: build-and-test-valid-example
needs: build-and-test-valid-examples
runs-on: ubuntu-latest

steps:
Expand All @@ -47,6 +49,6 @@ jobs:
- name: Install poltergust
run: npm ci

- name: Test the invalid example ruleset (should exit 1)
- name: Run the invalid example (should exit 1)
run: npx poltergust ./examples/invalid || (exitcode=$?; [ $exitcode -eq 1 ] || exit $exitcode)
shell: bash
88 changes: 77 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,88 @@

# 👻 poltergust

An npm CLI to extract, test and merge Spectral rules from .md files.
> With poltergust, you can document, define and test your [Spectral](https://github.com/stoplightio/spectral) rules in a single place.
- **Rules**: A YAML codeblock starting by `#👻-rule` is considered a spectral rule and will be aggregated in the spectral.yaml file
- **Test cases**: A YAML codeblock containing `#👻-failures:` or `#👻-fails-here:` is considered an OpenAPI test case
- `#👻-failures: X some-rule-name` expects the given rule to return only X failures for this test case. For example `#👻-failures: 0 some-rule-name` can be used to assert that a test case does not trigger a rule.
- `#👻-fails-here: some-rule-name` expects the given rule to be trigger at this very line
- **Base ruleset**: to merge the rules, a `spectral.base.yaml` is needed. It should be a standard Spectral ruleset files, with empty rules. But it can includes extends, aliases, functions...
Poltergust is a npm CLI that looks for .md files in a directory (and sub-directories) and extract Spectral rules and test cases.
- **Rules**: any YAML codeblock starting by `#👻-rule` is considered a spectral rule and will be aggregated in the spectral.yaml file
- **Test cases**: any YAML codeblock containing `#👻-failures:` or `#👻-fails-here:` is considered an OpenAPI test case
- `#👻-failures: X some-rule-name` expects the given rule to return exactly X failures against the OpenAPI document.
- `#👻-failures: 0 some-rule-name` expects the given rule to not fail the OpenAPI document.
- `#👻-fails-here: some-rule-name` expects the given rule to fail at a specific line of the OpenAPI document.
- **Base ruleset**: to merge the rules, a `spectral.base.yaml` file is needed. It's a standard Spectral ruleset files (with aliases, funcitons, extends, ...), with empty rules (they will be added by poltergust).

## Setup and run
## How to run

```sh
npm install
npx poltergust ./examples/valid
npx poltergust ./your-rules-directory
```

## Examples
## Simple example

- [valid](examples/valid)
- [invalid](examples/invalid)
(from [simple](examples/simple))

1. This is a Spectral rule:

```yaml
#👻-rule
operation-parameters-must-have-description:
description: Operation parameters must have a description
given: $.paths[*][*].parameters[*]
severity: error
then:
field: description
function: truthy
```
2. This is a test case for this rule:
```yaml
#👻-failures: 1 operation-parameters-must-have-description
openapi: 3.0.1
paths:
/test/{id}:
get:
parameters:
# the 'id' parameter needs a description
- name: id #👻-fails-here: operation-parameters-must-have-description
in: path
required: true
schema:
type: string
```
3. The spectral.base.yaml is:
```yaml
formats: ["oas3"]
rules:
#rules will be injected by poltergust
```

4. Running poltegust:
```bash
npx poltergust .\examples\simple
🔎 Testing the spectral rules from the .md files in the directory: .\examples\simple
👻 operation-parameters-must-have-description (examples\simple\README.md:6)
✅ Test OK (examples\simple\README.md:18)
✅ Spectral rules merged in the file: examples\simple\spectral.yaml
```

4. The aggregated Spectral ruleset can be found [here](examples/simple/spectral.yaml)

```yaml
formats: ["oas3"]
rules:
#rules will be injected by poltergust
operation-parameters-must-have-description:
description: Operation parameters must have a description
given: $.paths[*][*].parameters[*]
severity: error
then:
field: description
function: truthy
```
## More examples
- [complex](examples/complex): subdirectories, functions, ...
- [invalid](examples/invalid): a test case that fails
36 changes: 36 additions & 0 deletions examples/complex/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Complex example

* This example contains rules accross several markdown files: [rules1.md](rules1.md) and [rules2.md](rules2.md) and even subdirectories [subdirectory/subrules.md](subdirectory/subrules.md)
* ✅ All the test declared in those files are expected to pass
* Some of the rules use custom functions defined in the [functions](functions) directory
* [spectral.base.yaml](spectral.base.yaml) contains the base rule files that will be used to merge the rules into. For example, it contains the extends, aliases and functions declarations
* [spectral.yaml](spectral.yaml) is the output of the merge operation: [spectral.base.yaml](spectral.base.yaml) + all the rules found in [rules1.md](rules1.md) and [rules2.md](rules2.md)

## Test ouput

```
npx poltergust .\examples\simple
🔎 Testing the spectral rules from the .md files in the directory: .\examples\simple
👻 operation-parameters-must-have-description (examples\simple\README.md:6)
✅ Test OK (examples\simple\README.md:18)
✅ Spectral rules merged in the file: examples\simple\spectral.yaml
PS C:\Users\jb.muscat\sources\GitHub\api-guidelines> npx poltergust .\examples\complex
🔎 Testing the spectral rules from the .md files in the directory: .\examples\complex
👻 base-path-must-start-with-slash (examples\complex\rules1.md:39)
✅ Test OK (examples\complex\rules1.md:16)
✅ Test OK (examples\complex\rules1.md:26)
👻 operation-parameters-must-have-description (examples\complex\rules1.md:90)
✅ Test OK (examples\complex\rules1.md:57)
✅ Test OK (examples\complex\rules1.md:72)
👻 operation-must-have-description (examples\complex\rules1.md:106)
👻 operation-must-have-no-summary (examples\complex\rules1.md:121)
👻 operation-must-have-at-least-one-response (examples\complex\rules1.md:134)
👻 path-parameters-must-be-kebab-case (examples\complex\rules2.md:49)
✅ Test OK (examples\complex\rules2.md:11)
👻 required-property-must-exist (examples\complex\rules2.md:96)
✅ Test OK (examples\complex\rules2.md:66)
👻 request-bodies-must-have-a-content (examples\complex\subdirectory\subrules.md:41)
✅ Test OK (examples\complex\subdirectory\subrules.md:8)
✅ Test OK (examples\complex\subdirectory\subrules.md:25)
✅ Spectral rules merged in the file: examples\complex\spectral.yaml
```
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ aliases:
parameters:
- $.paths[*].parameters
- $.paths[*][*].parameters
#rules will be injected from the rules/*.md files
rules:
rules:
#rules will be injected by poltergust
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ aliases:
parameters:
- $.paths[*].parameters
- $.paths[*][*].parameters
#rules will be injected from the rules/*.md files
rules:
#rules will be injected by poltergust
base-path-must-start-with-slash:
description: Base path must be relative (start with a /)
message: "{{description}}. But was {{value}}."
Expand Down
File renamed without changes.
4 changes: 2 additions & 2 deletions examples/invalid/spectral.base.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ aliases:
parameters:
- $.paths[*].parameters
- $.paths[*][*].parameters
#rules will be injected from the rules/*.md files
rules:
rules:
#rules will be injected by poltergust
30 changes: 30 additions & 0 deletions examples/simple/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Simple example

1. This is a Spectral rule:

```yaml
#👻-rule
operation-parameters-must-have-description:
description: Operation parameters must have a description
given: $.paths[*][*].parameters[*]
severity: error
then:
field: description
function: truthy
```
2. This is a test case for this rule:
```yaml
#👻-failures: 1 operation-parameters-must-have-description
openapi: 3.0.1
paths:
/test/{id}:
get:
parameters:
# the 'id' parameter needs a description
- name: id #👻-fails-here: operation-parameters-must-have-description
in: path
required: true
schema:
type: string
```
3 changes: 3 additions & 0 deletions examples/simple/spectral.base.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
formats: ["oas3"]
rules:
#rules will be injected by poltergust
11 changes: 11 additions & 0 deletions examples/simple/spectral.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
formats: ["oas3"]
rules:
#rules will be injected by poltergust
operation-parameters-must-have-description:
description: Operation parameters must have a description
given: $.paths[*][*].parameters[*]
severity: error
then:
field: description
function: truthy

31 changes: 0 additions & 31 deletions examples/valid/README.md

This file was deleted.

0 comments on commit 22f1dc6

Please sign in to comment.