This commit is contained in:
Ferdi Koomen 2020-09-25 15:50:16 +02:00
parent 9985c45e61
commit 75c9ef321e
30 changed files with 417 additions and 243 deletions

View File

@ -5,25 +5,29 @@ module.exports = {
testEnvironment: 'node',
testMatch: [
'<rootDir>/src/**/*.spec.ts',
'<rootDir>/test/**/*.spec.js',
'<rootDir>/test/index.spec.js',
],
moduleNameMapper: {
'\\.hbs$': '<rootDir>/src/templates/__mocks__/index.js',
},
collectCoverageFrom: [
'src/**/*.ts',
'!src/**/*.d.ts',
],
},
{
displayName: 'E2E',
testEnvironment: 'node',
testMatch: [
'<rootDir>/test/e2e/index.js',
'<rootDir>/test/e2e/v2.fetch.spec.js',
// '<rootDir>/test/e2e/v2.xhr.spec.js',
// '<rootDir>/test/e2e/v2.node.spec.js',
// '<rootDir>/test/e2e/v3.fetch.spec.js',
// '<rootDir>/test/e2e/v3.xhr.spec.js',
// '<rootDir>/test/e2e/v3.node.spec.js',
],
globals: {
URL: 'http://localhost:3000',
},
},
],
collectCoverageFrom: [
'<rootDir>/src/**/*.ts',
'!<rootDir>/src/**/*.d.ts',
'!<rootDir>/bin',
'!<rootDir>/dist',
],
};

View File

