8

由于我两次尝试将消息发布到JSpec Google Group显然都失败了,所以我在这里发帖。

我在使用JSpec时遇到问题,显然进入了带有某种测试的无限递归循环(如下)。有任何想法吗?我的代码有问题还是 JSpec 有问题?我正在通过 Ruby Gem 运行 JSpec 2.11.2。

错误是“RangeError:超出最大调用堆栈大小。” (Safari)和“内部错误:递归过多”(FF/Mac)。我可以使用 Firebug 控制台将项目添加到房间,没有错误。

要重现该问题,请使用“jspec init test”创建模板 jspec 项目。然后像这样编辑以下文件:

你的lib.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;
};

规范核心.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
4

1 回答 1

1

免责声明:我之前也没有听说过 JSpec(尽管如果您正在寻找Jasmine是一个不错的选择。

我唯一能想到的是“be”函数是如何工作的。如果它沿着对象图移动以查找两个项目是否相等,那么它可能会遇到循环依赖打嗝:即您在每个项目中引用您的房间,而这些房间又包含您的项目,而您的房间又包含您的房间和等等等等。这最终成为一个无限循环,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
    }
  }
}
于 2012-05-20T19:28:35.270 回答