Merge branch 'feature/allow-callfake-to-be-async' of https://github.com/mrlannigan/jasmine into merge-test

    - Merges #1448 from @mrlannigan
diff --git a/.travis.yml b/.travis.yml
index 9d1f756..0092e7e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -24,7 +24,16 @@
   include:
     - env:
       - USE_SAUCE=false
-      - TEST_COMMAND="bash travis-node-script.sh"
+      - TEST_COMMAND="bash travis-node-script.sh v0.12.18"
+    - env:
+      - USE_SAUCE=false
+      - TEST_COMMAND="bash travis-node-script.sh v4"
+    - env:
+      - USE_SAUCE=false
+      - TEST_COMMAND="bash travis-node-script.sh v8"
+    - env:
+      - USE_SAUCE=false
+      - TEST_COMMAND="bash travis-node-script.sh v9"
     - env:
       - JASMINE_BROWSER="safari"
       - SAUCE_OS="OS X 10.11"
diff --git a/lib/jasmine-core/jasmine.js b/lib/jasmine-core/jasmine.js
index e54501e..f30b7b0 100644
--- a/lib/jasmine-core/jasmine.js
+++ b/lib/jasmine-core/jasmine.js
@@ -5010,7 +5010,7 @@
      * @param {Function} fn The function to invoke with the passed parameters.
      */
     this.callFake = function(fn) {
-      if(!j$.isFunction_(fn)) {
+      if(!(j$.isFunction_(fn) || j$.isAsyncFunction_(fn))) {
         throw new Error('Argument passed to callFake should be a function, got ' + fn);
       }
       plan = fn;
diff --git a/spec/core/SpyStrategySpec.js b/spec/core/SpyStrategySpec.js
index 0965c04..16f1af1 100644
--- a/spec/core/SpyStrategySpec.js
+++ b/spec/core/SpyStrategySpec.js
@@ -92,12 +92,35 @@
     expect(returnValue).toEqual(67);
   });
 
+  it("allows a fake async function to be called instead", function(done) {
+    jasmine.getEnv().requireAsyncAwait();
+    var originalFn = jasmine.createSpy("original"),
+        fakeFn = jasmine.createSpy("fake").and.callFake(eval("async () => { return 67; }")),
+        spyStrategy = new jasmineUnderTest.SpyStrategy({fn: originalFn}),
+        returnValue;
+
+    spyStrategy.callFake(fakeFn);
+    spyStrategy.exec().then(function (returnValue) {
+      expect(originalFn).not.toHaveBeenCalled();
+      expect(fakeFn).toHaveBeenCalled();
+      expect(returnValue).toEqual(67);
+      done();
+    }).catch(function (err) {
+      done.fail(err);
+    })
+  });
+
   it('throws an error when a non-function is passed to callFake strategy', function() {
     var originalFn = jasmine.createSpy('original'),
         spyStrategy = new jasmineUnderTest.SpyStrategy({fn: originalFn}),
         invalidFakes = [5, 'foo', {}, true, false, null, void 0, new Date(), /.*/];
 
     spyOn(jasmineUnderTest, 'isFunction_').and.returnValue(false);
+    spyOn(jasmineUnderTest, 'isAsyncFunction_').and.returnValue(false);
+
+    expect(function () {
+      spyStrategy.callFake(function() {});
+    }).toThrowError(/^Argument passed to callFake should be a function, got/);
 
     expect(function () {
       spyStrategy.callFake(function() {});
diff --git a/src/core/SpyStrategy.js b/src/core/SpyStrategy.js
index 5af7cbe..b0c716f 100644
--- a/src/core/SpyStrategy.js
+++ b/src/core/SpyStrategy.js
@@ -88,7 +88,7 @@
      * @param {Function} fn The function to invoke with the passed parameters.
      */
     this.callFake = function(fn) {
-      if(!j$.isFunction_(fn)) {
+      if(!(j$.isFunction_(fn) || j$.isAsyncFunction_(fn))) {
         throw new Error('Argument passed to callFake should be a function, got ' + fn);
       }
       plan = fn;
diff --git a/travis-node-script.sh b/travis-node-script.sh
index 6fa0ded..fe3859b 100644
--- a/travis-node-script.sh
+++ b/travis-node-script.sh
@@ -4,7 +4,7 @@
 git clone https://github.com/creationix/nvm.git ~/.nvm
 (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`)
 source ~/.nvm/nvm.sh
-nvm install v0.12.18
+nvm install ${1:-"v0.12.18"}
 
 npm install
 npm test