@ -54,13 +54,14 @@
"test:update": "jest --selectProjects UNIT --updateSnapshot",
"test:watch": "jest --selectProjects UNIT --watch",
"test:coverage": "jest --selectProjects UNIT --coverage",
"test:e2e": "jest --selectProjects E2E",
"eslint": "eslint \"./src/**/*.ts\" \"./test/**/*.ts\" \"./bin/index.js\"",
"eslint:fix": "eslint \"./src/**/*.ts\" \"./test/**/*.ts\" \"./bin/index.js\" --fix",
"prettier": "prettier \"./src/**/*.ts\" \"./test/**/*.ts\" \"./bin/index.js\" --check",
"prettier:fix": "prettier \"./src/**/*.ts\" \"./test/**/*.ts\" \"./bin/index.js\" --write",
"test:e2e": "jest --selectProjects E2E --runInBand",
"eslint": "eslint \"./src/**/*.ts\" \"./bin/index.js\"",
"eslint:fix": "eslint \"./src/**/*.ts\" \"./bin/index.js\" --fix",
"prettier": "prettier \"./src/**/*.ts\" \"./bin/index.js\" --check",
"prettier:fix": "prettier \"./src/**/*.ts\" \"./bin/index.js\" --write",
"prepublish": "yarn run clean && yarn run release",
"codecov": "codecov --token=66c30c23-8954-4892-bef9-fbaed0a2e42b"
"codecov": "codecov --token=66c30c23-8954-4892-bef9-fbaed0a2e42b",
"aap": "node ./test/e2e/index.js"
},
"dependencies": {
"camelcase": "6.0.0",

View File

@ -1,57 +1,4 @@
'use strict';
const generate = require('./scripts/generate');
const copy = require('./scripts/copy');
const compile = require('./scripts/compile');
const build = require('./scripts/build');
const server = require('./scripts/server');
const browser = require('./scripts/browser');
describe('e2e', () => {
beforeAll(async () => {
await generate('v2', 'fetch');
await generate('v2', 'xhr');
await generate('v2', 'node');
await generate('v3', 'fetch');
await generate('v3', 'xhr');
await generate('v3', 'node');
await copy('v2', 'fetch');
await copy('v2', 'xhr');
await copy('v2', 'node');
await copy('v3', 'fetch');
await copy('v3', 'xhr');
await copy('v3', 'node');
await build('v2', 'fetch');
await build('v2', 'xhr');
await build('v2', 'node');
await build('v3', 'fetch');
await build('v3', 'xhr');
await build('v3', 'node');
await server.start();
await browser.start();
}, 30000);
afterAll(async () => {
await server.stop();
await browser.stop();
});
it('runs in chrome', async () => {
expect(true).toBeTruthy();
});
it('runs in node', async () => {
// const child1 = require('./generated/v2/fetch/index.js');
// const child2 = require('./generated/v3/fetch/index.js');
// const resultDefaultsService1 = child1.testDefaultsService();
// const resultDefaultsService2 = child2.testDefaultsService();
// expect(resultDefaultsService1).toContain('aap');
// expect(resultDefaultsService2).toContain('aap');
expect(true).toBeTruthy();
});
});
server.start('v2', 'fetch');

View File

@ -1,69 +0,0 @@
'use strict';
const express = require('express');
const puppeteer = require('puppeteer');
const fs = require('fs');
const path = require('path');
const http = require('http');
const compile = require('./scripts/compiler');
const browser = require('./scripts/browser');
const server = require('./scripts/server');
describe('e2e', () => {
let app;
let browser;
let page;
let server;
beforeAll(async () => {
app = express();
app.all('/api/*', (req, res) => {
res.send({
method: req.method,
protocol: req.protocol,
hostname: req.hostname,
path: req.path,
url: req.url,
query: req.query,
body: req.body,
headers: req.headers,
});
});
server = app.listen(3000);
browser = await puppeteer.launch();
page = await browser.newPage();
});
afterAll(async () => {
await page.close();
await browser.close();
await server.close();
});
it('runs in chrome', async () => {
await page.goto('http://localhost:3000/api/test', {
waitUntil: 'networkidle0',
});
const content = await page.content();
expect(content).toBeDefined();
});
it('runs in node', async () => {
return new Promise((resolve) => {
http.get('http://localhost:3000/api/test', (res) => {
const chunks = [];
res.on('data', (chunk) => {
chunks.push(chunk);
});
res.on('end', () => {
const content = Buffer.concat(chunks).toString();
console.log(content);
expect(content).toBeDefined();
resolve();
});
})
});
});
})

View File

@ -1,31 +0,0 @@
In the before all script:
generate 6 libraries
- fetch (v2 & v3)
- xhr (v2 & v3)
- node (v2 & v3)
/generated/v2/fetch
/generated/v2/xhr
/generated/v2/node
/generated/v3/fetch
/generated/v3/xhr
/generated/v3/node
link in 6 projects
- fetch (v2 & v3)
- xhr (v2 & v3)
- node (v2 & v3)
Note: This can be one base 'template' that copies to dirs above
Compile projects
Start server that serves the api echo sever.
In the tests:
Run e2e tests (node + puppeteer)
After all tests:
Close pupeteer and server!

View File

@ -8,6 +8,9 @@ let page
async function start() {
browser = await puppeteer.launch();
page = await browser.newPage();
await page.goto(`http://localhost:3000/`, {
waitUntil: 'networkidle0',
});
}
async function stop() {
@ -15,7 +18,12 @@ async function stop() {
await browser.close();
}
async function evaluate(fn) {
return await page.evaluate(fn);
}
module.exports = {
start,
stop,
evaluate,
};

View File

@ -1,29 +0,0 @@
'use strict';
const rollup = require('rollup');
const { nodeResolve } = require('@rollup/plugin-node-resolve');
const commonjs = require('@rollup/plugin-commonjs');
const typescript = require('rollup-plugin-typescript2');
async function build(version, client) {
const input = `./test/e2e/generated/${version}/${client}/index.ts`;
const output = `./test/e2e/generated/${version}/${client}/index.js`;
const options = {
treeshake: false,
plugins: [
typescript(),
nodeResolve(),
commonjs(),
],
input: input,
output: {
file: output,
format: 'cjs',
},
}
const bundle = await rollup.rollup(options);
await bundle.generate(options.output);
await bundle.write(options.output);
}
module.exports = build;

View File

@ -5,11 +5,11 @@ const path = require('path');
const os = require('os');
function compile(version, client) {
const baseDir = `./test/e2e/generated/src/${version}/${client}`;
const baseDir = `./test/e2e/generated/${version}/${client}/js/api/`;
const tsconfig = {
compilerOptions: {
target: 'es6',
module: 'commonjs',
module: 'es6',
moduleResolution: 'node',
},
include: ['./index.ts'],

View File

@ -1,11 +1,19 @@
'use strict';
const fs = require('fs');
const path = require('path');
const glob = require('glob');
async function copy(version, client) {
return new Promise(resolve => {
fs.copyFile('./test/e2e/test/index.ts', `./test/e2e/generated/${version}/${client}/index.ts`, resolve);
});
const input = path.resolve('./test/e2e/test/');
const output = path.resolve(`./test/e2e/generated/${version}/${client}/js`);
const files = glob.sync('*.js', { cwd: input });
for (let file of files) {
fs.copyFileSync(
path.resolve(input, file),
path.resolve(output, file)
);
}
}
module.exports = copy;

View File

@ -5,7 +5,7 @@ const OpenAPI = require('../../../dist');
async function generate(version, client) {
await OpenAPI.generate({
input: `./test/spec/${version}.json`,
output: `./test/e2e/generated/${version}/${client}/api`,
output: `./test/e2e/generated/${version}/${client}/js/api/`,
httpClient: client,
useOptions: false,
useUnionTypes: false,

View File

@ -1,9 +0,0 @@
'use strict';
async function runner() {
return new Promise(resolve => {
resolve();
});
}
module.exports = runner;

View File

@ -5,10 +5,20 @@ const express = require('express');
let app;
let server
async function start() {
async function start(version, client) {
return new Promise(resolve => {
app = express();
app.all('/api/*', (req, res) => {
app.use(express.static(`./test/e2e/generated/${version}/${client}`, {
extensions: ['', 'js'],
index: 'index.js'
}));
app.get('/', (req, res) => {
res.send('<script src="public/script.js"></script>');
});
app.all('/base/api/*', (req, res) => {
res.send({
method: req.method,
protocol: req.protocol,
@ -20,6 +30,7 @@ async function start() {
headers: req.headers,
});
});
server = app.listen(3000, resolve);
});
}

17
test/e2e/test/index.js Normal file
View File

@ -0,0 +1,17 @@
import * as complexService from './testComplexService';
import * as defaultsService from './testDefaultsService';
import * as headerService from './testHeaderService';
import * as parametersService from './testParametersService';
import * as responseService from './testResponseService';
import * as simpleService from './testSimpleService';
import * as typesService from './testTypesService';
export {
complexService,
defaultsService,
headerService,
parametersService,
responseService,
simpleService,
typesService
};

View File

@ -1,25 +0,0 @@
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import { ComplexService, DefaultsService } from './api';
export async function testDefaultsService(): Promise<any> {
const callWithDefaultParameters = await DefaultsService.callWithDefaultParameters();
const callWithDefaultOptionalParameters = await DefaultsService.callWithDefaultOptionalParameters();
return {
callWithDefaultParameters,
callWithDefaultOptionalParameters,
};
}
export async function testComplexService(): Promise<any> {
const complexTypes = await ComplexService.complexTypes(
{},
{
prop: 'Hello World!',
}
);
return {
complexTypes,
};
}

3
test/e2e/test/script.js Normal file
View File

@ -0,0 +1,3 @@
import('./index.js').then(module => {
window.test = module;
});

View File

@ -0,0 +1,13 @@
import { ComplexService } from './api';
export async function complexTypes() {
return await ComplexService.complexTypes({
first: {
second: {
third: 'Hello World!',
},
},
}, {
prop: 'Hello World!',
});
}

View File

@ -0,0 +1,20 @@
import { DefaultsService } from './api';
export async function callWithDefaultParameters() {
return await DefaultsService.callWithDefaultParameters();
}
export async function callWithDefaultOptionalParameters() {
return await DefaultsService.callWithDefaultOptionalParameters();
}
export async function callToTestOrderOfParams() {
return await DefaultsService.callToTestOrderOfParams(
'parameterStringWithNoDefault',
'parameterOptionalStringWithDefault',
'parameterOptionalStringWithEmptyDefault',
'parameterOptionalStringWithNoDefault',
'parameterStringWithDefault',
'parameterStringWithEmptyDefault'
);
}

View File

@ -0,0 +1,5 @@
import { HeaderService } from './api';
export async function callWithResultFromHeader() {
return await HeaderService.callWithResultFromHeader();
}

View File

@ -0,0 +1,23 @@
import { ParametersService } from './api';
export async function callWithParameters() {
return await ParametersService.callWithParameters(
'parameterHeader',
'parameterQuery',
'parameterForm',
'parameterBody',
'parameterPath'
);
}
export async function callWithWeirdParameterNames() {
return await ParametersService.callWithWeirdParameterNames(
'parameterHeader',
'parameterQuery',
'parameterForm',
'parameterBody',
'parameterPath1',
'parameterPath2',
'parameterPath3'
);
}

View File

@ -0,0 +1,13 @@
import { ResponseService } from './api';
export async function callWithResponse() {
return await ResponseService.callWithResponse();
}
export async function callWithResponses() {
return await ResponseService.callWithResponses();
}
export async function callWithDuplicateResponses() {
return await ResponseService.callWithDuplicateResponses();
}

View File

@ -0,0 +1,29 @@
import { SimpleService } from './api';
export async function getCallWithoutParametersAndResponse() {
return await SimpleService.getCallWithoutParametersAndResponse();
}
export async function putCallWithoutParametersAndResponse() {
return await SimpleService.putCallWithoutParametersAndResponse();
}
export async function postCallWithoutParametersAndResponse() {
return await SimpleService.postCallWithoutParametersAndResponse();
}
export async function deleteCallWithoutParametersAndResponse() {
return await SimpleService.deleteCallWithoutParametersAndResponse();
}
export async function optionsCallWithoutParametersAndResponse() {
return await SimpleService.optionsCallWithoutParametersAndResponse();
}
export async function headCallWithoutParametersAndResponse() {
return await SimpleService.headCallWithoutParametersAndResponse();
}
export async function patchCallWithoutParametersAndResponse() {
return await SimpleService.patchCallWithoutParametersAndResponse();
}

View File

@ -0,0 +1,13 @@
import { TypesService } from './api';
export async function types() {
return await TypesService.types(
['foo', 'bar'],
{ foo: 'bar' },
'Success',
123,
'Hello World!',
true,
{ foo: 'bar' }
);
}

28
test/e2e/v2.fetch.spec.js Normal file
View File

@ -0,0 +1,28 @@
'use strict';
const generate = require('./scripts/generate');
const copy = require('./scripts/copy');
const compile = require('./scripts/compile');
const server = require('./scripts/server');
const browser = require('./scripts/browser');
describe('v2.fetch', () => {
beforeAll(async () => {
await generate('v2', 'fetch');
await copy('v2', 'fetch');
await compile('v2', 'fetch');
await server.start('v2', 'fetch');
await browser.start();
}, 30000);
afterAll(async () => {
await server.stop();
await browser.stop();
});
it('complexService', async () => {
const result = await browser.evaluate(async () => await window.test.complexService.complexTypes());
expect(result).toBe('');
});
});

82
test/e2e/v2.node.spec.js Normal file
View File

@ -0,0 +1,82 @@
'use strict';
const generate = require('./scripts/generate');
const copy = require('./scripts/copy');
const compile = require('./scripts/compile');
const server = require('./scripts/server');
let tests;
describe('v2.node', () => {
beforeAll(async () => {
await generate('v2', 'node');
await copy('v2', 'node');
await compile('v2', 'fetch');
await server.start('v2', 'fetch');
tests = require('./generated/v2/node/js/index.js');
}, 30000);
afterAll(async () => {
await server.stop();
tests = null;
});
it('complexService', async () => {
const result = await tests.complexService.complexTypes();
expect(result).toBeTruthy();
});
it('defaultsService', async () => {
const result1 = await tests.defaultsService.callWithDefaultParameters();
const result2 = await tests.defaultsService.callWithDefaultOptionalParameters();
const result3 = await tests.defaultsService.callToTestOrderOfParams();
expect(result1).toBeTruthy();
expect(result2).toBeTruthy();
expect(result3).toBeTruthy();
});
it('headerService', async () => {
const result = await tests.headerService.callWithResultFromHeader();
expect(result).toBeTruthy();
});
it('parametersService', async () => {
const result1 = await tests.parametersService.callWithParameters();
const result2 = await tests.parametersService.callWithWeirdParameterNames();
expect(result1).toBeTruthy();
expect(result2).toBeTruthy();
});
it('responseService', async () => {
const result1 = await tests.responseService.callWithResponse();
const result2 = await tests.responseService.callWithResponses();
const result3 = await tests.responseService.callWithDuplicateResponses();
expect(result1).toBeTruthy();
expect(result2).toBeTruthy();
expect(result3).toBeTruthy();
});
it('simpleService', async () => {
const result1 = await tests.simpleService.getCallWithoutParametersAndResponse();
const result2 = await tests.simpleService.putCallWithoutParametersAndResponse();
const result3 = await tests.simpleService.postCallWithoutParametersAndResponse();
const result4 = await tests.simpleService.deleteCallWithoutParametersAndResponse();
const result5 = await tests.simpleService.optionsCallWithoutParametersAndResponse();
const result6 = await tests.simpleService.headCallWithoutParametersAndResponse();
const result7 = await tests.simpleService.patchCallWithoutParametersAndResponse();
expect(result1).toBeTruthy();
expect(result2).toBeTruthy();
expect(result3).toBeTruthy();
expect(result4).toBeTruthy();
expect(result5).toBeTruthy();
expect(result6).toBeTruthy();
expect(result7).toBeTruthy();
});
it('typesService', async () => {
const result = await tests.typesService.types();
expect(result).toBeTruthy();
});
});

27
test/e2e/v2.xhr.spec.js Normal file
View File

@ -0,0 +1,27 @@
'use strict';
const generate = require('./scripts/generate');
const copy = require('./scripts/copy');
const compile = require('./scripts/compile');
const server = require('./scripts/server');
const browser = require('./scripts/browser');
describe('v2.xhr', () => {
beforeAll(async () => {
await generate('v2', 'xhr');
await copy('v2', 'xhr');
await compile('v2', 'xhr');
await server.start('v2', 'xhr');
await browser.start();
}, 30000);
afterAll(async () => {
await server.stop();
await browser.stop();
});
it('runs', async () => {
expect(true).toBeTruthy();
});
});

28
test/e2e/v3.fetch.spec.js Normal file
View File

@ -0,0 +1,28 @@
'use strict';
const generate = require('./scripts/generate');
const copy = require('./scripts/copy');
const compile = require('./scripts/compile');
const server = require('./scripts/server');
const browser = require('./scripts/browser');
describe('v3.fetch', () => {
beforeAll(async () => {
await generate('v3', 'fetch');
await copy('v3', 'fetch');
await compile('v3', 'fetch');
await server.start('v3', 'fetch');
await browser.start();
}, 30000);
afterAll(async () => {
await server.stop();
await browser.stop();
});
it('runs', async () => {
expect(true).toBeTruthy();
});
});

30
test/e2e/v3.node.spec.js Normal file
View File

@ -0,0 +1,30 @@
'use strict';
const generate = require('./scripts/generate');
const copy = require('./scripts/copy');
const compile = require('./scripts/compile');
const server = require('./scripts/server');
let tests;
describe('v3.node', () => {
beforeAll(async () => {
await generate('v3', 'node');
await copy('v3', 'node');
await compile('v3', 'node');
await server.start('v3', 'node');
tests = require('./generated/v3/node/index.js');
}, 30000);
afterAll(async () => {
await server.stop();
tests = null;
});
it('runs', async () => {
console.log(app);
expect(true).toBeTruthy();
});
});

27
test/e2e/v3.xhr.spec.js Normal file
View File

@ -0,0 +1,27 @@
'use strict';
const generate = require('./scripts/generate');
const copy = require('./scripts/copy');
const compile = require('./scripts/compile');
const server = require('./scripts/server');
const browser = require('./scripts/browser');
describe('v3.xhr', () => {
beforeAll(async () => {
await generate('v3', 'xhr');
await copy('v3', 'xhr');
await compile('v3', 'xhr');
await server.start('v3', 'xhr');
await browser.start();
}, 30000);
afterAll(async () => {
await server.stop();
await browser.stop();
});
it('runs', async () => {
expect(true).toBeTruthy();
});
});

View File

@ -4,8 +4,8 @@
"title": "swagger",
"version": "v1.0"
},
"host": "localhost:8080",
"basePath": "/api",
"host": "localhost:3000",
"basePath": "/base",
"schemes": [
"http"
],

View File

@ -6,7 +6,7 @@
},
"servers": [
{
"url": "/api"
"url": "http://localhost:3000/base"
}
],
"paths": {