38 votes

Comment déclarer une variable dans une étendue spécifique dans coffeescript?

Je suis en train d'écrire un jasmin test en coffeescript qui utilise un beforeEach bloc. Cela heurte à un problème avec coffeescript de la variable de portée. Voici ce que je voudrais écrire:

describe 'PhoneDetailCtrl', () ->
  beforeEach () ->
    scope = angular.scope()
    $browser = scope.$service('$browser')

  it 'should fetch phone detail', () ->
    scope.params = {phoneId:'xyz'}
    $browser.xhr.expectGET('phones/xyz.json').respond({name:'phone xyz'})
    ctrl = scope.$new(PhoneDetailCtrl)

    expect(ctrl.phone).toEqualData({})
    $browser.xhr.flush()

    expect(ctrl.phone).toEqualData({name:'phone xyz'})

Cela ne fonctionne pas, bien que, parce que l' scope et $browser obtiendrez déclaré avec var au plus profond de la portée. C'est, une fois dans l' beforeEach puis à nouveau en it bloc. Je peux forcer les variables déclarées dans la bonne portée par l'initialisation, mais cela semble très étrange:

describe 'PhoneDetailCtrl', () ->
  $browser = {}
  scope = {}
  beforeEach () ->
    scope = angular.scope()
    $browser = scope.$service('$browser')

  it 'should fetch phone detail', () ->
    scope.params = {phoneId:'xyz'}
    ...

Cela fonctionne, mais le javascript, il compile est en fait

describe('PhoneListCtrl', function() {
  var $browser, ctrl, scope;
  $browser = {};
  ctrl = {};
  scope = {};

où tous j'ai besoin est la ligne var $browser, ctrl, scope;. Puis-je écrire cela de façon plus concise, en coffeescript?

30voto

Brian Genisio Points 30777

Vous faites de la bonne façon.

Ceci est décrit dans le CoffeeScript de la documentation. Je ne voudrais pas vous soucier de la JS qu'il crée. Oui, c'est un peu brouillon, si vous écrivez vous-même, mais c'est l'une des choses que vous avez à vivre avec lorsque vous utilisez un re-écrivain comme CoffeeScript.

Vous n'avez, cependant, ont un couple d'options qui sont assez sympa.

Vous pouvez mettre les variables dans le contexte actuel, si vous le souhaitez (qui se trouve être votre jasmin.Spec objet pour les curieux, il est relativement sûr et approprié pour mettre variables... il suffit de ne pas écraser existant vars dans le contexte.):

describe 'PhoneDetailCtrl', () ->
  beforeEach () ->
    @scope = angular.scope()
    @$browser = @scope.$service('$browser')

it 'should fetch phone detail', () ->
  @scope.params = {phoneId:'xyz'}
  #... etc

Vous pouvez également configurer votre propre variable dans laquelle stocker les choses

describe 'PhoneDetailCtrl', () ->
  setup = {}

  beforeEach () ->
    setup.scope = angular.scope()
    setup.$browser = setup.scope.$service('$browser')

  it 'should fetch phone detail', () ->
    setup.scope.params = {phoneId:'xyz'}
    #... etc

10voto

L'un des représentants de Angular m'a dirigé vers cet exemple: https://github.com/GoogleChrome/textdrive-app/blob/master/test/unit/services/storageSpec.coffee

Votre test pourrait être écrit comme suit:

 describe "MyGame", ->
    mygame = null
    beforeEach inject (_MyGame_) ->
        mygame = _MyGame_

    it "should have two players", ->
        expect(mygame.opponents.length).toEqual 2
 

Syntaxe beaucoup plus propre - sans la nécessité de rendre les choses globales.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X