2013-03-01 8 views
6

Sto tentando di ASCIUGARE alcuni test sul gelsomino estraendo esempi condivisi.Jasmine ha condiviso problemi con lo scope con il coffeescript

@sharedExamplesForThing = (thing) -> 
    beforeEach -> 
    @thingy = new thing 

    it "is neat", -> 
    expect(@thingy.neat).toBeTruthy() 


describe "widget with shared behavior", -> 
    sharedExamplesForThing(-> new Widget) 

Questo funziona bene quando tutto è definito in un unico file. I problemi che sto incontrando si verificano quando provo a spostare gli esempi condivisi in un file separato. Ottengo Can't find variable: sharedExamplesForThing ...

Così nell'interesse di debug, ho provato la seguente:

describe "widget with shared behavior", -> 
    it "is acting like a meany", -> 
    console.log sharedExamplesForThing 
    expect(false).toBeTruthy() 
    sharedExamplesForThing(-> new Widget) 

Nel blocco is acting like a meany, il registro mostra sharedExamplesForThing come [Function] ma ho ancora ottenere il Can't find variable al di fuori del it. Penso che questo potrebbe avere qualcosa a che fare con un problema di scoping al di fuori della mia esperienza attuale, ma potrei sbagliarmi completamente. Cosa mi manca qui?

(usando le rotaie, riso jasmine, guard-gelsomino)

risposta

1

Quando si assegna una variabile membro di primo livello nella CoffeeScript viene assegnato come una proprietà dell'oggetto globale (window in un browser). Quindi genera il seguente JavaScript:

window.sharedExamplesForThing = ...; 

Ciò significa che si può fare riferimento ad esso al di fuori del file come window.sharedExamplesForThing o semplicemente sharedExamplesForThing. Quindi quello che stai facendo dovrebbe funzionare assumendo che il file di esempio condiviso sia stato caricato prima del file spec. Penso che il problema che si ha è che il file spec viene caricato per primo (perché le funzioni di descrizione vengono eseguite mentre il file viene caricato mentre le funzioni vengono eseguite dopo che tutti i file sono stati caricati). Quindi potrebbe essere necessario modificare l'ordine di caricamento, è possibile provare a mettere i file di esempi condivisi in una directory support e quindi richiedere questo prima.

Invece di assegnare le variabili direttamente all'oggetto finestra può essere meglio di creare uno spazio dei nomi per esportare le variabili condivise in (in modo da non ingombrare l'oggetto globale):

window.MyNamespace = {} 

MyNamespace.sharedExamplesForThing = ... 

Poi, nel il tuo file spec puoi riferirti ad esso come MyNamespace.sharedExamplesForThing.

Trovo utile osservare il codice JavaScript generato per cercare di capire come CoffeeScript esporta le variabili tra i file.

0

Ecco il post del blog che ho scritto sul modo migliore di fare esempi condivisi. Spero che questo ti aiuti.

http://pivotallabs.com/drying-up-jasmine-specs-with-shared-behavior/

+0

Il tuo post è altamente incompleto. In primo luogo, manca il 'sharedBehaviorForGameOf 'di cui si sta parlando, e in secondo luogo, sto avendo un file spec di prova che è quasi il 100% della tua replica, anche alla gerarchia esatta e con un solo' it() 'blocco per 'describe()' block, e ancora, le mie variabili "condivise" sono visibili solo al mio primo test e non sono referenziabili in nessun altro test al di sotto del primo. Penso che poche persone come me apprezzeranno se completi il ​​tuo articolo e fornisci alcuni suggerimenti su vars/funzioni condivise. Oltre a questo, hai fatto un ottimo lavoro in biblioteca, lo adoro. – dimitarvp

+0

Ho dimenticato di menzionare che sto cercando di usare le vars condivise nei blocchi 'runs()' che consumano il risultato di una chiamata AJAX reale (non presa in giro). Forse è un problema di scoping, poiché ovviamente i tuoi esempi di vanilla funzionano abbastanza bene. – dimitarvp

2

ho trovato il pezzo su shared examples from thoughtbot veramente utile.

ho implementato in CoffeeScript come segue:

1) In alcuni file di supporto che viene caricato prima di tutti i file spec:

window.FooSpec = 
    sharedExamples: {} 

window.itShouldBehaveLike = (-> 
    exampleName  = _.first(arguments) 
    exampleArguments = 
    _.select(_.rest(arguments), ((arg) => return !_.isFunction(arg))) 
    innerBlock  = _.detect(arguments, ((arg) => return _.isFunction(arg))) 
    exampleGroup  = FooSpec.sharedExamples[exampleName] 

    if(exampleGroup) 
    return describe(exampleName, (-> 
     exampleGroup.apply(this, exampleArguments) 
     if(innerBlock) then innerBlock() 
    ) 
    ) 
    else 
    return it("cannot find shared behavior: '" + exampleName + "'", (-> 
     expect(false).toEqual(true) 
    ) 
    ) 
) 

2) Per le mie specifiche:

(a) Posso definire un comportamento condiviso:

FooSpec.sharedExamples["had a good day"] = (-> 
    it "finds good code examples", -> 
     expect(this.thoughtbot_spy).toHaveBeenCalled() 
) 

(b) e usarlo ovunque in alcune specifiche come:

itShouldBehaveLike("had a good day") 

(Nota: Io parto dal presupposto spec ha definito this.thoughtbot_spy conseguenza prima riga sopra)

Problemi correlati