Blackbing Playground

[PhantomJS] Function.prototype.bind

PhantomJS 1.9.7 (Mac OS X) ERROR

使用 reactjs 來寫 test case 時,用 PhantomJS 執行時就遇到這個 error,奇怪的是用其他的 browser 來執行就沒有問題。

1
2
3
TypeError: 'undefined' is not a function (evaluating 'RegExp.prototype.test.bind(
/^(data|aria)-[a-z_][a-z\d_.\-]*$/
)')

查了一下追到這個 issue Function.prototype.bind is undefined,看起來是 PhantomJS 的內核沒有支援 Function.prototype.bind。於是再找到 MDN 的 Function.prototype.bind,在載入 reactJS 之前先將這個 polyfill 加進去就可以解決了。

karma.conf.js

1
2
3
4
5
files: [
'test/polyfill/*.js',
'app/bower_components/react/react-with-addons.js',
'.tmp/test/spec/*.js'
]

phantom_bind_polyfill.js(2014/8/3 updated)

use react official polyfill

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
(function() {
var Ap = Array.prototype;
var slice = Ap.slice;
var Fp = Function.prototype;
if (!Fp.bind) {
// PhantomJS doesn't support Function.prototype.bind natively, so
// polyfill it whenever this module is required.
Fp.bind = function(context) {
var func = this;
var args = slice.call(arguments, 1);
function bound() {
var invokedAsConstructor = func.prototype && (this instanceof func);
return func.apply(
// Ignore the context parameter when invoking the bound function
// as a constructor. Note that this includes not only constructor
// invocations using the new keyword but also calls to base class
// constructors such as BaseClass.call(this, ...) or super(...).
!invokedAsConstructor && context || this,
args.concat(slice.call(arguments))
);
}
// The bound function must share the .prototype of the unbound
// function so that any object created by one constructor will count
// as an instance of both constructors.
bound.prototype = func.prototype;
return bound;
};
}
})();