2011-09-12 10 views
5

Obszerne czytanie o różnych frameworkach asercji w JavaScript. Czy istnieje jakaś de facto/najczęstsza "standardowa" biblioteka/framework? Przy wyborze jednego - które punkty są najbardziej warte zauważenia?Asercje w JavaScript

Wymóg (jedyny), jaki mogę wziąć pod uwagę, to maksymalny narzut wydajności w trybie produkcyjnym.

+0

Może tylko fraza glitch - ale zero wydajności to produkcja będzie zła. Być może masz na myśli przybliżenie do zera. –

+4

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

+0

@Marc B: masz rację :) poprawianie. – BreakPhreak

Odpowiedz

6

Dwa możliwe rozwiązania:

Wykonaj skrypt wersji kompilacji, usuwając linie Assert.

lub

Czy skrypt build przesłonić funkcję Assert więc jest to tylko funkcja pusta. Wadą tego jest to, że jeśli twierdzimy, że wywołanie ma logikę [aka assert (x> 100, "foo")], to logika [x> 100] nadal będzie działała.

+0

zgodził się! więc nie ma możliwości unieważnienia obliczeń argumentów, prawda? – BreakPhreak

+0

Jedynym sposobem jest usunięcie go lub zmiana języka asercji na bardziej jUnit/JSUnit/QUnit, gdzie masz różne sprawdzenia assertTrue, assertFalse, assertEquals, assertNotSame. – epascarello

+0

O zatwierdzeniu odpowiedzi. W miarę możliwości - czy mógłbyś wyjaśnić to ostatnie? Na przykład, jeśli mam 'assertTrue (a! = B)' - jaką sztuczkę mogę zastosować, aby 'a! = B' nie było obliczane w trybie produkcyjnym (mniej narzutów)? – BreakPhreak

4

Oto co mogę użyć:

Kiedy pracuję nad kodem mam initDevMode(); na górze pliku, nad którym pracuję, i kiedy jestem gotowy do wydania do produkcji, po prostu usuwam tę linię i wszystkie potwierdzenia, idą do pustej funkcji.

/** 
* 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

Nie należy "rzucać (" Asercja nie powiodła się ")" znajduje się w bloku "if (! Test)"? –

0

Spójrz na Jascree; zasadniczo jest to narzędzie, które może usuwać asercje z niemal dowolną logiką z twojego kodu. Jest przydatny jako procesor wsadowy do generowania kodu produkcyjnego lub do katalogu skryptów z zabezpieczeniem fastcgi, z którego można korzystać, gdy trzeba przetestować wydajność/profilować swój kod.

2

Używam następujących elementów, aby zamienić plik console.assert, gdy jest on niedostępny z jakiegokolwiek powodu.

Z pewnością nie jest to norma de facto, i jest dalekie od ideału, ale spełnia twoje wymagania, aby twierdzenie nie było oceniane w trybie produkcji. Pokazuje również wyrażenie, które spowodowało niepowodzenie asercji, co pomaga w debugowaniu.

Skrętna składnia wywołania (z wyrażeniem funkcji) służy do utworzenia zamknięcia, dzięki czemu funkcja assert ma dostęp do tych samych zmiennych, do których dzwoniący miał dostęp.

Podejrzewam, że ma to wysoką wartość czasu kompilacji i czasu pracy, ale nie próbowałem tego sprawdzać.

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]*$/, ''); 
    } 
} 

Korzystanie wygląda tak:

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!

Powiązane problemy