                   completions))
     (should (= start-col 7))))
 
-(ycmd-ert-test-deferred goto-declaration "test-goto.cpp" 'c++-mode
-  (apply-partially #'ycmd--send-completer-command-request "GoToDeclaration")
-  7 9
+(ycmd-ert-test-deferred-request goto-declaration "test-goto.cpp" 'c++-mode
+  :request-func (apply-partially #'ycmd--send-completer-command-request
+                                 "GoToDeclaration")
+  :line 9 :column 7
   (if (assoc-default 'exception response)
       (should nil)
     (progn
       (should (= (assoc-default 'column_num response) 10))
       (should (= (assoc-default 'line_num response) 2)))))
 
-(ycmd-ert-test-deferred goto-definition "test-goto.cpp" 'c++-mode
-  (apply-partially #'ycmd--send-completer-command-request "GoToDefinition")
-  7 9
+(ycmd-ert-test-deferred-request goto-definition "test-goto.cpp" 'c++-mode
+  :request-func (apply-partially #'ycmd--send-completer-command-request
+                                 "GoToDefinition")
+  :line 9 :column 7
   (if (assoc-default 'exception response)
       (should nil)
     (progn

      (ycmd-test-mode))
    buff))

(defmacro ycmd-ert-test-deferred (name filename mode request-func column line &rest body)
  "Define a test case for a deferred request to the ycmd.

NAME is a symbol denoting the local name of the test.  The test
itself is named `ycmd-test-NAME'.  FILENAME is the input file with
the `major-mode' MODE.  REQUEST-FUNC is the function with the
request to the ycmd server.  COLUMN and LINE is the file location
for the request.  The remaining forms of BODY are used to evaluate
the server's response,"
  (declare (indent 3) (debug t))
  (let ((full-name (intern (format "ycmd-test-%s" name))))
    `(ert-deftest ,full-name ()
       (let* ((buff (ycmd-test-prepare-file ,filename ,mode))
              (current-position (ycmd--col-line-to-position ,column ,line buff)))
         (deferred:sync!
           (deferred:$
             (funcall ,request-func buff current-position)
             (deferred:nextc it
               (lambda (response)
                 ,@body))))
         (kill-buffer buff)))))

(ycmd-ert-test-deferred get-completions "test.cpp" 'c++-mode
  'ycmd-get-completions
  7 8
  (let ((start-col (assoc-default 'completion_start_column response))
        (completions (assoc-default 'completions response)))
    (should (some (lambda (c)

    (deferred:sync!
      (ycmd-notify-file-ready-to-parse))))

(defun ycmd-test-prepare-buffer-for-file (filename mode)
  "Read FILENAME into new temporary buffer and return in.
Put the buffer into MODE, and run `ycmd-test-mode' on it."
  (let ((buff (find-file-noselect
               (f-join ycmd-test-resources-location filename))))
    (with-current-buffer buff
