[Service] Integrate DeviceHome and SignalingServer
[platform/framework/web/wrtjs.git] / device_home / node_modules / jake / lib / test_task.js
1 /*
2  * Jake JavaScript build tool
3  * Copyright 2112 Matthew Eernisse (mde@fleegix.org)
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *         http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17 */
18
19 let path = require('path');
20 let currDir = process.cwd();
21
22 /**
23   @name jake
24   @namespace jake
25 */
26 /**
27   @name jake.TestTask
28   @constructor
29   @description Instantiating a TestTask creates a number of Jake
30   Tasks that make running tests for your software easy.
31
32   @param {String} name The name of the project
33   @param {Function} definition Defines the list of files containing the tests,
34   and the name of the namespace/task for running them. Will be executed on the
35   instantiated TestTask (i.e., 'this', will be the TestTask instance), to set
36   the various instance-propertiess.
37
38   @example
39   let t = new jake.TestTask('bij-js', function () {
40     this.testName = 'testSpecial';
41     this.testFiles.include('test/**');
42   });
43
44  */
45 let TestTask = function () {
46   let self = this;
47   let args = Array.prototype.slice.call(arguments);
48   let name = args.shift();
49   let definition = args.pop();
50   let prereqs = args.pop() || [];
51
52   /**
53     @name jake.TestTask#testNam
54     @public
55     @type {String}
56     @description The name of the namespace to place the tests in, and
57     the top-level task for running tests. Defaults to "test"
58    */
59   this.testName = 'test';
60
61   /**
62     @name jake.TestTask#testFiles
63     @public
64     @type {jake.FileList}
65     @description The list of files containing tests to load
66    */
67   this.testFiles = new jake.FileList();
68
69   /**
70     @name jake.TestTask#showDescription
71     @public
72     @type {Boolean}
73     @description Show the created task when doing Jake -T
74    */
75   this.showDescription = true;
76
77   /*
78     @name jake.TestTask#totalTests
79     @public
80     @type {Number}
81     @description The total number of tests to run
82   */
83   this.totalTests = 0;
84
85   /*
86     @name jake.TestTask#executedTests
87     @public
88     @type {Number}
89     @description The number of tests successfully run
90   */
91   this.executedTests = 0;
92
93   if (typeof definition == 'function') {
94     definition.call(this);
95   }
96
97   if (this.showDescription) {
98     desc('Run the tests for ' + name);
99   }
100
101   task(this.testName, prereqs, {async: true}, function () {
102     let t = jake.Task[this.fullName + ':run'];
103     t.on('complete', function () {
104       complete();
105     });
106     // Pass args to the namespaced test
107     t.invoke.apply(t, arguments);
108   });
109
110   namespace(self.testName, function () {
111
112     let runTask = task('run', {async: true}, function (pat) {
113       let re;
114       let testFiles;
115
116       // Don't nest; make a top-level namespace. Don't want
117       // re-calling from inside to nest infinitely
118       jake.currentNamespace = jake.defaultNamespace;
119
120       re = new RegExp(pat);
121       // Get test files that match the passed-in pattern
122       testFiles = self.testFiles.toArray()
123         .filter(function (f) {
124           return (re).test(f);
125         }) // Don't load the same file multiple times -- should this be in FileList?
126         .reduce(function (p, c) {
127           if (p.indexOf(c) < 0) {
128             p.push(c);
129           }
130           return p;
131         }, []);
132
133       // Create a namespace for all the testing tasks to live in
134       namespace(self.testName + 'Exec', function () {
135         // Each test will be a prereq for the dummy top-level task
136         let prereqs = [];
137         // Continuation to pass to the async tests, wrapping `continune`
138         let next = function () {
139           complete();
140         };
141         // Create the task for this test-function
142         let createTask = function (name, action) {
143           // If the test-function is defined with a continuation
144           // param, flag the task as async
145           let t;
146           let isAsync = !!action.length;
147
148           // Define the actual namespaced task with the name, the
149           // wrapped action, and the correc async-flag
150           t = task(name, createAction(name, action), {
151             async: isAsync
152           });
153           t.once('complete', function () {
154             self.executedTests++;
155           });
156           t._internal = true;
157           return t;
158         };
159         // Used as the action for the defined task for each test.
160         let createAction = function (n, a) {
161           // A wrapped function that passes in the `next` function
162           // for any tasks that run asynchronously
163           return function () {
164             let cb;
165             if (a.length) {
166               cb = next;
167             }
168             if (!(n == 'before' || n == 'after' ||
169                     /_beforeEach$/.test(n) || /_afterEach$/.test(n))) {
170               jake.logger.log(n);
171             }
172             // 'this' will be the task when action is run
173             return a.call(this, cb);
174           };
175         };
176           // Dummy top-level task for everything to be prereqs for
177         let topLevel;
178
179         // Pull in each test-file, and iterate over any exported
180         // test-functions. Register each test-function as a prereq task
181         testFiles.forEach(function (file) {
182           let exp = require(path.join(currDir, file));
183
184           // Create a namespace for each filename, so test-name collisions
185           // won't be a problem
186           namespace(file, function () {
187             let testPrefix = self.testName + 'Exec:' + file + ':';
188             let testName;
189             // Dummy task for displaying file banner
190             testName = '*** Running ' + file + ' ***';
191             prereqs.push(testPrefix + testName);
192             createTask(testName, function () {});
193
194             // 'before' setup
195             if (typeof exp.before == 'function') {
196               prereqs.push(testPrefix + 'before');
197               // Create the task
198               createTask('before', exp.before);
199             }
200
201             // Walk each exported function, and create a task for each
202             for (let p in exp) {
203               if (p == 'before' || p == 'after' ||
204                   p == 'beforeEach' || p == 'afterEach') {
205                 continue;
206               }
207
208               if (typeof exp.beforeEach == 'function') {
209                 prereqs.push(testPrefix + p + '_beforeEach');
210                 // Create the task
211                 createTask(p + '_beforeEach', exp.beforeEach);
212               }
213
214               // Add the namespace:name of this test to the list of prereqs
215               // for the dummy top-level task
216               prereqs.push(testPrefix + p);
217               // Create the task
218               createTask(p, exp[p]);
219
220               if (typeof exp.afterEach == 'function') {
221                 prereqs.push(testPrefix + p + '_afterEach');
222                 // Create the task
223                 createTask(p + '_afterEach', exp.afterEach);
224               }
225             }
226
227             // 'after' teardown
228             if (typeof exp.after == 'function') {
229               prereqs.push(testPrefix + 'after');
230               // Create the task
231               let afterTask = createTask('after', exp.after);
232               afterTask._internal = true;
233             }
234
235           });
236         });
237
238         self.totalTests = prereqs.length;
239         process.on('exit', function () {
240           // Throw in the case where the process exits without
241           // finishing tests, but no error was thrown
242           if (!jake.errorCode && (self.totalTests > self.executedTests)) {
243             throw new Error('Process exited without all tests completing.');
244           }
245         });
246
247         // Create the dummy top-level task. When calling a task internally
248         // with `invoke` that is async (or has async prereqs), have to listen
249         // for the 'complete' event to know when it's done
250         topLevel = task('__top__', prereqs);
251         topLevel._internal = true;
252         topLevel.addListener('complete', function () {
253           jake.logger.log('All tests ran successfully');
254           complete();
255         });
256
257         topLevel.invoke(); // Do the thing!
258       });
259
260     });
261     runTask._internal = true;
262
263   });
264
265
266 };
267
268 jake.TestTask = TestTask;
269 exports.TestTask = TestTask;
270