UNPKG

6.56 kBJavaScriptView Raw
1/* eslint-env mocha */
2'use strict';
3
4const os = require('os');
5const path = require('path');
6const fs = require('mz/fs');
7const madge = require('../lib/api');
8
9require('should');
10
11describe('API', () => {
12 it('throws error on missing path argument', () => {
13 (() => {
14 madge();
15 }).should.throw('path argument not provided');
16 });
17
18 it('returns a Promise', () => {
19 madge(__dirname + '/cjs/a.js').should.be.Promise(); // eslint-disable-line new-cap
20 });
21
22 it('throws error if file or directory does not exists', (done) => {
23 madge(__dirname + '/missing.js').catch((err) => {
24 err.message.should.match(/no such file or directory/);
25 done();
26 }).catch(done);
27 });
28
29 it('takes single file as path', (done) => {
30 madge(__dirname + '/cjs/a.js').then((res) => {
31 res.obj().should.eql({
32 'a.js': ['b.js', 'c.js'],
33 'b.js': ['c.js'],
34 'c.js': []
35 });
36 done();
37 }).catch(done);
38 });
39
40 it('takes an array of files as path and combines the result', (done) => {
41 madge([__dirname + '/cjs/a.js', __dirname + '/cjs/normal/d.js']).then((res) => {
42 res.obj().should.eql({
43 'a.js': ['b.js', 'c.js'],
44 'b.js': ['c.js'],
45 'c.js': [],
46 'normal/d.js': []
47 });
48 done();
49 }).catch(done);
50 });
51
52 it('take a single directory as path and find files in it', (done) => {
53 madge(__dirname + '/cjs/normal').then((res) => {
54 res.obj().should.eql({
55 'a.js': ['sub/b.js'],
56 'd.js': [],
57 'sub/b.js': ['sub/c.js'],
58 'sub/c.js': ['d.js']
59 });
60 done();
61 }).catch(done);
62 });
63
64 it('takes an array of directories as path and compute the basedir correctly', (done) => {
65 madge([__dirname + '/cjs/multibase/1', __dirname + '/cjs/multibase/2']).then((res) => {
66 res.obj().should.eql({
67 '1/a.js': [],
68 '2/b.js': []
69 });
70 done();
71 }).catch(done);
72 });
73
74 it('takes a predefined tree', (done) => {
75 madge({
76 a: ['b', 'c', 'd'],
77 b: ['c'],
78 c: [],
79 d: ['a']
80 }).then((res) => {
81 res.obj().should.eql({
82 a: ['b', 'c', 'd'],
83 b: ['c'],
84 c: [],
85 d: ['a']
86 });
87 done();
88 }).catch(done);
89 });
90
91 it('can exclude modules using RegExp', (done) => {
92 madge(__dirname + '/cjs/a.js', {
93 excludeRegExp: ['^b.js$']
94 }).then((res) => {
95 res.obj().should.eql({
96 'a.js': ['c.js'],
97 'c.js': []
98 });
99 done();
100 }).catch(done);
101 });
102
103 describe('dependencyFilter', () => {
104 it('will stop traversing when returning false', (done) => {
105 madge(__dirname + '/cjs/a.js', {
106 dependencyFilter: () => {
107 return false;
108 }
109 }).then((res) => {
110 res.obj().should.eql({
111 'a.js': []
112 });
113 done();
114 }).catch(done);
115 });
116
117 it('will not stop traversing when not returning anything', (done) => {
118 madge(__dirname + '/cjs/a.js', {
119 dependencyFilter: () => {}
120 }).then((res) => {
121 res.obj().should.eql({
122 'a.js': ['b.js', 'c.js'],
123 'b.js': ['c.js'],
124 'c.js': []
125 });
126 done();
127 }).catch(done);
128 });
129
130 it('will pass arguments to the function', (done) => {
131 let counter = 0;
132
133 madge(__dirname + '/cjs/a.js', {
134 dependencyFilter: (dependencyFilePath, traversedFilePath, baseDir) => {
135 if (counter === 0) {
136 dependencyFilePath.should.match(/test\/cjs\/b\.js$/);
137 traversedFilePath.should.match(/test\/cjs\/a\.js$/);
138 baseDir.should.match(/test\/cjs$/);
139 }
140
141 if (counter === 1) {
142 dependencyFilePath.should.match(/test\/cjs\/c\.js$/);
143 traversedFilePath.should.match(/test\/cjs\/a\.js$/);
144 baseDir.should.match(/test\/cjs$/);
145 }
146
147 if (counter === 2) {
148 dependencyFilePath.should.match(/test\/cjs\/c\.js$/);
149 traversedFilePath.should.match(/test\/cjs\/b\.js$/);
150 baseDir.should.match(/test\/cjs$/);
151 }
152
153 counter++;
154 }
155 }).then(() => {
156 done();
157 }).catch(done);
158 });
159 });
160
161 describe('obj()', () => {
162 it('returns dependency object', (done) => {
163 madge(__dirname + '/cjs/a.js').then((res) => {
164 res.obj().should.eql({
165 'a.js': ['b.js', 'c.js'],
166 'b.js': ['c.js'],
167 'c.js': []
168 });
169 done();
170 }).catch(done);
171 });
172 });
173
174 describe('warnings()', () => {
175 it('returns an array of skipped files', (done) => {
176 madge(__dirname + '/cjs/missing.js').then((res) => {
177 res.obj().should.eql({
178 'missing.js': ['c.js'],
179 'c.js': []
180 });
181 res.warnings().should.eql({
182 skipped: ['./path/non/existing/file']
183 });
184 done();
185 }).catch(done);
186 });
187 });
188
189 describe('dot()', () => {
190 it('returns a promise resolved with graphviz DOT output', (done) => {
191 madge(__dirname + '/cjs/b.js')
192 .then((res) => res.dot())
193 .then((output) => {
194 output.should.eql('digraph G {\n "b.js";\n "c.js";\n "b.js" -> "c.js";\n}\n');
195 done();
196 })
197 .catch(done);
198 });
199 });
200
201 describe('depends()', () => {
202 it('returns modules that depends on another', (done) => {
203 madge(__dirname + '/cjs/a.js').then((res) => {
204 res.depends('c.js').should.eql(['a.js', 'b.js']);
205 done();
206 }).catch(done);
207 });
208 });
209
210 describe('orphans()', () => {
211 it('returns modules that no one is depending on', (done) => {
212 madge(__dirname + '/cjs/normal').then((res) => {
213 res.orphans().should.eql(['a.js']);
214 done();
215 }).catch(done);
216 });
217 });
218
219 describe('image()', () => {
220 let imagePath;
221
222 beforeEach(() => {
223 imagePath = path.join(os.tmpdir(), 'madge_' + Date.now() + '_image.png');
224 });
225
226 afterEach(() => {
227 return fs.unlink(imagePath).catch(() => {});
228 });
229
230 it('rejects if a filename is not supplied', (done) => {
231 madge(__dirname + '/cjs/a.js')
232 .then((res) => res.image())
233 .catch((err) => {
234 err.message.should.eql('imagePath not provided');
235 done();
236 });
237 });
238
239 it('rejects on unsupported image format', (done) => {
240 madge(__dirname + '/cjs/a.js')
241 .then((res) => res.image('image.zyx'))
242 .catch((err) => {
243 err.message.should.match(/Format: "zyx" not recognized/);
244 done();
245 });
246 });
247
248 it('rejects if graphviz is not installed', (done) => {
249 madge(__dirname + '/cjs/a.js', {graphVizPath: '/invalid/path'})
250 .then((res) => res.image('image.png'))
251 .catch((err) => {
252 err.message.should.match(/Could not execute .*gvpr \-V/);
253 done();
254 });
255 });
256
257 it('writes image to file', (done) => {
258 madge(__dirname + '/cjs/a.js')
259 .then((res) => res.image(imagePath))
260 .then((writtenImagePath) => {
261 writtenImagePath.should.eql(imagePath);
262
263 return fs
264 .exists(imagePath)
265 .then((exists) => {
266 if (!exists) {
267 throw new Error(imagePath + ' not created');
268 }
269 done();
270 });
271 })
272 .catch(done);
273 });
274 });
275});