2015-07-24 15 views
11

Od api Chai za masz kodu:Jak działa funkcja oczekiwana przez Chai?

.exist 

Asserts that the target is neither null nor undefined. 

var foo = 'hi' 
    , bar = null 
    , baz; 

expect(foo).to.exist; 
expect(bar).to.not.exist; 
expect(baz).to.not.exist; 

Jak to istnieje praca w niepełnym wymiarze? Funkcja oczekiwać zwraca obiekt, a następnie po prostu właściwość wyszukiwania na obiekcie "do". To po prostu ocena własności, prawda? Jedyne, co miałoby dla mnie sens, to fakt, że właściwość exist jest metodą gettera.

Co się udać?

+0

Jest to właściwość * getter *. – Bergi

+0

Tak, nie przywykłem do ich częstego używania. –

+0

Cóż, "chai" obejmuje je. I nie spojrzałeś na "powinien" ... – Bergi

Odpowiedz

2

chai ujawnia metodę use dostępu do eksportu chai i jest to utils.

Ta metoda może być używana przez osoby trzecie przy creating plugins, ale jest również używana wewnętrznie do ładowania interfejsu.

Realizacja tej metody jest prosta:

exports.use = function (fn) { 
    if (!~used.indexOf(fn)) { 
    fn(this, util); 
    used.push(fn); 
    } 

    return this; 
}; 

Wewnętrznie używa tego, aby załadować (między innymi) Podstawowym Assertion prototype i funkcjonalność rdzeń twierdzenie:

var assertion = require('./chai/assertion'); // primary Assertion prototype 
exports.use(assertion); // load it 

var core = require('./chai/core/assertions'); // core assertion functionality 
exports.use(core); // load it 

Jedną z metod, które są narażone przez Assertion prototype jest metoda addProperty, która pozwala na dodanie właściwości do wspomnianego prototype.

Wewnętrznie chai używa tej metody, aby dodać funkcję potwierdzenia rdzenia do Assertion prototype. Na przykład wszystkie łańcuchy językowe i pomocników asercji (exist, empty, itp.) Są dodawane w ten sposób.

łańcuchy Język:

[ 'to', 'be', 'been' 
    , 'is', 'and', 'has', 'have' 
    , 'with', 'that', 'which', 'at' 
    , 'of', 'same' ].forEach(function (chain) { 
    Assertion.addProperty(chain, function() { 
     return this; 
    }); 
    }); 

Cała ta funkcjonalność będzie dostępna, gdy specyficzny interfejs zostanie załadowany wewnętrznie, na przykład expect. Kiedy ten interfejs jest załadowany, nowy Assertion prototype zostanie instancja ilekroć expect zostanie wykonany, która będzie zawierać wszystkie funkcje:

// load expect interface 
var expect = require('./chai/interface/expect'); // expect interface 
exports.use(expect); // load it 

// expect interface 
module.exports = function (chai, util) { 
    chai.expect = function (val, message) { 
    return new chai.Assertion(val, message); // return new Assertion Object with all functionality 
    }; 
}; 

Jak widać metoda expect akceptuje val argument (i opcjonalnej message argument). Po wywołaniu tej metody (na przykład expect(foo)) zostanie utworzona i zwrócona nowa wersja Assertion prototype, odsłaniająca wszystkie podstawowe funkcje (umożliwiające wykonanie expect(foo).to.exist).

Assertion Constructor używa flagutil ustawić wartość flagi na obiekt, który mapuje do przekazany w val argument.

function Assertion (obj, msg, stack) { 
    flag(this, 'ssfi', stack || arguments.callee); 
    flag(this, 'object', obj); // the 'object' flag maps to the passed in val 
    flag(this, 'message', msg); 
    } 

Wszystko exist wtedy nie jest się tę wartość przez flagutil i ocenia, czy to nie jest równa null metodą assert zdefiniowany na Assertion prototype.

+0

Ale w jaki sposób zatrzymuje on pozostały kod po wykonaniu połączenia oczekującego, jeśli test się nie powiedzie? Na przykład, jeśli istnieje callback 'done()' później w 'it', to nie jest wykonywane ... –

0

Po wywołaniu expect(foo) tworzony jest nowy obiekt Assertion.

do, mieć, z, i podobne właściwości nie robią nic, tylko zwrócić instancję Assertion. Są one jedynie dla czytelności.

Jednak w twoim przykładzie istnieje, jest faktycznie czymś, co uruchamia asercję.

Jego właściwość. sposób ich właściwości są dodawane do twierdzenie jest, że są one zdefiniowane jako funkcje getter jak można see here.

expect(foo).to.exist mogłyby być podzielone tak:

const assertion = new Assertion; 
assertion.exists; 

assertion.exists dodaje do obiektu twierdzenie o getter. Oznacza to, że podczas wykonywania assertion.exists, aby ocenić wartość asercji.istnieje, funkcja, która została wcześniej dostarczona do addProperty jest wykonywana.

Możesz przeczytać więcej o getter functions.