柴如何期待功能的运作?

Lar*_*ess 13 javascript mocha.js chai

从chai的api你有这样的代码:

.exist

Asserts that the target is neither null nor undefined.

var foo = 'hi'
  , bar = null
  , baz;

expect(foo).to.exist;
expect(bar).to.not.exist;
expect(baz).to.not.exist;
Run Code Online (Sandbox Code Playgroud)

如何存在部分工作?expect函数返回一个对象,然后在"to"对象上只有一个属性查找.这只是一个房产评估,不是吗?对我来说唯一有意义的是,如果存在属性是一个getter方法.

怎么回事?

dan*_*ouz 5

chai 公开了一种访问use导出的方法chai,它是utils.

第三方在创建插件时可以使用此方法,但它也在内部用于加载其接口。

这个方法的实现很简单:

exports.use = function (fn) {
  if (!~used.indexOf(fn)) {
    fn(this, util);
    used.push(fn);
  }

  return this;
};
Run Code Online (Sandbox Code Playgroud)

在内部,它使用它来加载(除其他外)主要Assertion prototype和核心断言功能:

var assertion = require('./chai/assertion'); // primary Assertion prototype
exports.use(assertion); // load it

var core = require('./chai/core/assertions'); // core assertion functionality
exports.use(core); // load it
Run Code Online (Sandbox Code Playgroud)

公开的方法之一Assertion prototypeaddProperty允许您向所述添加属性的方法prototype

内部chai使用此方法将核心断言功能添加到Assertion prototype. 例如,所有语言链和断言助手(existempty等)都是以这种方式添加的。

语言链:

[ 'to', 'be', 'been'
  , 'is', 'and', 'has', 'have'
  , 'with', 'that', 'which', 'at'
  , 'of', 'same' ].forEach(function (chain) {
    Assertion.addProperty(chain, function () {
      return this;
    });
  });
Run Code Online (Sandbox Code Playgroud)

例如,当内部加载特定接口时,所有这些功能都可用expect。加载此接口后,Assertion prototype每当执行时都会实例化一个新接口expect,其中包含所有功能:

// load expect interface
var expect = require('./chai/interface/expect'); // expect interface
exports.use(expect); // load it

// expect interface
module.exports = function (chai, util) {
  chai.expect = function (val, message) {
    return new chai.Assertion(val, message); // return new Assertion Object with all functionality
  };
};
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,该expect方法接受一个val参数(和一个可选message参数)。当调用此方法时(例如expect(foo)Assertion prototype,将实例化并返回一个新方法,从而公开所有核心功能(允许您执行以下操作expect(foo).to.exist)。

使用Assertion Constructor来在映射flag util到传入参数的对象上设置标志值val

  function Assertion (obj, msg, stack) {
    flag(this, 'ssfi', stack || arguments.callee);
    flag(this, 'object', obj); // the 'object' flag maps to the passed in val
    flag(this, 'message', msg);
  }
Run Code Online (Sandbox Code Playgroud)

然后exist所做的就是通过 获取该值,并使用上定义的方法flag util评估它是否不等于。nullassertAssertion prototype

  Assertion.addProperty('exist', function () {
    this.assert(
        null != flag(this, 'object')
      , 'expected #{this} to exist'
      , 'expected #{this} to not exist'
    );
  });
Run Code Online (Sandbox Code Playgroud)