2011-09-12 26 views
5

Lectura exhaustiva sobre varios marcos de aserciones en JavaScript. ¿Hay algún tipo de biblioteca/marco "estándar" de facto/más común? Al seleccionar uno, ¿qué puntos merecen más atención?Afirmaciones en JavaScript

El único requisito que puedo pensar es una sobrecarga de rendimiento cercana a cero cuando está en modo de producción.

+0

Quizás solo un error de fraseo, pero el rendimiento cero es producción sería malo. Quizás te refieres a una sobrecarga cercana a cero. –

+4

Afirmaciones? Hm, 'console.assert()'? –

+0

@Marc B: tienes razón :) arreglándolo. – BreakPhreak

Respuesta

6

dos soluciones posibles:

Haga que su guión liberación acumulación eliminar las líneas Assert.

o

Haga que su escritura de la estructura anular la función de aserción lo que es sólo una función de vacío. Lo malo de esto es si afirmas que call tiene lógica en él [también conocido como assert (x> 100, "foo")] que la lógica [x> 100] todavía se ejecutará.

+0

de acuerdo! Entonces, no hay forma de hacer que el cálculo de los argumentos sea nulo, ¿verdad? – BreakPhreak

+0

La única forma es eliminarlo o cambiar el lenguaje de aserción para que sea más parecido a jUnit/JSUnit/QUnit donde tiene diferentes comprobaciones assertTrue, assertFalse, assertEquals, assertNotSame. – epascarello

+0

A propósito de aprobar la respuesta. Solo si es posible, ¿podría aclarar sobre esto último? Como, si tengo 'assertTrue (a! = B)' - ¿qué truco puedo aplicar, de modo que 'a! = B' no se calculará en modo de producción (menos sobrecarga)? – BreakPhreak

4

Aquí es lo que uso:

Cuando estoy trabajando en el código que tengo initDevMode(); en la parte superior del archivo con el que estoy trabajando, y cuando estoy listo para lanzarlo a la producción, simplemente elimino esa línea y todas las afirmaciones pasan a una función vacía.

/** 
* Log a message to console: 
* either use jquery's console.error 
* or a thrown exception. 
* 
* call initDevMode(); before use to activate 
* use with: 
*  assert(<condition>, "message"); 
*  eg: assert(1 != 1, "uh oh!"); 
* 
* Log errors with: 
*  errorLog(message); 
*  eg: errorLog(xhr.status); 
*/ 
assert = function(test, msg) { } 
errorLog =function(msg) { } 

initDevMode = function() { 
    assert = function(test, msg) { 
     msg = msg || "(no error message)"; 
     if(!test) { 
      try { 
        throw Error(); 
       } catch(e) { 
        var foo = e; 
        var lines = e.stack.split('\n'); 
        for(i in lines) { 
         if(i > 2) { 
         errorLog(msg + lines[i]); 
        } 
       } 
      } 
     } 
     throw("Assertion failed with: " + msg); 
    }; 
    errorLog = function(msg) { 
     if(typeof console.error == 'function') { 
      console.error(msg); 
     } else { 
      function errorLog(msg) { 
       console.log("foo"); 
       setTimeout(function() { 
        throw new Error(msg); 
       }, 0); 
      } 
     } 
    }; 
} 
+1

No debería 'throw (' Falló la aserción ')' resid 'dentro' if (! Test) 'block? –

0

Echa un vistazo a Jascree; básicamente es una herramienta que puede eliminar aserciones con lógica casi arbitraria de su código. Es útil utilizarlo como procesador por lotes para generar su código de producción o para un directorio de scripts respaldado por fastcgi que puede usar cuando necesite evaluar el rendimiento/perfil de su código.

2

Utilizo lo siguiente para reemplazar console.assert cuando no está disponible por la razón que sea.

Definitivamente no es un estándar de facto, y está lejos de ser ideal, pero satisface su requisito de que la afirmación no se evalúe en modo de producción. Además, le muestra la expresión que desencadenó la afirmación fallida, que ayuda a la depuración.

La sintaxis de llamada screwy (con una expresión de función) está ahí para crear un cierre, de modo que la función assert tenga acceso a las mismas variables a las que tuvo acceso el llamador.

Sospecho que esto tiene un alto tiempo de compilación y una sobrecarga de tiempo de ejecución, pero no he intentado verificarlo.

function assert(func) { 
    var name; 
    if (typeof(ENABLE_ASSERTIONS) !== "undefined" && !ENABLE_ASSERTIONS) { 
     return; 
    } 
    name = arguments.callee.caller; 
    name = name ? name.name : "(toplevel)"; 
    if (!func()) { 
     throw name + ": assertion failed: " + ('' + func).replace(/function[^(]*\([^)]*\)[^{]*{[^r]*return/, '').replace(/;[ \t\n]*}[ \t\n]*$/, ''); 
    } 
} 

Usando que parece:

function testAssertSuccess() { 
    var i = 1; 
    assert(function() { return i === 1; }); 
} 
function testAssertFailure() { 
    var j = 1; 
    assert(function() { return j === 2; }); 
} 
ENABLE_ASSERTIONS = true; 
testAssertSuccess(); 
testAssertFailure(); 

HTH!

Cuestiones relacionadas