Как стать автором
Обновить

Комментарии 7

> Знать о том, что в языке есть labels я конечно знал, но не догадывался что они такие капризные. Ломающим сценарием было:

Может я чего то не понимаю, но если обернуть эту конструкцию в блок, то ничего не сломается.
в блоки оборачивались statements, которым был For Statement
{ l1: { for (var x in y) { continue l1; } } }
Так можно и весь JavaScript капризным обозвать, мол этот expression возращает не reference, а value — какой же он капризный.

Кстати то, что вы в статье добавили перенос строки после лэйбла ничего не поменяло. Он как добавлялся в labels list следующего statement, так и добавляется. Было бы хорошо, если бы вы в статье описали более подробно саму проблему, а не называли лэйблы копризными, хотя просто сами допустили ошибку, разрывая связь identifier и statement.

Я не про то, что о боже мой, как можно было допустить ошибку. А про то, что «капризные лэйблы» ничего не объясняет для читателя.
Перенос строки я добавил чтобы было более понятно, что именно оборачивание в блок for-in statement-а влечет за собой проблему, а не оборачивание всего куска кода.

Поясню проблему подробнее. Моя ошибка заключалась (как и было сказано в статье) в неверном предположении, что оборачивание *любого* for, for-in, while, do-while statement-а в блок не является деструктивным.

Проблема заключается в том, что в случае если for, for-in, while. do-while statement-а является частью тела labeled statement и в цикле использутся continue lableName, его нельзя просто взять и обернуть в блок, так как это изменение повлечет за собой ошибку выполнения.

То есть
loop: 
for (i = 0; i < 3; i++) {
  if (i == 1) {
    continue loop;
  }
  console.log(i);
}

работать будет, а
loop: 
{ for (i = 0; i < 3; i++) {
  if (i == 1) {
    continue loop;
  }
  console.log(i);
}}

не найдет label loop при выполнении цикла.

При всем при этом этом
loop: 
{ for (i = 0; i < 3; i++) {
  if (i == 1) {
    break loop;
  }
  console.log(i);
}}

или
lbl1: {{
    console.log('will be displayed');
    break lbl1;
    console.log('will not be displayed');
}}

будет работать.

Из-за описанных особенностей я назвал labels капризными, но вы правы, так можно назвать капризными любые особенности, которых не ожидаешь. Пусть будет не капризные, а неожиданные.
Да, я имеено про это описание проблемы, которое и должно быть в статье, спасибо :)
Добрый день. А как можно использовать instanbul, в клиентских скриптах? При команде cover мне выдает, что не найден jQuery.
Я использую istanbul следующим образом:
В проекте используется grunt с помощью которого помимо всего прочего запускаются клиентские тесты.
Клиентские тесты написаны на Jasmine. Если вы используете другой тествовый framework (qunit или mocha например) то нужно его поискать в списке расширений и использовать. У меня из расширений grunt установлены grunt-contrib-jasmine и grunt-template-jasmine-istanbul.

Gruntfile.js выглядит примерно так:

//...
grunt.initConfig({
   //...
   jasmine: {
      dev: {
        specRoot: 'test/',
        src: '*.js',
        options: {
          vendor: [
            'libs/jquery-1.9.1.min.js',
            'libs/*.js'
          ],
          specs: 'test/*Spec.js',
          template: require('grunt-template-jasmine-istanbul'),
          templateOptions: {
            coverage: 'bin/client-coverage-dev/coverage.json',
            report: 'bin/client-coverage-dev',
            thresholds: {
              lines: 80,
              statements: 80,
              branches: 80,
              functions: 80
            }
          }
        }
      }
   }
   //...
});
//...
grunt.loadNpmTasks('grunt-contrib-jasmine');
//...
grunt.registerTask('testclient', ['jasmine:dev']);
//...


Соответственно команда 'grunt testclient' запускает тесты ('test/*Spec.js) в phantomjs и создает отчеты в bin/client-coverage-dev.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории