-
Notifications
You must be signed in to change notification settings - Fork 347
Run hs2hs on .hsc-files before loading #1238
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f57ce5a
d6a8eea
de7dd07
91800f0
31bc866
4dc2902
914175e
15a0471
68a70c6
44dac28
3489200
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
;; haskell-hsc2hs-tests.el --- -*- lexical-binding: t; -*- | ||
|
||
(require 'ert) | ||
(require 'haskell) | ||
(require 'haskell-test-utils) | ||
|
||
|
||
(defvar default-hsc "{-# LANGUAGE CPP #-} | ||
{-# LANGUAGE CApiFFI #-} | ||
{-# LANGUAGE ForeignFunctionInterface #-} | ||
|
||
module Hsc2hsTest where | ||
|
||
import Foreign | ||
import Foreign.C.String | ||
import Foreign.C.Types | ||
|
||
#include <stdlib.h> | ||
|
||
newtype NUMBERS = NUMBERS { unNUMBERS :: CInt } | ||
deriving (Eq,Show) | ||
|
||
#{enum NUMBERS, NUMBERS | ||
, rand_max = RAND_MAX | ||
} | ||
") | ||
|
||
(defvar fake-ghci "#!/usr/bin/awk -f | ||
|
||
BEGIN { | ||
printf \"%s\", \"Your wish is my IO ().\\nChanged directory: /tmp/\\nPrelude> \" | ||
fflush() | ||
} | ||
|
||
/^:t unNUMBERS rand_max$/ { | ||
printf \"%s\", \"unNUMBERS rand_max :: CInt\\nPrelude> \" | ||
fflush() | ||
next | ||
} | ||
|
||
{ | ||
printf \"%s\", \"\\n<interactive>:\"NR\":1-\"length($0)\": Not in scope: ‘\"$0\"’\\nPrelude> \" | ||
fflush() | ||
} | ||
" "Very stupid fake ghci specific to our tests") | ||
|
||
(defvar fake-hsc2hs "#!/usr/bin/awk -f | ||
|
||
/^#{/ { | ||
skip = 1 | ||
} | ||
|
||
!skip && !/^#include/ { | ||
lines = lines $0\"\\n\" | ||
} | ||
|
||
/}/ { | ||
skip = 0 | ||
} | ||
|
||
/A_TYPO/ { | ||
print FILENAME\":\"NR\":58: error: ‘A_TYPO’ undeclared (first use in this function)\" >\"/dev/stderr\" | ||
lines=\"\" | ||
exit(1) | ||
} | ||
|
||
END { | ||
if(lines) { | ||
lines = lines \"rand_max :: NUMBERS\\n\" | ||
lines = lines \"rand_max = NUMBERS 2147483647\\n\" | ||
hs = FILENAME | ||
sub(/hsc$/, \"hs\", hs) | ||
if(FILENAME==hs) { | ||
print FILENAME\" doesn't seem to end in .hsc\">\"/dev/stderr\" | ||
exit(1) | ||
} | ||
else { | ||
print lines > hs | ||
} | ||
} | ||
} | ||
" "Very stupid fake hsc2hs specific to our tests") | ||
|
||
|
||
(defmacro with-hsc2hs (contents &rest body) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should always use the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
"Load CONTENTS as a .hsc, then run BODY after it's loaded into REPL. | ||
Uses fake hsc2hs script from this directory." | ||
(declare (debug t) (indent 1)) | ||
`(with-temp-switch-to-buffer | ||
(let* ((hsc (make-temp-file "haskell-hsc2hs-tests.el" nil ".hsc")) | ||
(hs (replace-regexp-in-string "\\.hsc\\'" ".hs" hsc))) | ||
(insert ,contents) | ||
(write-file hsc) | ||
(haskell-mode) | ||
(with-script-path haskell-process-path-hsc2hs fake-hsc2hs 'keep | ||
(haskell-process-load-file) | ||
(let ((proc (get-buffer-process "*hsc2hs*"))) | ||
(while (and proc (eq (process-status proc) 'run)) ; TODO: is there no built-in way to block-wait on a process? | ||
(sit-for 0.5)) | ||
,@body) | ||
(delete-file haskell-process-path-hsc2hs)) | ||
(delete-file hsc) | ||
(when (file-exists-p hs) | ||
(delete-file hs))))) | ||
|
||
(ert-deftest hsc2hs-errors () | ||
(custom-set-variables '(haskell-process-wrapper-function #'identity)) ; altered by some earlier test | ||
(let ((error-hsc (concat default-hsc | ||
"newtype FOO = FOO { unFOO :: CInt } deriving (Eq,Show)\n" | ||
"#{enum FOO, FOO , a_typo = A_TYPO }\n"))) | ||
(with-hsc2hs error-hsc | ||
(with-current-buffer "*hsc2hs*" | ||
(goto-char (point-min)) | ||
(when (re-search-forward "A_TYPO" nil 'noerror) | ||
(goto-char (match-beginning 0))) | ||
(should (looking-at-p "A_TYPO. undeclared")))))) | ||
|
||
(ert-deftest hsc2hs-compile-and-load () | ||
(custom-set-variables '(haskell-process-wrapper-function #'identity)) ; altered by some earlier test | ||
(with-script-path haskell-process-path-ghci fake-ghci 'keep | ||
(custom-set-variables '(haskell-process-args-ghci '("-W" "interactive"))) | ||
(with-hsc2hs default-hsc | ||
(with-current-buffer (haskell-session-interactive-buffer haskell-session) | ||
(goto-char (point-max)) | ||
(insert ":t unNUMBERS rand_max") | ||
(goto-char (point-max)) | ||
(haskell-interactive-handle-expr) | ||
(sit-for 1.0) ; TODO: can we wait until the prompt appears, with a timeout? | ||
(forward-line -1) | ||
(should (looking-at-p "unNUMBERS rand_max :: CInt")))) | ||
(delete-file haskell-process-path-ghci))) | ||
|
||
;; haskell-hsc2hs-tests.el ends here |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great test!