Skip to content

Commit

Permalink
chore: use jest over mocha (#214)
Browse files Browse the repository at this point in the history
* add jest

* refactor tests to match linting suggestions

* refactor cli test

* migrate test for openapi compatibility

* migrate test for openapi compatibility

* refactor test for example app v2

* migrate helpers

* reorganize addDataToSwaggerObject

* move lib-specific test to the right place

* rename

* rename fixtures to files

* migrate open api spec

* remove unnecessary line

* move v2 example files

* update .editorconfig file

* remove mocha

* attempt to respect nvmrc

* attempt to respect nvmrc

* attempt to respect nvmrc

* set node version

* set 10

* try a matrix instead

* try snapshot update

* update tests

* update github workflow
  • Loading branch information
kalinchernev authored Oct 8, 2020
1 parent a0ad333 commit 0bfe3dc
Show file tree
Hide file tree
Showing 48 changed files with 3,382 additions and 1,567 deletions.
21 changes: 5 additions & 16 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -1,21 +1,10 @@
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org

root = true


[*]

# Change these settings to your own preference
indent_style = space
indent_size = 2

# We recommend you to keep these unchanged
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true

[*.md]
trim_trailing_whitespace = false
max_line_length = 80
trim_trailing_whitespace = true
6 changes: 5 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
module.exports = {
root: true,
extends: ['airbnb-base', 'plugin:prettier/recommended'],
extends: [
'airbnb-base',
'plugin:prettier/recommended',
'plugin:jest/recommended',
],
rules: {
'func-names': 'off',
'no-console': 'off',
Expand Down
8 changes: 7 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,20 @@ jobs:
tests:
name: tests
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [10.x, 12.x, 14.x]

steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Run tests
run: yarn test

publish:
name: Publish
name: publish
needs: tests
runs-on: ubuntu-latest
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
Expand Down
5 changes: 0 additions & 5 deletions .mocharc.yml

This file was deleted.

3 changes: 2 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
test/fixtures/wrong_syntax.json
test/files/v2/wrong_syntax.json
test/files/v2/wrong_syntax.yaml
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"editor.formatOnSave": true
}
5 changes: 2 additions & 3 deletions example/v2/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,12 @@ app.get('/api-docs.json', (req, res) => {
routes.setup(app);
routes2.setup(app);

// Expose app
module.exports = app;

// Start the server
const server = app.listen(PORT, () => {
const host = server.address().address;
const { port } = server.address();

console.log('Example app listening at http://%s:%s', host, port);
});

module.exports = { app, server };
20 changes: 20 additions & 0 deletions example/v2/app.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const request = require('supertest');
const { app, server } = require('./app');
const swaggerSpec = require('./swagger-spec.json');

describe('Example application written in swagger specification (v2)', () => {
it('should be healthy', async () => {
const response = await request(app).get('/');
expect(response.status).toBe(200);
});

it('should return the expected specification', async () => {
const response = await request(app).get('/api-docs.json');
expect(response.status).toBe(200);
expect(response.body).toEqual(swaggerSpec);
});

afterAll(() => {
server.close();
});
});
File renamed without changes.
7 changes: 3 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"main": "index.js",
"scripts": {
"test:lint": "eslint .",
"test:js": "mocha --timeout 10000 --exit",
"test:js": "jest --verbose",
"start": "node example/v2/app.js",
"test": "run-p test:* -cn"
},
Expand All @@ -41,18 +41,17 @@
},
"devDependencies": {
"body-parser": "1.19.0",
"chai": "4.2.0",
"chai-jest-snapshot": "2.0.0",
"eslint": "7.9.0",
"eslint-config-airbnb-base": "14.2.0",
"eslint-config-prettier": "6.11.0",
"eslint-loader": "4.0.2",
"eslint-plugin-import": "2.22.0",
"eslint-plugin-jest": "^24.0.2",
"eslint-plugin-prettier": "3.1.4",
"express": "4.17.1",
"husky": "4.3.0",
"jest": "^26.4.2",
"lint-staged": "10.4.0",
"mocha": "8.1.3",
"npm-run-all": "4.1.5",
"prettier": "2.1.2",
"supertest": "4.0.2"
Expand Down
77 changes: 77 additions & 0 deletions test/__snapshots__/cli.spec.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`command line interface help menu is default fallback when no arguments 1`] = `
"Usage: swagger-jsdoc [options] <path ...>
Options:
-V, --version output the version number
-d, --definition <swaggerDef.js> Input swagger definition.
-o, --output [swaggerSpec.json] Output swagger specification.
-h, --help display help for command
"
`;
exports[`command line interface help menu works 1`] = `
"Usage: swagger-jsdoc [options] <path ...>
Options:
-V, --version output the version number
-d, --definition <swaggerDef.js> Input swagger definition.
-o, --output [swaggerSpec.json] Output swagger specification.
-h, --help display help for command
"
`;
exports[`command line interface should reject definition file with invalid JSON syntax 1`] = `
"Error while loading definition file 'test/files/v2/wrong_syntax.json':
Unexpected token t in JSON at position 18
"
`;
exports[`command line interface should reject definition file with invalid YAML syntax 1`] = `
"Error while loading definition file 'test/files/v2/wrong_syntax.yaml':
tag suffix cannot contain exclamation marks at line 2, column 5:
!!!title: Hello World
^
"
`;
exports[`command line interface should reject definition file with non-JSON compatible YAML syntax 1`] = `
"Error while loading definition file 'test/files/v2/non_json_compatible.yaml':
unknown tag !<tag:yaml.org,2002:js/undefined> at line 3, column 3:
version: 1.0.0
^
"
`;
exports[`command line interface should require a definition file 1`] = `
"Definition file is required.
You can do that, for example:
$ swag-jsdoc -d swaggerDef.js wrongDefinition
Usage: swagger-jsdoc [options] <path ...>
Options:
-V, --version output the version number
-d, --definition <swaggerDef.js> Input swagger definition.
-o, --output [swaggerSpec.json] Output swagger specification.
-h, --help display help for command
"
`;
exports[`command line interface should require an info object in the definition 1`] = `
"Definition file should contain an info object!
More at http://swagger.io/specification/#infoObject
"
`;
exports[`command line interface should require arguments with jsDoc data about an API 1`] = `
"You must provide sources for reading API files.
Either add filenames as arguments, or add an \\"apis\\" key in your definitions file.
"
`;
exports[`command line interface should require title and version in the info object 1`] = `
"The title and version properties are required!
More at http://swagger.io/specification/#infoObject
"
`;
132 changes: 132 additions & 0 deletions test/cli.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
const fs = require('fs');
const { promisify } = require('util');
const { exec } = require('child_process');

const sh = promisify(exec);
const dir = process.env.PWD;
const bin = `${dir}/bin/swagger-jsdoc.js`;

describe('command line interface', () => {
it('help menu is default fallback when no arguments', async () => {
const result = await sh(`${bin}`);
expect(result.stdout).toMatchSnapshot();
});

it('help menu works', async () => {
const result = await sh(`${bin} -h`);
expect(result.stdout).toMatchSnapshot();
});

it('should require a definition file', async () => {
const result = await sh(`${bin} wrongDefinition`);
expect(result.stdout).toMatchSnapshot();
});

it('should require an info object in the definition', async () => {
const result = await sh(`${bin} -d test/files/v2/empty_definition.js`);
expect(result.stdout).toMatchSnapshot();
});

it('should require title and version in the info object', async () => {
const result = await sh(`${bin} -d test/files/v2/wrong_definition.js`);
expect(result.stdout).toMatchSnapshot();
});

it('should require arguments with jsDoc data about an API', async () => {
const result = await sh(`${bin} -d example/v2/swaggerDef.js`);
expect(result.stdout).toMatchSnapshot();
});

it('should create swagger.json by default when the API input is good', async () => {
const result = await sh(
`${bin} -d example/v2/swaggerDef.js example/v2/routes.js`
);
expect(result.stdout).toBe('Swagger specification is ready.\n');
const specification = fs.statSync('swagger.json');
expect(specification.nlink).not.toBe(0);
});

it('should create swagger.json by default when the API input is from definition file', async () => {
const result = await sh(`${bin} -d test/files/v2/api_definition.js`);
expect(result.stdout).toBe('Swagger specification is ready.\n');
const specification = fs.statSync('swagger.json');
expect(specification.nlink).not.toBe(0);
});

it('should accept custom configuration for output specification', async () => {
const result = await sh(
`${bin} -d example/v2/swaggerDef.js -o customSpec.json example/v2/routes.js`
);
expect(result.stdout).toBe('Swagger specification is ready.\n');
const specification = fs.statSync('customSpec.json');
expect(specification.nlink).not.toBe(0);
});

it('should create a YAML swagger spec when a custom output configuration with a .yaml extension is used', async () => {
const result = await sh(
`${bin} -d example/v2/swaggerDef.js -o customSpec.yaml example/v2/routes.js`
);
expect(result.stdout).toBe('Swagger specification is ready.\n');
const specification = fs.statSync('customSpec.yaml');
expect(specification.nlink).not.toBe(0);
});

it('should allow a JavaScript definition file', async () => {
const result = await sh(`${bin} -d test/files/v2/api_definition.js`);
expect(result.stdout).toBe('Swagger specification is ready.\n');
const specification = fs.statSync('swagger.json');
expect(specification.nlink).not.toBe(0);
});

it('should allow a JSON definition file', async () => {
const result = await sh(`${bin} -d test/files/v2/api_definition.json`);
expect(result.stdout).toBe('Swagger specification is ready.\n');
const specification = fs.statSync('swagger.json');
expect(specification.nlink).not.toBe(0);
});

it('should allow a YAML definition file', async () => {
const result = await sh(`${bin} -d test/files/v2/api_definition.yaml`);
expect(result.stdout).toBe('Swagger specification is ready.\n');
const specification = fs.statSync('swagger.json');
expect(specification.nlink).not.toBe(0);
});

it('should reject definition file with invalid YAML syntax', async () => {
const result = await sh(`${bin} -d test/files/v2/wrong_syntax.yaml`);
expect(result.stdout).toMatchSnapshot();
});

it('should reject definition file with non-JSON compatible YAML syntax', async () => {
const result = await sh(`${bin} -d test/files/v2/non_json_compatible.yaml`);
expect(result.stdout).toMatchSnapshot();
});

it('should reject definition file with invalid JSON syntax', async () => {
const result = await sh(`${bin} -d test/files/v2/wrong_syntax.json`);
expect(result.stdout).toMatchSnapshot();
});

it('should reject bad YAML identation with feedback: upper line', async () => {
await expect(
sh(
`${bin} -d example/v2/swaggerDef.js test/files/v2/wrong-yaml-identation1.js`
)
).rejects.toThrow();
});

it('should reject bad YAML identation with feedback: same line', async () => {
await expect(
sh(
`${bin} -d example/v2/swaggerDef.js test/files/v2/wrong-yaml-identation2.js`
)
).rejects.toThrow();
});

afterAll(() => {
fs.unlinkSync(`${dir}/swagger.json`);
fs.unlinkSync(`${dir}/customSpec.json`);
fs.unlinkSync(`${dir}/customSpec.yaml`);
fs.unlinkSync(`${dir}/customSpec.yml`);
});
});
Loading

0 comments on commit 0bfe3dc

Please sign in to comment.