1// Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
2//
3// Use of this source code is governed by a BSD-style license
4// that can be found in the LICENSE file in the root of the source
5// tree. An additional intellectual property rights grant can be found
6// in the file PATENTS.  All contributing project authors may
7// be found in the AUTHORS file in the root of the source tree.
8//
9// This script loads all the test/* files into a very small context that
10// only exposes a minimal set of functions that allows to register tests.
11//
12// Once all files are loaded it runs the specific test on the command line.
13// If no arguments are given it lists all the registered tests.
14//
15// Note: the small context where the scripts are loaded is intended to keep
16// nodejs-isms away from the test code and isolate implementation details away
17// from them.
18var fs = require('fs');
19var vm = require('vm');
20var Test = require('./test.js');
21
22var testSuites = {};
23
24function registerTest(name, func) {
25  testSuites[name] = func;
26}
27
28function registerBotTest(name, func, bots) {
29  registerTest(name, bootstrap);
30
31  function bootstrap(test) {
32    var callbacks = [];
33    for (var i = 0; i != bots.length; ++i)
34      callbacks.push(test.spawnBot.bind(test, "", bots[i]));
35
36    test.wait(callbacks, func.bind(test, test));
37  }
38}
39
40function loadTestFile(filename, doneCallback) {
41  var loadTestContext = {
42    setTimeout: setTimeout,
43    registerTest: registerTest,
44    registerBotTest: registerBotTest
45  };
46  var script = vm.createScript(fs.readFileSync(filename), filename);
47  script.runInNewContext(loadTestContext);
48  doneCallback();
49}
50
51function iterateOverTestFiles(foreachCallback, doneCallback) {
52  fs.readdir('test', function (error, list) {
53    function iterateNextFile() {
54      if (list.length === 0) {
55        doneCallback();
56      } else {
57        var filename = list.pop();
58        if (filename[0] === '.' || filename.slice(-3) !== '.js') {
59          // Skip hidden and non .js files on that directory.
60          iterateNextFile();
61        } else {
62          foreachCallback('test/' + filename, iterateNextFile);
63        }
64      }
65    }
66
67    if (error !== null) {
68      throw error;
69    }
70    iterateNextFile();
71  });
72}
73
74function runTest(testname) {
75  if (testname in testSuites) {
76    console.log("Running test: " + testname);
77    var test = new Test();
78    testSuites[testname](test);
79  } else {
80    console.log("Unknown test: " + testname);
81  }
82}
83
84function printUsage() {
85  console.log('Run as:\n $ '
86      + process.argv[0] + ' ' + process.argv[1]
87      + ' <testname>');
88  console.log('These are the existent ones:');
89  for (var testname in testSuites)
90    console.log('  ' + testname);
91}
92
93function main() {
94  // TODO(andresp): support multiple tests.
95  var testList = process.argv.slice(2);
96  if (testList.length === 1)
97    runTest(testList[0]);
98  else
99    printUsage();
100}
101
102iterateOverTestFiles(loadTestFile, main);
103