从chai的api你有这样的代码:
-(void)setCopyedString:(NSMutableString *)copyedString{
_copyedString = [copyedString mutableCopy];
}
这是如何存在部分工作的? expect函数返回一个对象,然后在"到"上只需要一个属性查找。宾语。这只是一项财产评估,但不是吗?对我来说唯一有意义的是,如果存在属性是一个getter方法。
该怎么回事?
答案 0 :(得分:3)
chai公开use
方法来访问chai
导出,并utils
。
creating plugins时,第三方可以使用此方法,但内部也可以使用此方法加载其接口。
这种方法的实现很简单:
exports.use = function (fn) {
if (!~used.indexOf(fn)) {
fn(this, util);
used.push(fn);
}
return this;
};
在内部,它使用它来加载(以及其他)主要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
Assertion prototype
公开的方法之一是addProperty
方法,它允许您向所述prototype
添加属性。
内部chai
使用此方法将核心断言功能添加到Assertion prototype
。例如,所有语言链和断言助手(exist
,empty
等)都以这种方式添加。
语言链:
[ 'to', 'be', 'been'
, 'is', 'and', 'has', 'have'
, 'with', 'that', 'which', 'at'
, 'of', 'same' ].forEach(function (chain) {
Assertion.addProperty(chain, function () {
return this;
});
});
当内部加载特定接口时,所有这些功能都可用,例如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
};
};
如您所见,expect
方法接受val
参数(以及可选的message
参数)。调用此方法时(例如expect(foo)
)将实例化并返回新的Assertion prototype
,从而暴露所有核心功能(允许您执行expect(foo).to.exist
)。
Assertion Constructor
使用flag
util
在Object上设置一个标记值,该值映射到传入的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);
}
然后,所有exist
都通过flag
util
获取此值,并使用定义的null
方法评估它是否等于assert
在Assertion prototype
。
Assertion.addProperty('exist', function () {
this.assert(
null != flag(this, 'object')
, 'expected #{this} to exist'
, 'expected #{this} to not exist'
);
});
答案 1 :(得分:1)
当你调用expect(foo)
时,会实例化一个新的Assertion对象。
to,have,with和类似属性除了返回Assertion实例之外什么都不做。它们只是为了便于阅读。
但是,在您的示例中,存在,实际上是运行断言的东西。
它的财产。他们将属性添加到Assertion的方式是将它们定义为getter函数see here.
expect(foo).to.exist
可以分解为:
const assertion = new Assertion;
assertion.exists;
使用getter将 assertion.exists
添加到断言对象。
这意味着当您执行assertion.exists以评估assertion.exists的值时,会执行先前提供给addProperty
的函数。
您可以阅读有关getter functions的更多信息。