Skip to content

Commit b7c4f75

Browse files
committed
mocking level of unit tests increased
1 parent a4917ab commit b7c4f75

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+517
-436
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
node_modules
33
lib
44
coverage
5+
tmp
56
*.log
67
.idea
78
*.ipr

.istanbul.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ instrumentation:
22
root: src
33
include-all-sources: true
44
default-excludes: true
5-
excludes: ['**/*.spec.js', '**/*.spec.def.js', 'index.js']
5+
excludes: ['**/*.spec.js', '**/*.spec-def.js', '**/index.js']
66
es-modules: true
77
extensions:
88
- .js

docs/interface/api-adapter/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ API Adapter interface is a common way to make API plugginable to applications. W
66

77
### Criteria against
88

9-
1. Adapter must have `pluginCall` and `request` methods implemented.
9+
1. Adapter must have `pluginCall`, `unplugCall` and `request` methods implemented.
1010

1111
**Example**
1212

1313
class MyApiAdapter {
1414
pluginCall() {}
1515
16+
unplugCall() {}
17+
1618
request(data) {
1719
return JSON.stringify(data);
1820
}

docs/objects/application/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ Application object provides ability work with features of application. This incl
66

77
[getFeature()](get-feature/README.md)
88

9-
[getFeatures()](get-features/README.md)
9+
[getFeatureNames()](get-feature-names/README.md)
1010

1111
[extendWithFeature()](extend-with-feature/README.md)
1212

13+
[shrinkWithFeature()](shrink-with-feature/README.md)
14+
1315
[executeFeature()](execute-feature/README.md)
1416

1517
[apiAdapter](api-adapter/README.md)

docs/objects/application/get-features/README.md renamed to docs/objects/application/get-feature-names/README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
### getFeatures()
1+
### getFeatureNames()
22

3-
[Index](/docs/README.md) | [Objects in Globular](/docs/objects/README.md) | [Application](/docs/objects/application/README.md) | getFeatures()
3+
[Index](/docs/README.md) | [Objects in Globular](/docs/objects/README.md) | [Application](/docs/objects/application/README.md) | getFeatureNames()
44

55
Returns IDs of application's available features.
66

77
**Signature**
88

9-
myApp.getFeatures()
9+
myApp.getFeatureNames()
1010

1111
**Return value**
1212

1313
Array containing string IDs of features.
1414

1515
**Example**
1616

17-
const featureList = myApp.getFeatures();
17+
const featureList = myApp.getFeatureNames();
1818
if (featureList.indexOf('check-wind-condictions') < 0) {
1919
throw new Error('Missing feature: Check Wind Conditions');
2020
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
### shrinkWithFeature()
2+
3+
[Index](/docs/README.md) | [Objects in Globular](/docs/objects/README.md) | [Application](/docs/objects/application/README.md) | shrinkWithFeature()
4+
5+
Removes a feature from application's functionality.
6+
7+
**Signature**
8+
9+
myApplication.WithFeature(featureName)
10+
11+
**Parameters**
12+
13+
`featureName`
14+
15+
*(mandatory)* String identifier to uniquely identify feature.
16+
17+
**Example**
18+
19+
class ReserveRoom {
20+
execute() {
21+
// to some stuffs
22+
}
23+
}
24+
25+
myApplication.extendWithFeature('reserve-room', ReserveRoom);
26+
myApplication.shrinkWithFeature('reserve-room');

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
"babel-core": "6.18.0",
4343
"babel-eslint": "7.1.1",
4444
"babel-loader": "6.2.7",
45-
"babel-plugin-add-module-exports": "^0.2.1",
45+
"babel-plugin-add-module-exports": "0.2.1",
4646
"babel-plugin-transform-runtime": "6.15.0",
4747
"babel-preset-es2015": "6.18.0",
4848
"babel-preset-es2015-loose": "7.0.0",
@@ -59,12 +59,12 @@
5959
"isparta": "4.0.0",
6060
"istanbul": "0.4.5",
6161
"mocha": "3.0.2",
62-
"node-localstorage": "^1.3.0",
62+
"node-localstorage": "1.3.0",
6363
"phantomjs": "1.9.20",
6464
"phantomjs-prebuilt": "2.1.13",
6565
"rimraf": "2.5.4",
6666
"sinon": "3.2.1",
67-
"sinon-chai": "2.8.0",
67+
"sinon-chai": "2.14.0",
6868
"webpack": "2.4.0"
6969
},
7070
"devEngines": {

src/Globular.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import ApiAdapter from './modules/api/ApiAdapter';
1+
import { ApiAdapter } from './modules/api/ApiAdapter';
22
import ApplicationFactory from './modules/application';
33

44
const applications = new Map();

src/Globular.spec.js

Lines changed: 36 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,53 @@
1-
import { expect } from 'chai';
21
import sinon from 'sinon';
3-
import { LocalStorage } from 'node-localstorage';
2+
import { expect } from 'chai';
43

5-
import globular from './Globular';
6-
import ApplicationFactory from './modules/application';
7-
import isInterfaceImplemented from './util/isInterfaceImplemented';
8-
import isMethod from './util/isMethod';
4+
import Globular from './Globular';
95

10-
describe('globular Framework', () => {
11-
context('when no custom plugins defined', () => {
12-
it('should create a new application', () => {
13-
expect(isInterfaceImplemented(globular.initializeApp('sample-app'), ['getFeatures', 'getFeature', 'extendWithFeature', 'executeFeature'])).to.be.equal(true);
14-
});
15-
it('should return application immediately when initialized', () => {
16-
const initializedApp = globular.initializeApp('sample-app');
17-
const application = globular.app('sample-app');
18-
expect(application).to.equal(initializedApp);
19-
});
20-
});
21-
context('when custom plugins defined', () => {
22-
let FactoryStub;
6+
import ApplicationFactory from './modules/application/ApplicationFactory';
237

8+
describe('Globular Framework', () => {
9+
context('when no API nor persitency passed', () => {
2410
beforeEach(() => {
25-
FactoryStub = sinon.stub(ApplicationFactory, 'produce');
11+
sinon.stub(ApplicationFactory, 'produce').returns({ });
2612
});
13+
2714
afterEach(() => {
28-
FactoryStub.restore();
29-
});
30-
it('should pass Persistency Adapter to newly created application', () => {
31-
const localStorageToInject = new LocalStorage('./tmp/localStorage');
32-
globular.initializeApp('sample-app', { persistency: localStorageToInject });
33-
expect(FactoryStub.calledOnce).to.be.equal(true);
34-
expect(FactoryStub.lastCall.args[0].persistency).to.be.equal(localStorageToInject);
15+
ApplicationFactory.produce.restore();
3516
});
36-
it('should pass API Adapter to newly created application', () => {
37-
const apiAdapterToInject = { pluginCall() {}, request() {} };
38-
globular.initializeApp('sample-app', { api: apiAdapterToInject });
39-
expect(FactoryStub.calledOnce).to.be.equal(true);
40-
expect(FactoryStub.lastCall.args[0].api).to.be.equal(apiAdapterToInject);
17+
18+
it('should indicate application factory to produce an app with API but with no persitency', () => {
19+
Globular.initializeApp('sampleApp');
20+
21+
const callArgs = ApplicationFactory.produce.firstCall.args;
22+
expect(ApplicationFactory.produce.calledOnce).to.be.equal(true);
23+
expect(callArgs[0].api).to.not.be.equal(undefined);
24+
expect(callArgs[0].persistency).to.be.equal(undefined);
4125
});
42-
it('should pass default API Adapter instance to application when no Adapter defined', () => {
43-
globular.initializeApp('sample-app1');
44-
expect(FactoryStub.lastCall.args[0].api).not.to.be.equal(undefined);
4526

46-
globular.initializeApp('sample-app2', {});
47-
expect(FactoryStub.lastCall.args[0].api).not.to.be.equal(undefined);
27+
it('should indicate application factory to produce an with persitency passed to', () => {
28+
const persistency = { };
29+
Globular.initializeApp('sampleApp', { persistency });
4830

49-
globular.initializeApp('sample-app3', { persistency: new LocalStorage('./tmp/localStorage') });
50-
expect(FactoryStub.lastCall.args[0].api).not.to.be.equal(undefined);
31+
const callArgs = ApplicationFactory.produce.firstCall.args;
32+
expect(ApplicationFactory.produce.calledOnce).to.be.equal(true);
33+
expect(callArgs[0].api).to.not.be.equal(undefined);
34+
expect(callArgs[0].persistency).to.be.equal(persistency);
5135
});
52-
});
5336

54-
context('when examining interface', () => {
55-
it('should have expected overall interface', () => {
56-
expect(isInterfaceImplemented(globular, ['initializeApp', 'app'])).to.be.equal(true);
37+
it('should indicate application factory to produce an with API passed to', () => {
38+
const api = { };
39+
Globular.initializeApp('sampleApp', { api });
40+
41+
const callArgs = ApplicationFactory.produce.firstCall.args;
42+
expect(ApplicationFactory.produce.calledOnce).to.be.equal(true);
43+
expect(callArgs[0].api).to.be.equal(api);
44+
expect(callArgs[0].persistency).to.be.equal(undefined);
5745
});
58-
it('should have expected API Adapter interface', () => {
59-
expect(isMethod(globular.Api)).to.be.equal(true);
46+
47+
it('should make newly created app to be available', () => {
48+
const app = Globular.initializeApp('sampleApp');
49+
50+
expect(Globular.app('sampleApp')).to.be.equal(app);
6051
});
6152
});
6253
});

src/modules/api/ApiAdapter.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import isMethod from '../../util/isMethod';
2-
3-
export default function ApiAdapter() {
1+
export function ApiAdapter() {
42
const calls = new Map();
53

64
function isAlreadyPluggedIn(id) {
@@ -32,7 +30,7 @@ export default function ApiAdapter() {
3230
/* eslint-disable class-methods-use-this */
3331
return new class {
3432
pluginCall(id, call) {
35-
if (!isMethod(call)) {
33+
if (typeof call !== 'function') {
3634
throw new TypeError('Invalid API call');
3735
}
3836
if (isAlreadyPluggedIn(id)) {
@@ -43,6 +41,14 @@ export default function ApiAdapter() {
4341
/* eslint-enable no-eval */
4442
}
4543

44+
unplugCall(id) {
45+
calls.delete(id);
46+
}
47+
48+
getAvailableCalls() {
49+
return Array.from(calls.keys());
50+
}
51+
4652
request(id, data) {
4753
return new Promise((resolve, reject) => {
4854
if (!isAlreadyPluggedIn(id)) {

0 commit comments

Comments
 (0)