Как объявить переменную в определенной области в coffeescript?
Я пытаюсь написать тест жасмина в coffeescript, который использует блок beforeEach. Это сталкивается с проблемой изменения масштаба переменной coffeescript. Вот что я хотел бы написать:
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'})
Это не работает, потому что scope
и $browser
будут объявлены с помощью var
в самой внутренней области. То есть, один раз в beforeEach
, а затем снова в блоке it
. Я могу заставить переменные объявляться в правильной области, инициализируя их, но это кажется очень странным:
describe 'PhoneDetailCtrl', () ->
$browser = {}
scope = {}
beforeEach () ->
scope = angular.scope()
$browser = scope.$service('$browser')
it 'should fetch phone detail', () ->
scope.params = {phoneId:'xyz'}
...
Это работает, но javascript, который он компилирует, на самом деле
describe('PhoneListCtrl', function() {
var $browser, ctrl, scope;
$browser = {};
ctrl = {};
scope = {};
где мне нужна только строка var $browser, ctrl, scope;
. Могу ли я написать это более кратко в coffeescript?
Ответы
Ответ 1
Вы делаете это правильно.
Это описано в документации CoffeeScript. Я бы не стал беспокоиться о том, что он создает. Да, это немного беспорядочно, если вы должны сами написать это, но это одна из тех вещей, с которыми вам приходится жить, когда вы используете репитера, такого как CoffeeScript.
Однако у вас есть несколько вариантов, которые довольно приятны.
Вы можете поместить переменные в текущий контекст, если хотите (что, вероятно, будет вашим объектом jasmine.Spec для любопытных, поэтому это относительно безопасное и подходящее место для размещения переменных... просто не перезаписывайте существующие vars в контексте.):
describe 'PhoneDetailCtrl', () ->
beforeEach () ->
@scope = angular.scope()
@$browser = @scope.$service('$browser')
it 'should fetch phone detail', () ->
@scope.params = {phoneId:'xyz'}
#... etc
Вы также можете настроить свою собственную переменную для хранения вещей
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
Ответ 2
Ваш тест можно записать следующим образом:
describe "MyGame", ->
mygame = null
beforeEach inject (_MyGame_) ->
mygame = _MyGame_
it "should have two players", ->
expect(mygame.opponents.length).toEqual 2
Более чистый синтаксис - без необходимости делать вещи глобальными.