Почему реактивность Tracker не срабатывает ровно в половину времени при использовании нескольких вычислений в одном блоке описания Jasmine?
При тестировании реактивности с помощью Jasmine некоторые вычисления в Tracker начали вести себя очень интригующе: ровно половина вычислений реактивна, другая половина - нет.
Чтобы проверить это, я сделал следующее:
//In a describe block
var foo = new ReactiveVar(false);
it('should react to the changes of foo (1)', function(done) {
Tracker.autorun(function observeFoo(fooComputation) {
var fooValue = foo.get();
console.log('foo in its computation is', fooValue);
if ( fooValue === true ) {
fooComputation.stop();
done();
}
});
setTimeout(function setFoo() {
foo.set(true);
}, 100);
});
Итак, в основном:
- Инициализировать реактивный
foo
вfalse
, - Начните отслеживать его, ожидая, пока он доберется до
true
так что тест объявленdone()
, - Используйте тайм-аут для
foo.set(true)
и таким образом решить тест. - Остановите это вычисление, потому что оно больше не нужно.
Теперь давайте сделаем то же самое с другой переменной:
var foo = new ReactiveVar(false),
bar = new ReactiveVar(false);
it('should react to the changes of foo (1)', function(done) { /* ... */ });
it('should react to the changes of bar (2)', function(done) {
Tracker.autorun(function observeBar(barComputation) {
var barValue = bar.get();
console.log('bar in its computation is', barValue);
if ( barValue === true ) {
barComputation.stop();
done();
}
});
setTimeout(function setBar() {
bar.set(true);
}, 100);
});
Вот где начинается самое интересное. Хотя этот тест представляет собой тот же код с другим именем и имеет точно такую же написанную логику, он не проходит, потому что панель отслеживания вычислений никогда не запускается повторно.
console.log
показывает это очень хорошо:
foo в своих вычислениях:
false
foo в своих вычислениях:true
- включилась реактивность!
Бар в своем расчете:false
[Ничего такого]
Хотя очень ясно, что вычисления для foo
был перезапущен и, таким образом, его тест был завершен, вычисление для bar
никогда не аннулируется и, следовательно, тест не пройден.
Однако это не останавливается здесь. Если мы добавим третий контрольный пример для новой реактивной переменной (скажем, baz
) и следуйте той же процедуре, что и раньше (инициализируйте ее другими, добавляя тест в конце того же describe
функция) то работает отлично!
var foo = new ReactiveVar(false),
bar = new ReactiveVar(false),
baz = new ReactiveVar(false);
it('should react to the changes of foo (1)', function(done) { /* ... */ });
it('should react to the changes of bar (2)', function(done) { /* ... */ });
it('should react to the changes of baz (3)', function(done) { /* ... */ });
Вот тест (1)
успешно, тест (2)
не проходит тест (3)
преуспевает.
Теперь, если мы добавим четвертый тест, с новым cat
например, следуя той же процедуре... Затем проверьте (4)
потерпит неудачу со следующим журналом.
Фу в его вычислении
false
Фу в его вычисленииtrue
бар в своем расчетеfalse
бар не перезапускается и не работает
Баз в своих вычисленияхfalse
Баз в своих вычисленияхtrue
кот в своем расчетеfalse
кот не запускается и не работает
[Ничего такого]
foo
а также baz
были прореагированы, а не bar
а также cat
,
Я сделал это с двумя другими (пятым и шестым), тот же результат: (5)
преуспевает, (6)
выходит из строя.
"Нечетные" тесты успешны, "четные" не пройдены.
Полный код воспроизведения:
describe('Tracker usage with Jasmine', function() {
var foo = new ReactiveVar(false),
bar = new ReactiveVar(false),
baz = new ReactiveVar(false),
cat = new ReactiveVar(false),
pup = new ReactiveVar(false),
elf = new ReactiveVar(false);
it('should react to the changes of foo (1)', function(done) {
Tracker.autorun(function observeFoo(fooComputation) {
var fooValue = foo.get();
console.log('foo in its computation is', fooValue);
if ( fooValue === true ) {
fooComputation.stop();
done();
}
});
setTimeout(function setFoo() {
foo.set(true);
}, 100);
});
it('should react to the changes of bar (2)', function(done) {
Tracker.autorun(function observeBar(barComputation) {
var barValue = bar.get();
console.log('bar in its computation is', barValue);
if ( barValue === true ) {
barComputation.stop();
done();
}
});
setTimeout(function setBar() {
bar.set(true);
}, 100);
});
it('should react to the changes of baz (3)', function(done) {
Tracker.autorun(function observeBaz(bazComputation) {
var bazValue = baz.get();
console.log('baz in its computation is', bazValue);
if ( bazValue === true ) {
bazComputation.stop();
done();
}
});
setTimeout(function setBaz() {
baz.set(true);
}, 100);
});
it('should react to the changes of cat (4)', function(done) {
Tracker.autorun(function observeCat(catComputation) {
var catValue = cat.get();
console.log('cat in its computation is', catValue);
if ( catValue === true ) {
catComputation.stop();
done();
}
});
setTimeout(function setCat() {
cat.set(true);
}, 100);
});
it('should react to the changes of pup (5)', function(done) {
Tracker.autorun(function observePup(pupComputation) {
var pupValue = pup.get();
console.log('pup in its computation is', pupValue);
if ( pupValue === true ) {
pupComputation.stop();
done();
}
});
setTimeout(function setPup() {
pup.set(true);
}, 100);
});
it('should react to the changes of elf (6)', function(done) {
Tracker.autorun(function observeElf(elfComputation) {
var elfValue = elf.get();
console.log('elf in its computation is', elfValue);
if ( elfValue === true ) {
elfComputation.stop();
done();
}
});
setTimeout(function setElf() {
elf.set(true);
}, 100);
});
});
Почему это происходит?
Как я могу решить эту проблему, сохраняя все эти реактивные переменные в одном и том же describe
функционировать?
Я попытался добавить вложенный describe
функционирует без успеха.
Эта проблема волшебным образом исчезает при изоляции тестов в их собственных не связанных describe
функции, пожалуйста, не отвечайте таким образом.