/// Tester
///
/// Classe para testes automáticos.
///
/// NOTA: Assume que é usada em modo de depuração.
///
document.write ('');
W.Tester = function (optLoopsPerTest) {
var me = this;
me._testCount = me._failedCount = 0;
me._loopsPerTest = optLoopsPerTest || 1;
me._mask = null
}
W.Tester.prototype = Proto = new Object;
// Testa se a função chamada FUNC-NM retorna EXPECTED-RES quando recebe os argumentos em ARG-LISW.
Proto.testFunc = function (funcnm, arglist, expectedRes) {
var me = this, args = [], i, u = arguments.length - 1, f = eval (funcnm), res, l = me._loopsPerTest, t1, t2;
if (!me._allowTest (++me._testCount)) return;
for (i = 1; i < u; ++i) args.push (arguments [i]);
t1 = new Date;
for (i = 0; i < l; ++i)
res = f.apply (null, args);
t2 = new Date;
// Testar o resultado.
expectedRes = arguments [u];
me._print (funcnm, args, expectedRes, res, t2 - t1)
}
// Testa se o método METH-NM de OBJ, classe CLASSE-NM, retorna EXPECTED-RES quando recebe os argumentos em ARG-LISW.
Proto.testMethod = function (classnm, obj, methnm, arglist, expectedRes) {
var me = this, args = [], i, u = arguments.length - 1, res, f = eval ("obj." + methnm), l = me._loopsPerTest, t1, t2;
if (!me._allowTest (++me._testCount)) return;
for (i = 3; i < u; ++i) args.push (arguments [i]);
t1 = new Date;
for (i = 0; i < l; ++i)
res = f.apply (obj, args);
t2 = new Date;
// Extraír o nome da função.
// Testar o resultado.
expectedRes = arguments [u];
me._print (classnm + "." + methnm, args, expectedRes, res, t2 - t1)
}
// Termina o processamento de testes.
Proto.close = function () {
var me = this, tbl = me._tbl, tf, cell, s = "";
if (!tbl) return;
// Resumir desempenho dos testes.
if (me._testCount) {
s = me._testCount == 1 ? "1 teste corrido" : (me._testCount + " testes corridos")
switch (me._failedCount) {
case 0:
break;
case 1:
s += me._testCount > 1 ? ", mas 1 falhou" : ", mas falhado";
break;
default:
s += ", mas " + me._failedCount + "falharam"
}
}
else s = "Não foram corridos quaisquer testes.";
// Colocar a informação no rodapé.
tbl.tFoot.rows [0].cells [0].appendChild (D.createTextNode (s));
}
// Desliga todos os testes excepto aqueles identificados nos parâmetros.
Proto.disableAllExcept = function (/* ... */) { this._disable (0, arguments); }
// Desliga os testes identificados nos parâmetros.
Proto.disable = function (/* ... */) { this._disable (1, arguments); }
// Imprime os parâmetros de um teste e se foi bem-sucedido ou não.
Proto._print = function (funcnm, args, expectedRes, res, timeTaken) {
var me = this, tbl = me._tbl, tr, cell, t, body, succeeded;
// forçar a criação de uma nova tabela se a corrente tiver deixado de ser a última.
if (!tbl || tbl.nextSibling) {
tbl = me._tbl = D.createElement ("table");
tbl.cellSpacing = tbl.cellPadding = 0;
tbl.className = "tester-tbl";
// Criar o cabeçalho.
t = tbl.createTHead ();
tr = t.insertRow (-1);
_newCell (tr, "",
"Teste",
"Resultado Obtido",
"Resultado Esperado",
"Avaliação",
"T");
// Criar o rodapé.
t = tbl.createTFoot ();
cell = t.insertRow (-1).insertCell (-1);
cell.colSpan = 99;
// Criar o corpo.
tbl.appendChild (body = D.createElement ("TBODY"));
D.body.appendChild (tbl)
}
else body = tbl.tBodies [0];
// Testar resultados.
if (expectedRes && expectedRes.getFullYear && res && res.getFullYear) { // Caso especial na comparação de datas.
succeeded = expectedRes - res == 0;
}
else succeeded = expectedRes == res;
if (succeeded && expectedRes == null && res == null) {
if ((expectedRes + "" == "NaN") != (res + "" == "NaN")) succeeded = 0;
}
succeeded || ++me._failedCount;
// Criar nova linha para este teste.
t = dbg.asText ([res, expectedRes]);
res = t [0];
expectedRes = t [1];
tr = body.insertRow (-1);
if (!succeeded) tr.className = "erro";
else if (tbl.rows.length % 2 == 0)
tr.className = "x2";
_newCell (tr, me._testCount,
funcnm + "(" + dbg.asText (args) + ")",
res,
expectedRes,
succeeded ? "Ok" : "FALHOU",
timeTaken.toLocaleString () + "ms");
// Cria uma nova célula com o valor S.
function _newCell (tr, _rest_) {
var args = arguments, l = args.length, i;
for (i = 1; i < l;) {
cell = tr.insertCell (-1);
cell.innerHTML = args [i++];
}
}
}
// Indica se se pode processar o teste TEST-NUM.
Proto._allowTest = function (testNum) {
var me = this, m = me._mask;
if (!m) return 1;
return !m [testNum] == me._maskExcept
}
// Marca os testes identificados em ARGS. B indica se serão excluídos ou exclusivos.
Proto._disable = function (b, args) {
var i, m = this._mask = [], l = args.length;
for (i = 0; i < l; ++i) m [args [i]] = 1;
this._maskExcept = b;
}