Skip to content

Commit 31c6df9

Browse files
committedMay 5, 2019
Added unit tests
1 parent cf0022b commit 31c6df9

18 files changed

+433
-3
lines changed
 

‎.codeclimate.yml

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
version: 2
2+
plugins:
3+
eslint:
4+
enabled: true
5+
stylelint:
6+
enabled: true
7+
exclude_patterns:
8+
- src/tasks/watch.js
9+
- __tests__/**
10+
- __mocks__/**

‎.eslintrc

+4-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66
},
77
"parserOptions": {
88
"sourceType": "module",
9-
"ecmaVersion": 2018
9+
"ecmaVersion": 2018,
10+
"ecmaFeatures": {
11+
"experimentalObjectRestSpread": true
12+
}
1013
},
1114
"globals": {
1215
"Promise": true,

‎.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
.tern-*
33
node_modules/
44
package-lock.json
5+
coverage/

‎.travis.yml

+15-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,20 @@
11
language: node_js
22
node_js:
3-
- 8
3+
- "8"
4+
cache:
5+
directories:
6+
- node_modules
7+
env:
8+
global:
9+
- CC_TEST_REPORTER_ID=c7ef634d96a67d1c98a87dadc02205dc01f9b935cd10699d9d1bce46ccdcbd27
10+
before_script:
11+
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
12+
- chmod +x ./cc-test-reporter
13+
- ./cc-test-reporter before-build
14+
after_script:
15+
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
416
install:
517
- npm install
18+
- npm install -g jest
619
script:
7-
- npm run eslint
20+
- npm test

‎__mocks__/packages/Application/dist/main.js

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"name": "Application"
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"osjs": {
3+
"type": "package"
4+
}
5+
}
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"malformed
3+
}
+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"osjs": {
3+
"type": "package"
4+
}
5+
}

‎__mocks__/packages/Theme/dist/main.js

Whitespace-only changes.
+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"name": "Theme",
3+
"type": "theme"
4+
}

‎__mocks__/packages/Theme/package.json

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"osjs": {
3+
"type": "package"
4+
}
5+
}

‎__mocks__/setup.js

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
const logger = require('consola');
2+
3+
jest.spyOn(console, 'info')
4+
.mockImplementation(() => {});
5+
6+
jest.spyOn(console, 'log')
7+
.mockImplementation(() => {});
8+
9+
jest.spyOn(process, 'exit')
10+
.mockImplementation(() => {});
11+
12+
logger.mockTypes(() => jest.fn());

‎__tests__/cli.js

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
const path = require('path');
2+
const cli = require('../src/cli.js');
3+
4+
describe('cli', () => {
5+
const createInstance = (...argv) => cli([
6+
'/usr/bin/node',
7+
'/tmp/node_modules/.bin/osjs-cli',
8+
...argv
9+
], {
10+
root: path.resolve(__dirname, '..')
11+
});
12+
13+
test('should initialize without error', () => {
14+
return expect(createInstance())
15+
.resolves
16+
.toBe(undefined);
17+
});
18+
19+
test('should run info task', () => {
20+
return expect(createInstance('info'))
21+
.resolves
22+
.toBe(undefined);
23+
});
24+
});

‎__tests__/tasks/discover.js

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
const logger = require('consola');
2+
const path = require('path');
3+
const temp = require('temp');
4+
const fs = require('fs-extra');
5+
const utils = require('../../src/utils.js');
6+
const task = require('../../src/tasks/discover.js');
7+
8+
describe('task > package:discover', () => {
9+
const root = temp.mkdirSync('osjs-cli-jest');
10+
const fname = str => path.resolve(root, str);
11+
12+
afterAll(() => fs.removeSync(root));
13+
14+
test('should discover packages', async () => {
15+
const defaults = utils.createOptions({root});
16+
17+
const options = utils.resolveOptions(defaults, {
18+
discover: [
19+
path.resolve(__dirname, '../../__mocks__/packages'),
20+
path.resolve(__dirname, '../../__mocks__/packages')
21+
]
22+
});
23+
24+
await task['package:discover']
25+
.action({
26+
logger,
27+
options,
28+
args: {},
29+
commander: null
30+
});
31+
32+
expect(fs.existsSync(fname('dist/metadata.json')))
33+
.toBe(true);
34+
35+
expect(require(fname('dist/metadata.json')))
36+
.toMatchObject([{
37+
name: 'Application'
38+
}, {
39+
name: 'Theme',
40+
type: 'theme'
41+
}]);
42+
43+
expect(fs.existsSync(fname('dist/apps/Application/main.js')))
44+
.toBe(true);
45+
46+
expect(fs.existsSync(fname('dist/themes/Theme/main.js')))
47+
.toBe(true);
48+
49+
expect(fs.existsSync(fname('dist/apps/Failed')))
50+
.toBe(false);
51+
});
52+
});

‎__tests__/tasks/scaffold.js

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
const logger = require('consola');
2+
const path = require('path');
3+
const temp = require('temp');
4+
const fs = require('fs-extra');
5+
const utils = require('../../src/utils.js');
6+
const task = require('../../src/tasks/scaffold.js');
7+
8+
describe('task > make:*', () => {
9+
const root = temp.mkdirSync('osjs-cli-jest');
10+
const fname = str => path.resolve(root, str);
11+
12+
const defaults = utils.createOptions({root});
13+
14+
const options = utils.resolveOptions(defaults, {
15+
discover: [
16+
path.resolve(__dirname, '../../__mocks__/packages')
17+
]
18+
});
19+
20+
const runTask = (name, args = {}) => task[name]
21+
.action({
22+
logger,
23+
options,
24+
args,
25+
commander: null
26+
});
27+
28+
const basicScaffold = async (name, type) => {
29+
const filename = `my-${name}.js`;
30+
await runTask(`make:${name}`, {type, filename});
31+
32+
return fs.existsSync(fname(`src/${type}/${filename}`));
33+
};
34+
35+
afterAll(() => fs.removeSync(root));
36+
37+
describe('make:auth', () => {
38+
test('should create client auth adapter', () => {
39+
return expect(basicScaffold('auth', 'client'))
40+
.resolves
41+
.toBe(true);
42+
});
43+
44+
test('should create server auth adapter', async () => {
45+
return expect(basicScaffold('auth', 'server'))
46+
.resolves
47+
.toBe(true);
48+
});
49+
50+
test('should fail when exists', async () => {
51+
return expect(basicScaffold('auth', 'server'))
52+
.rejects
53+
.toBeInstanceOf(Error);
54+
});
55+
});
56+
57+
describe('make:settings', () => {
58+
test('should create client settings adapter', () => {
59+
return expect(basicScaffold('settings', 'client'))
60+
.resolves
61+
.toBe(true);
62+
});
63+
64+
test('should create server settings adapter', async () => {
65+
return expect(basicScaffold('settings', 'server'))
66+
.resolves
67+
.toBe(true);
68+
});
69+
});
70+
71+
describe('make:provider', () => {
72+
test('should create client provider adapter', () => {
73+
return expect(basicScaffold('provider', 'client'))
74+
.resolves
75+
.toBe(true);
76+
});
77+
78+
test('should create server provider adapter', async () => {
79+
return expect(basicScaffold('provider', 'server'))
80+
.resolves
81+
.toBe(true);
82+
});
83+
});
84+
85+
describe('make:vfs', () => {
86+
test('should create client vfs adapter', () => {
87+
return expect(basicScaffold('vfs', 'client'))
88+
.resolves
89+
.toBe(true);
90+
});
91+
92+
test('should create server vfs adapter', async () => {
93+
return expect(basicScaffold('vfs', 'server'))
94+
.resolves
95+
.toBe(true);
96+
});
97+
});
98+
99+
describe('make:application', () => {
100+
test('should create application', async () => {
101+
await runTask('make:application', {
102+
dry: true,
103+
force: true,
104+
name: 'StandardApplication',
105+
target: 'src/packages/StandardApplication'
106+
});
107+
108+
expect(fs.readdirSync(fname('src/packages/StandardApplication')))
109+
.toHaveLength(7);
110+
});
111+
});
112+
113+
describe('make:iframe-application', () => {
114+
test('should create application', async () => {
115+
await runTask('make:iframe-application', {
116+
dry: true,
117+
force: true,
118+
name: 'IframeApplication',
119+
target: 'src/packages/IframeApplication'
120+
});
121+
122+
expect(fs.readdirSync(fname('src/packages/IframeApplication')))
123+
.toHaveLength(6);
124+
});
125+
});
126+
});

‎__tests__/utils.js

+151
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
const path = require('path');
2+
const utils = require('../src/utils.js');
3+
4+
describe('utils', () => {
5+
describe('createOptions', () => {
6+
test('should create structured object', () => {
7+
const options = utils.createOptions({
8+
root: '/tmp'
9+
});
10+
11+
expect(options.dist())
12+
.toEqual({
13+
root: '/tmp/dist',
14+
themes: '/tmp/dist/themes',
15+
sounds: '/tmp/dist/sounds',
16+
icons: '/tmp/dist/icons',
17+
packages: '/tmp/dist/apps',
18+
metadata: '/tmp/dist/metadata.json'
19+
});
20+
21+
expect(options)
22+
.toMatchObject({
23+
cli: '/tmp/src/cli',
24+
config: {
25+
disabled: [],
26+
discover: [],
27+
tasks: []
28+
},
29+
npm: '/tmp/package.json',
30+
packages: '/tmp/packages.json',
31+
production: false,
32+
root: '/tmp'
33+
});
34+
});
35+
});
36+
37+
describe('resolveOptions', () => {
38+
test('should create new object', () => {
39+
const task = jest.fn();
40+
41+
const defaults = utils.createOptions({
42+
root: '/tmp'
43+
});
44+
45+
const options = utils.resolveOptions(defaults, {
46+
tasks: [
47+
task
48+
],
49+
discover: [
50+
'/foo'
51+
],
52+
disabled: [
53+
'foo'
54+
],
55+
packages: {
56+
metadata: {
57+
Foo: {
58+
bar: 'baz'
59+
}
60+
}
61+
}
62+
});
63+
64+
expect(options)
65+
.toMatchObject({
66+
cli: '/tmp/src/cli',
67+
config: {
68+
disabled: [
69+
'foo'
70+
],
71+
packages: {
72+
metadata: {
73+
Foo: {
74+
bar: 'baz'
75+
}
76+
}
77+
},
78+
discover: [
79+
'/tmp/node_modules',
80+
'/foo'
81+
],
82+
tasks: [
83+
task
84+
]
85+
},
86+
npm: '/tmp/package.json',
87+
packages: '/tmp/packages.json',
88+
production: false,
89+
root: '/tmp'
90+
});
91+
});
92+
});
93+
94+
describe('loadTasks', () => {
95+
test('should load a list of tasks', () => {
96+
const promise = utils.loadTasks({
97+
foo: {
98+
description: 'foo'
99+
}
100+
}, [
101+
() => ({
102+
bar: {
103+
description: 'bar'
104+
}
105+
})
106+
], {});
107+
108+
return expect(promise)
109+
.resolves
110+
.toEqual({
111+
foo: {
112+
description: 'foo'
113+
},
114+
bar: {
115+
description: 'bar'
116+
}
117+
});
118+
});
119+
});
120+
121+
describe('spawnAsync', () => {
122+
test('should exit with correct code', () => {
123+
return expect(utils.spawnAsync('sh', ['-c', 'exit 123']))
124+
.rejects
125+
.toBe(123);
126+
});
127+
});
128+
129+
describe('npmPackages', () => {
130+
test('should get filtered list of metadata', () => {
131+
const root = path.resolve(__dirname, '../__mocks__', 'packages');
132+
return expect(utils.npmPackages(root))
133+
.resolves
134+
.toMatchObject([{
135+
json: {
136+
osjs: {type: 'package'}
137+
},
138+
meta: {
139+
name: 'Application'
140+
}
141+
}, {
142+
json: {
143+
osjs: {type: 'package'}
144+
},
145+
meta: {
146+
name: 'Theme'
147+
}
148+
}]);
149+
});
150+
});
151+
});

‎jest.config.js

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module.exports = {
2+
collectCoverage: true,
3+
coverageReporters: ['lcov'],
4+
5+
setupFilesAfterEnv: [
6+
'<rootDir>/__mocks__/setup.js'
7+
],
8+
9+
coveragePathIgnorePatterns: [
10+
'src/tasks/watch.js',
11+
'/node_modules/'
12+
]
13+
};

0 commit comments

Comments
 (0)
Please sign in to comment.