Skip to content

Commit 1356a1c

Browse files
morphaticdaffl
authored andcommitted
feat: @feathers/cli: introduce option to choose jest for tests instead of mocha (#1057)
1 parent c6e7e63 commit 1356a1c

File tree

18 files changed

+345
-110
lines changed

18 files changed

+345
-110
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
module.exports = generator => {
2+
const { props } = generator;
3+
const config = {
4+
"env": {
5+
"es6": true,
6+
"node": true
7+
},
8+
"parserOptions": {
9+
"ecmaVersion": 2017
10+
},
11+
"extends": "eslint:recommended",
12+
"rules": {
13+
"indent": [
14+
"error",
15+
2
16+
],
17+
"linebreak-style": [
18+
"error",
19+
"unix"
20+
],
21+
"quotes": [
22+
"error",
23+
"single"
24+
],
25+
"semi": [
26+
"error",
27+
"always"
28+
]
29+
}
30+
};
31+
config.env[props.tester] = true;
32+
return config;
33+
};
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module.exports = {
22
configDefault: require('./config.default.json.js'),
33
configProduction: require('./config.production.json.js'),
4-
package: require('./package.json.js')
4+
package: require('./package.json.js'),
5+
eslintrc: require('./eslintrc.json.js')
56
};

packages/generator-feathers/generators/app/configs/package.json.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,17 @@ module.exports = function(generator) {
2929
[packager]: version
3030
},
3131
'scripts': {
32-
test: `${packager} run eslint && ${packager} run mocha`,
32+
test: `${packager} run eslint && NODE_ENV= ${packager} run ${props.tester}`,
3333
eslint: `eslint ${lib}/. test/. --config .eslintrc.json`,
3434
dev: `nodemon ${lib}/`,
35-
start: `node ${lib}/`,
36-
mocha: 'mocha test/ --recursive --exit'
35+
start: `node ${lib}/`
3736
}
3837
};
38+
if ('mocha' === props.tester) {
39+
pkg.scripts['mocha'] = 'mocha test/ --recursive --exit';
40+
} else {
41+
pkg.scripts['jest'] = 'jest';
42+
}
3943

4044
return pkg;
4145
};

packages/generator-feathers/generators/app/index.js

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ module.exports = class AppGenerator extends Generator {
2828
this.devDependencies = [
2929
'nodemon',
3030
'eslint',
31-
'mocha',
3231
'request',
3332
'request-promise'
3433
];
@@ -78,36 +77,36 @@ module.exports = class AppGenerator extends Generator {
7877
type: 'list',
7978
message: 'Which package manager are you using (has to be installed globally)?',
8079
default: 'npm@>= 3.0.0',
81-
choices: [{
82-
name: 'npm',
83-
value: 'npm@>= 3.0.0'
84-
}, {
85-
name: 'Yarn',
86-
value: 'yarn@>= 0.18.0'
87-
}]
80+
choices: [
81+
{ name: 'npm', value: 'npm@>= 3.0.0' },
82+
{ name: 'Yarn', value: 'yarn@>= 0.18.0' }
83+
]
8884
}, {
8985
type: 'checkbox',
9086
name: 'providers',
9187
message: 'What type of API are you making?',
92-
choices: [{
93-
name: 'REST',
94-
value: 'rest',
95-
checked: true
96-
}, {
97-
name: 'Realtime via Socket.io',
98-
value: 'socketio',
99-
checked: true
100-
}, {
101-
name: 'Realtime via Primus',
102-
value: 'primus',
103-
}],
88+
choices: [
89+
{ name: 'REST', value: 'rest', checked: true },
90+
{ name: 'Realtime via Socket.io', value: 'socketio', checked: true },
91+
{ name: 'Realtime via Primus', value: 'primus', }
92+
],
10493
validate (input) {
10594
if (input.indexOf('primus') !== -1 && input.indexOf('socketio') !== -1) {
10695
return 'You can only pick SocketIO or Primus, not both.';
10796
}
10897

10998
return true;
11099
}
100+
}, {
101+
type: 'list',
102+
name: 'tester',
103+
message: 'Which testing framework do you prefer?',
104+
default: 'mocha',
105+
choices: [
106+
{ name: 'Mocha + assert', value: 'mocha' },
107+
{ name: 'Jest', value: 'jest' }
108+
],
109+
pageSize: 7 // unnecessary; trying to get codeclimate to leave me alone :(
111110
}];
112111

