UNPKG

7 kBJavaScriptView Raw
1'use strict';
2
3const expect = require('chai').expect;
4const Method = require('../lib/Method');
5
6describe('class Method', function() {
7 let method;
8
9 beforeEach(function() {
10 method = new Method('test', {}, function() {});
11 });
12
13 describe('constructor(name, options, fn)', function() {
14 [
15 ['name', 'test'],
16 ['stack', null],
17 ['adapters', ['express', 'socketio', 'rpc']],
18 ['skipHooks', false],
19 ['parent', null],
20 ['params', []],
21 ['description', 'test'],
22 ['notes', undefined],
23 ['documented', true],
24 ['route', { path: '/', verb: 'all' }],
25 ['upload', {}],
26 ['extra', {}],
27 ['options', {}]
28 ].forEach(function(prop) {
29 it(`should have property '${prop[0]}' and corresponding value`, function() {
30 expect(method).to.have.property(prop[0]).deep.eq(prop[1]);
31 });
32 });
33
34 it('should be a valid instance of Method class', function() {
35 expect(method).to.be.an.instanceof(Method);
36 });
37
38 it('should raise error when params missing `name` property', function() {
39 expect(function() {
40 new Method('test', { params: [{ type: 'any' }] }, function() {});
41 }).to.throw(Error).have.property('message', '`name` is missing for params of `test` method at position [0]');
42 });
43
44 it('should raise error when params missing inner params\' deep `name` property', function() {
45 expect(function() {
46 new Method('test', { params: [{ name: 'profile', type: 'any', params: { type: 'string' } }] }, function() {});
47 }).to.throw(Error).have.property('message', '`name` is missing for params of `test` method at position [0].params[0]');
48 });
49
50 it('should raise an error if there is no function to be executed', function() {
51 expect(function() {
52 new Method('test', { params: [{ type: 'any' }] });
53 }).to.throw(Error).have.property('message', 'Method fn must be a valid function');
54 });
55
56 it('should raise an error if there is no function to be executed', function() {
57 expect(function() {
58 new Method(null, { params: [{ type: 'any' }] }, function() {});
59 }).to.throw(Error).have.property('message', 'Method name must be a valid string');
60 });
61
62 it('should parse options.skipHooks by conditions', function() {
63 let method = new Method('test', { route: { verb: 'use' } }, function() {});
64 expect(method).to.have.property('skipHooks', true);
65
66 let method1 = new Method('test', { route: { verb: 'get' } }, function() {});
67 expect(method1).to.have.property('skipHooks', false);
68
69 let method2 = new Method('test', { skipHooks: true }, function() {});
70 expect(method2).to.have.property('skipHooks', true);
71
72 let method3 = new Method('test', { skipHooks: '' }, function() {});
73 expect(method3).to.have.property('skipHooks', false);
74 });
75 });
76
77 describe('prototype', function() {
78 describe('isSupport(adapterName)', function() {
79 it('should return false if invalid adapter name passed', function() {
80 expect(method.isSupport('abc')).to.be.false;
81 });
82
83 [
84 'express',
85 'rpc',
86 'socketio'
87 ].forEach(function(adapterName) {
88 it(`should return true if '${adapterName}' passed`, function() {
89 expect(method.isSupport(adapterName)).to.be.true;
90 });
91 });
92 });
93
94 describe('fullPath()', function() {
95 it('should return expected full path with or without parent object', function() {
96 expect(method.fullPath()).to.be.eq('/');
97
98 method.parent = {
99 fullPath: function() {
100 return '/users';
101 }
102 };
103
104 method.route.path = '/profile';
105
106 expect(method.fullPath()).to.be.eq('/users/profile');
107 });
108 });
109
110 describe('clone()', function() {
111 it('should clone as a new method with all same properties', function() {
112 let method = new Method('clone', {
113 description: 'clone method test',
114 params: [{ name: 'user' }],
115 route: { path: '/clone' }
116 }, function(next) {
117 next();
118 });
119
120 let methodCloned = method.clone();
121
122 expect(methodCloned).to.not.eq(method);
123
124 [
125 'name',
126 'stack',
127 'adapters',
128 'skipHooks',
129 'parent',
130 'params',
131 'description',
132 'notes',
133 'documented',
134 'route',
135 'upload',
136 'extra',
137 'options'
138 ].forEach(function(key) {
139 expect(methodCloned).to.have.property(key).to.deep.eq(method[key]);
140 });
141 });
142 });
143
144 describe('fullName()', function() {
145 it('should return expected full name with or without parent object', function() {
146 expect(method.fullName()).to.be.eq('test');
147
148 method.parent = {
149 fullName: function() {
150 return 'users';
151 }
152 };
153
154 method.route.path = '/profile';
155
156 expect(method.fullName()).to.be.eq('users.test');
157 });
158 });
159
160 describe('invoke() && compose(beforeStack, afterStack, errorStack)', function() {
161 it('should raise an error if method is not composed', function() {
162 expect(function() {
163 method.invoke();
164 }).to.throw(Error).to.have.property('message', 'Method: \'test\' must be composed before invoking');
165 });
166
167 it('should invoke composed function stack by predefined order without error', function(cb) {
168 let array = [];
169 let beforeStack = [
170 function(context, next) { array.push(1); next(); },
171 function(context, next) { array.push(2); next(); }
172 ];
173
174 method.fn = function(context, next) { array.push(3); next(); };
175
176 let afterStack = [
177 function(context, next) { array.push(4); next(); },
178 function(context, next) { array.push(5); next(); }
179 ];
180
181 let errorStack = [
182 function(context, next) { array.push(6); next(); },
183 ];
184
185 method.compose(beforeStack, afterStack, errorStack);
186
187 method.invoke().then(function() {
188 expect(array).to.deep.eq([1, 2, 3, 4, 5]);
189 }).then(cb, cb);
190 });
191
192 it('should invoke composed function stack by predefined order with error', function(cb) {
193 let array = [];
194 let beforeStack = [
195 function(context, next) { array.push(1); next(); },
196 function(context, next) { array.push(2); next(); }
197 ];
198
199 method.fn = function() { array.push(3); throw new Error('test'); };
200
201 let afterStack = [
202 function(context, next) { array.push(4); next(); },
203 function(context, next) { array.push(5); next(); }
204 ];
205
206 let errorStack = [
207 function(context, next) { array.push(6); next(); }
208 ];
209
210 method.compose(beforeStack, afterStack, errorStack);
211
212 method.invoke().then(function() {
213 expect(array).to.deep.eq([1, 2, 3, 6]);
214 }).then(cb, cb);
215 });
216 });
217 });
218});