JSpec - RangeError: превышен максимальный размер стека вызовов
После двух моих попыток отправить сообщение в группу Google JSpec, по-видимому, не получилось, вместо этого я публикую здесь.
У меня возникли проблемы с JSpec, по- видимому входящим в бесконечный рекурсивный цикл с определенным типом теста (ниже). Есть идеи? Что-то не так с моим кодом или это JSpec? Я использую JSpec 2.11.2 через Ruby Gem.
Ошибки "RangeError: превышен максимальный размер стека вызовов". (Safari) и "InternalError: слишком много рекурсии" (FF/Mac). Я могу добавить Предмет в Комнату, используя консоль Firebug, без ошибок.
Чтобы воспроизвести проблему, создайте шаблон проекта jspec с помощью 'jspec init test'. Затем отредактируйте следующие файлы следующим образом:
yourlib.core.js
var Game = {};
Game.item = function () {
var result = {
name : 'Undefined',
room : null
}
return result;
};
Game.room = function () {
var result = {
items : [],
addItem : function (name) {
var item = Game.item();
item.name = name;
item.room = this;
this.items.push(item);
return item;
}
};
return result;
};
spec.core.js
describe 'Room'
before_each
room = Game.room()
end
describe 'addItem()'
before_each
potion = room.addItem('Potion')
key = room.addItem('Key')
end
//this is fine
it 'should return two different items'
key.should_not.be potion
end
//InternalError: too much recursion
it 'should not give recursion error'
key.should.be potion
end
end
end
1 ответ
Отказ от ответственности: я также не слышал о JSpec раньше (хотя Жасмин является хорошей альтернативой, если вы ищете один.
Единственное, о чем я могу думать, это как работает функция "быть". Если он перемещается по графу объектов, чтобы определить, равны ли два элемента, то это может привести к циклическому сбоям в зависимости: т.е. вы ссылаетесь на свою комнату в каждом элементе, который, в свою очередь, содержит ваши элементы, которые, в свою очередь, содержат ваши комнаты и так далее и так далее. Это заканчивается бесконечным циклом, из которого функция be не может вернуться эффективно, заполняя стек, и, таким образом, выдает ошибку, которую вы видите.
Примерно так (без сравнения, также: не тестировал и не запускал этот код, возьмите его в качестве псевдокода для пояснения приведенного выше абзаца):
function be(obj) {
for (var key in obj) {
if (typeof(obj[key]) === "object") {
be(obj[key]); // If you have circular dependencies, the recursion never ends
}
}
}