113112
return this.prompt(prompts).then(props => {
@@ -145,7 +144,7 @@ module.exports = class AppGenerator extends Generator {
145144
);
146145

147146
this.fs.copyTpl(
148-
this.templatePath('app.test.js'),
147+
this.templatePath(`app.test.${props.tester}.js`),
149148
this.destinationPath(this.testDirectory, 'app.test.js'),
150149
context
151150
);
@@ -155,6 +154,11 @@ module.exports = class AppGenerator extends Generator {
155154
pkg
156155
);
157156

157+
this.fs.writeJSON(
158+
this.destinationPath('.eslintrc.json'),
159+
makeConfig.eslintrc(this)
160+
)
161+
158162
this.fs.writeJSON(
159163
this.destinationPath('config', 'default.json'),
160164
makeConfig.configDefault(this)
@@ -181,6 +185,8 @@ module.exports = class AppGenerator extends Generator {
181185
save: true
182186
});
183187

188+
this.devDependencies.push(this.props.tester);
189+
184190
this._packagerInstall(this.devDependencies, {
185191
saveDev: true
186192
});
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
const rp = require('request-promise');
2+
const url = require('url');
3+
const app = require('../<%= src %>/app');
4+
5+
const port = app.get('port') || 3030;
6+
const getUrl = pathname => url.format({
7+
hostname: app.get('host') || 'localhost',
8+
protocol: 'http',
9+
port,
10+
pathname
11+
});
12+
13+
describe('Feathers application tests (with jest)', () => {
14+
beforeAll(done => {
15+
this.server = app.listen(port);
16+
this.server.once('listening', () => done());
17+
});
18+
19+
afterAll(done => {
20+
this.server.close(done);
21+
});
22+
23+
it('starts and shows the index page', () => {
24+
expect.assertions(1);
25+
return rp(getUrl()).then(
26+
body => expect(body.indexOf('<html>')).not.toBe(-1)
27+
);
28+
});
29+
30+
describe('404', () => {
31+
it('shows a 404 HTML page', () => {
32+
expect.assertions(2);
33+
return rp({
34+
url: getUrl('path/to/nowhere'),
35+
headers: {
36+
'Accept': 'text/html'
37+
}
38+
}).catch(res => {
39+
expect(res.statusCode).toBe(404);
40+
expect(res.error.indexOf('<html>')).not.toBe(-1);
41+
});
42+
});
43+
44+
it('shows a 404 JSON error without stack trace', () => {
45+
expect.assertions(4);
46+
return rp({
47+
url: getUrl('path/to/nowhere'),
48+
json: true
49+
}).catch(res => {
50+
expect(res.statusCode).toBe(404);
51+
expect(res.error.code).toBe(404);
52+
expect(res.error.message).toBe('Page not found');
53+
expect(res.error.name).toBe('NotFound');
54+
});
55+
});
56+
});
57+
});

packages/generator-feathers/generators/app/templates/static/.eslintrc.json

Lines changed: 0 additions & 29 deletions
This file was deleted.

packages/generator-feathers/generators/hook/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ module.exports = class HookGenerator extends Generator {
153153
libDirectory: this.libDirectory
154154
}, this.props);
155155
const mainFile = this.destinationPath(this.libDirectory, 'hooks', `${context.kebabName}.js`);
156+
const tester = this.pkg.devDependencies.jest ? 'jest' : 'mocha';
156157

157158
if (!this.fs.exists(mainFile) && context.type) {
158159
this.props.services.forEach(serviceName =>
@@ -166,7 +167,7 @@ module.exports = class HookGenerator extends Generator {
166167
);
167168

168169
this.fs.copyTpl(
169-
this.templatePath(this.hasAsync ? 'test-async.js' : 'test.js'),
170+
this.templatePath(this.hasAsync ? `test-async.${tester}.js` : `test.${tester}.js`),
170171
this.destinationPath(this.testDirectory, 'hooks', `${context.kebabName}.test.js`),
171172
context
172173
);
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
const feathers = require('@feathersjs/feathers');
2+
const <%= camelName %> = require('../../<%= libDirectory %>/hooks/<%= kebabName %>');
3+
4+
describe('\'<%= name %>\' hook', () => {
5+
let app;
6+
7+
beforeEach(() => {
8+
app = feathers();
9+
10+
app.use('/dummy', {
11+
async get(id) {
12+
return { id };
13+
}
14+
});
15+
16+
app.service('dummy').hooks({
17+
<% if(type){ %><%= type %>: <%= camelName %>()<% } %>
18+
});
19+
});
20+
21+
it('runs the hook', async () => {
22+
expect.assertions(1);
23+
const result = await app.service('dummy').get('test');
24+
expect(result).toEqual({ id: 'test' });
25+
});
26+
});

0 commit comments

Comments
 (0)