diff --git a/lisp/ob-haxe.el b/lisp/ob-haxe.el new file mode 100644 index 000000000..5b0a42c7a --- /dev/null +++ b/lisp/ob-haxe.el @@ -0,0 +1,260 @@ +;;; ob-haxe.el --- org-babel functions for haxe evaluation + +;; Copyright (C) 2020 Free Software Foundation, Inc. + +;; Author: Ian Martins +;; Keywords: literate programming, reproducible research +;; Homepage: http://orgmode.org + +;; This file is not part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;; Org-Babel support for evaluating haxe source code. + +;;; Code: +(require 'ob) + +(defvar org-babel-tangle-lang-exts) +(add-to-list 'org-babel-tangle-lang-exts '("haxe" . "hx")) + +(defvar org-babel-default-header-args:haxe '() + "Default header args for haxe source blocks.") + +(defconst org-babel-header-args:haxe '((target . '(interp neko hashlink)) + (imports . :any)) + "Haxe-specific header arguments. +org-babel supports three of the platforms the haxe compiler can target. + + `interp' runs the haxe compiler with the `--interp' option. + `neko' and `hashlink' compile to bytecode and run the + respective VMs.") + +(defvar org-babel-haxe-command "haxe" + "Name of the haxe command.") + +(defcustom org-babel-haxe-hline-to "null" + "Replace hlines in incoming tables with this when translating to haxe." + :group 'org-babel + :version "25.2" + :package-version '(Org . "9.3") + :type 'string) + +(defcustom org-babel-haxe-null-to 'hline + "Replace `null' in haxe tables with this before returning." + :group 'org-babel + :version "25.2" + :package-version '(Org . "9.3") + :type 'symbol) + +(defun org-babel-execute:haxe (body params) + "Execute a haxe source block with BODY code and PARAMS params." + (let* ((fullclassname (or (cdr (assq :classname params)) ; class and package + (org-babel-haxe-find-classname body) + "Main")) + (classname (if (seq-contains fullclassname ?.) ; just class name + (file-name-extension fullclassname) + fullclassname)) + (packagename (if (seq-contains fullclassname ?.) ; just package name + (file-name-base fullclassname) + "")) + (packagedir (if (not (seq-empty-p packagename)) ; package name as a path + (replace-regexp-in-string "\\\." "/" packagename))) + (src-file (concat (replace-regexp-in-string "\\\." "/" fullclassname) ".hx")) + (cmdline (or (cdr (assq :cmdline params)) "")) + (target-name (cdr (assq :target params))) + (target (cond ((string= target-name "neko") "-neko main.n -cmd \"neko main.n\"") + ((string= target-name "hashlink") "-hl main.hl -cmd \"hl main.hl\"") + (t "--interp"))) + (cmd (concat org-babel-haxe-command + " " cmdline " -main " fullclassname " " target)) + (result-type (cdr (assq :result-type params))) + (result-params (cdr (assq :result-params params))) + (tmp-file (and (eq result-type 'value) + (org-babel-temp-file "haxe-"))) + (full-body (org-babel-expand-body:haxe + body params classname packagename result-type tmp-file))) + + ;; created package-name directories if missing + (unless (or (not packagedir) (file-exists-p packagedir)) + (make-directory packagedir 'parents)) + (with-temp-file src-file (insert full-body)) + (org-babel-reassemble-table + (org-babel-haxe-evaluate cmd target-name result-type result-params tmp-file) + (org-babel-pick-name + (cdr (assoc :colname-names params)) (cdr (assoc :colnames params))) + (org-babel-pick-name + (cdr (assoc :rowname-names params)) (cdr (assoc :rownames params)))))) + +;; helper functions + +(defun org-babel-haxe-find-classname (body) + "Try to find fully qualified classname in BODY." + (let ((package (if (string-match "package \\\([^ ]*\\\);" body) + (match-string 1 body))) + (class (if (string-match "class \\\([^ \n]*\\\)" body) + (match-string 1 body)))) + (or (and package class (concat package "." class)) + class))) + +(defun org-babel-expand-body:haxe (body params classname packagename + result-type tmp-file) + "Expand BODY with PARAMS. +BODY could be a few statements, or could include a full class +definition specifying package, imports, and class. Because we +allow this flexibility in what the source block can contain, it +is simplest to expand the code block from the inside out. + +CLASSNAME name of the class, which may have been specified +in multiple ways. + +PACKAGENAME name of the java package containing this class. + +RESULT-TYPE output or value. + +TMP-FILE name of tempfile to write to if value `result-type'." + (let* ((var-lines (org-babel-variable-assignments:haxe params)) + (imports-val (assq :imports params)) + (imports (if imports-val + (split-string (org-babel-read (cdr imports-val) nil) " ") + nil))) + (with-temp-buffer + (insert body) + + ;; wrap main + (goto-char (point-min)) + (when (not (re-search-forward "static .*function main\(\)" nil t)) + (while (re-search-forward "^[[:space:]]*import .*;$" nil t) ; if imports are defined, move past them + (goto-char (1+ (match-end 0)))) + (insert "public static function main() {\n") + (goto-char (point-max)) + (insert "\n}")) + + ;; insert variables + (when var-lines + (goto-char (point-min)) + (if (re-search-forward "^[[:space:]]*class .*\n?{[[:space:]]*$" nil t) + (goto-char (1+ (match-end 0)))) + (insert (mapconcat 'identity var-lines "\n")) + (insert "\n")) + + ;; special handling to return value + (when (eq result-type 'value) + (goto-char (point-min)) + (re-search-forward "^[[:space:]]*class .*\n?{" nil t) + (insert "\n") + (insert " public static function main() {\n") + (insert (format " var output = File.write(\"%s\");\n" (org-babel-process-file-name tmp-file 'noquote))) + (insert " output.writeString(haxe.Json.stringify(_main()));\n") + (insert " output.close();\n") + (insert " }\n") + (search-forward "function main()") ; rename existing main + (replace-match "function _main()")) + + ;; wrap class + (goto-char (point-min)) + (when (not (re-search-forward "^[[:space:]]*class [^ ]*" nil t)) + (while (re-search-forward "^[[:space:]]*import .*;$" nil t) ; if imports are defined, move past them + (goto-char (1+ (match-end 0)))) + (insert (concat "class " (file-name-base classname) " {\n")) + (goto-char (point-max)) + (insert "\n}")) + + ;; add imports + (if (eq result-type 'value) + (setq imports (append '("sys.io.File") imports))) + (when imports + (if (re-search-forward "^[[:space:]]*package .*;$" nil t) ; if package is defined, move past it + (goto-char (1+ (match-end 0)))) + (goto-char (point-min)) + (insert (mapconcat (lambda (ii) (concat "import " ii ";\n")) imports "\n"))) + + ;; add package at the top + (goto-char (point-min)) + (when (not (re-search-forward "^[[:space:]]*package .*;$" nil t)) + (insert (concat "package " packagename ";\n\n"))) + + (buffer-string)))) ; return expanded body + +(defun org-babel-variable-assignments:haxe (params) + "Return a list of haxe statements assigning the block's variables. +variables are contained in PARAMS." + (mapcar + (lambda (pair) + (format " static var %s %s = %s;" + (car pair) + (if (and (sequencep (cdr pair)) + (not (stringp (cdr pair)))) ":Array " "") + (org-babel-haxe-var-to-haxe (cdr pair)))) + (org-babel--get-vars params))) + +(defun org-babel-haxe-var-to-haxe (var) + "Convert an elisp value to a haxe variable. +Convert an elisp value, VAR, into a string of haxe source code +specifying a variable of the same value." + (cond ((and (sequencep var) + (not (stringp var))) + (concat "[" (mapconcat #'org-babel-haxe-var-to-haxe var ", ") "]")) + ((equal var 'hline) + org-babel-haxe-hline-to) + (t + (format "%S" (if (stringp var) (substring-no-properties var) var))))) + +(defun org-babel-haxe-table-or-string (results) + "Convert RESULTS into an appropriate elisp value. +If the results look like a list or vector, then convert them into an +Emacs-lisp table, otherwise return the results as a string." + (let ((res (org-babel-script-escape results))) + ;; (mapcar (lambda (el) (message "el %s %s" el (eq 'null el))) res) + (if (listp res) + (mapcar (lambda (el) (if (eq 'null el) + org-babel-haxe-null-to + el)) + res) + res))) + +(defun org-babel-haxe-evaluate + (cmd target result-type result-params tmp-file) + "Evaluate using an external haxe process. +CMD the command to execute. + +TARGET the platform the haxe compiler should target. + +If RESULT-TYPE equals 'output then return standard output as a +string. If RESULT-TYPE equals 'value then return the value +returned by the source block, as elisp. + +RESULT-PARAMS input params used to format the reponse. + +TMP-FILE filename of the tempfile to store the returned value in +for 'value RESULT-TYPE. Not used for 'output RESULT-TYPE." + (let ((raw (cond ((eq result-type 'output) + (org-babel-eval cmd "")) + (t + (org-babel-eval cmd "") + (org-babel-eval-read-file tmp-file))))) + (if (and + (or (string= target "neko") + (string= target "hashlink")) + (eq result-type 'output)) + (setq raw (substring raw 0 -1))) ; neko and hashlink runtimes add a trailing endline + (org-babel-result-cond result-params + raw + (org-babel-haxe-table-or-string raw)))) + +(provide 'ob-haxe) + +;;; ob-haxe.el ends here diff --git a/testing/examples/ob-haxe-test.org b/testing/examples/ob-haxe-test.org new file mode 100644 index 000000000..ba9119d58 --- /dev/null +++ b/testing/examples/ob-haxe-test.org @@ -0,0 +1,247 @@ +#+Title: a collection of examples for ob-haxe tests +#+OPTIONS: ^:nil +* Simple + :PROPERTIES: + :ID: 966875e9-d10e-406c-9211-449555e3d3b2 + :END: +#+name: simple +#+begin_src haxe :results output silent + Sys.print(42); +#+end_src + +#+name: simple_with_main +#+begin_src haxe :results output silent + static function main() { + Sys.print(42); + } +#+end_src + +#+name: simple_with_public_main_interp +#+begin_src haxe :results output silent + public static function main() { + Sys.print(42); + } +#+end_src + +#+name: simple_with_public_main_neko +#+begin_src haxe :target neko :results output silent + public static function main() { + Sys.print(42); + } +#+end_src + +#+name: simple_with_public_main_hashlink +#+begin_src haxe :target hashlink :results output silent + public static function main() { + Sys.print(42); + } +#+end_src + +#+name: simple_with_class +#+begin_src haxe :results output silent + class Simple { + public static function main() { + Sys.print(42); + } + } +#+end_src + +#+name: simple_with_class_and_package +#+begin_src haxe :results output silent + package pkg; + class Simple { + public static function main() { + Sys.print(42); + } + } +#+end_src + +#+name: simple_with_class_attr +#+begin_src haxe :results output silent :classname Simple + public static function main() { + Sys.print(42); + } +#+end_src + +#+name: simple_with_class_attr_with_package +#+begin_src haxe :results output silent :classname pkg.Simple + public static function main() { + Sys.print(42); + } +#+end_src + +* Variables + :PROPERTIES: + :ID: ecbe8740-e254-4c53-84b2-21a61bf1afb4 + :END: + +#+name: integer_var +#+begin_src haxe :var a=42 :results output silent + Sys.print(a); +#+end_src + +#+name: var_with_main +#+begin_src haxe :var a=42 :results output silent + public static function main() { + Sys.print(a); + } +#+end_src + +#+name: var_with_class +#+begin_src haxe :var a=42 :results output silent + class Main { + public static function main() { + Sys.print(a); + } + } +#+end_src + +#+name: var_with_class_and_package +#+begin_src haxe :var a=42 :results output silent + package pkg; + class Main { + public static function main() { + Sys.print(a); + } + } +#+end_src + +#+name: var_with_class_and_hanging_curlies +#+begin_src haxe :var a=42 :results output silent + class Main + { + public static function main() + { + Sys.print(a); + } + } +#+end_src + +#+name: two_vars +#+begin_src haxe :var a=21 b=2 :results output silent + Sys.print(a*b); +#+end_src + +#+name: string_var +#+begin_src haxe :var a="forty two" :results output silent + Sys.print('$a, len=${a.length}'); +#+end_src + +#+name: mulitline_string_var +#+begin_src haxe :var a="forty\ntwo" :results output silent + Sys.print('$a, len=${a.length}'); +#+end_src + +* Array + :PROPERTIES: + :ID: 1e93864d-385b-4901-9d12-b566fdb5b813 + :END: + +#+name: haxe_list +- forty +- two + +#+name: return_vector +#+begin_src haxe :results vector silent + return [[4], [2]]; +#+end_src + +#+name: read_return_list +#+begin_src haxe :var a=haxe_list :results silent + return [a[0][0], a[1][0]]; +#+end_src + +this is not an interesting test, but it demonstrates how to use +~:results output~ to write a neatly formatted list of strings which +can include spaces. + +#+name: read_output_list +#+begin_src haxe :var a=haxe_list :results output list raw silent + Sys.println('forty two'); + Sys.println('forty two'); +#+end_src + +* Matrix + :PROPERTIES: + :ID: a93bb906-eef8-4089-b490-64f266f5696c + :END: +#+name: haxe_matrix +| 2 | 1 | +| 4 | 2 | + +#+name: list_var +#+begin_src haxe :var a='("forty" "two") :results silent + return [a[0], a[1]]; +#+end_src + +#+name: vector_var +#+begin_src haxe :var a='["forty" "two"] :results silent + return [a[0], a[1]]; +#+end_src + +#+name: matrix_var +#+begin_src haxe :var a=haxe_matrix :results silent + return [[a[0][0], a[1][0]], // transpose + [a[0][1], a[1][1]]]; +#+end_src + +#+name: matrix_var_with_header +#+begin_src haxe :var a=haxe_matrix :results value table silent + return [["col1","col2"], + null, + [a[0][0], a[1][0]], // transpose + [a[0][1], a[1][1]]]; +#+end_src + +this is not an interesting test, but it demonstrates how to use +~:results output~ to write a table with header. + +#+name: output_table_with_header +#+begin_src haxe :var a=haxe_matrix :results output raw table silent + Sys.println("|col1|col2|"); + Sys.println("|-"); + for (ii in 0...a.length) { + for (jj in 0...a[0].length) { + Sys.print('|${a[ii][jj]}'); + } + Sys.println(""); + } +#+end_src + +* Inhomogeneous Table + :PROPERTIES: + :ID: 192cbb7d-9038-47ca-bab3-a0cbf44b487d + :END: + +#+name: haxe_table + | string | number | + |--------+--------| + | forty | 2 | + | two | 1 | + +#+name: inhomogeneous_table +#+begin_src haxe :var a=haxe_table :results silent + return [[a[0][0], a[0][1]*2], + [a[1][0], a[1][1]*2]]; +#+end_src + +* Library + :PROPERTIES: + :ID: 0b945cde-55a1-4723-8d78-5f69d98d09fa + :END: + +#+name: import_library +#+begin_src haxe :results output silent :imports haxe.crypto.Base64 haxe.io.Bytes + var encoded = Base64.encode(Bytes.ofString("42")); + var decoded = Base64.decode(encoded); + Sys.print('encoded=$encoded, decoded=$decoded'); +#+end_src + +#+name: import_library_inline +#+begin_src haxe :results output silent + import haxe.crypto.Base64; + import haxe.io.Bytes; + var encoded = Base64.encode(Bytes.ofString("42")); + var decoded = Base64.decode(encoded); + Sys.print('encoded=$encoded, decoded=$decoded'); +#+end_src diff --git a/testing/lisp/test-ob-haxe.el b/testing/lisp/test-ob-haxe.el new file mode 100644 index 000000000..b8c33c4b8 --- /dev/null +++ b/testing/lisp/test-ob-haxe.el @@ -0,0 +1,234 @@ +;;; test-ob-haxe.el --- tests for ob-haxe.el + +;; Copyright (c) 2020 Ian Martins +;; Authors: Ian Martins + +;; This file is not part of GNU Emacs. + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Code: +(org-test-for-executable "haxe") +(unless (featurep 'ob-haxe) + (signal 'missing-test-dependency "Support for haxe code blocks")) + +(ert-deftest ob-haxe/simple () + "Hello world program." + (if (executable-find org-babel-haxe-command) + (org-test-at-id "966875e9-d10e-406c-9211-449555e3d3b2" + (org-babel-next-src-block 1) + (should (string= "42" (org-babel-execute-src-block)))))) + +(ert-deftest ob-haxe/simple-with-main () + "Hello world program that defines a main function." + (if (executable-find org-babel-haxe-command) + (org-test-at-id "966875e9-d10e-406c-9211-449555e3d3b2" + (org-babel-next-src-block 2) + (should (string= "42" (org-babel-execute-src-block)))))) + +(ert-deftest ob-haxe/simple-with-public-main-interp () + "Hello world program that defines a public main function targeting interp." + (if (executable-find org-babel-haxe-command) + (org-test-at-id "966875e9-d10e-406c-9211-449555e3d3b2" + (org-babel-next-src-block 3) + (should (string= "42" (org-babel-execute-src-block)))))) + +(ert-deftest ob-haxe/simple-with-public-main-neko () + "Hello world program that defines a public main function targeting neko." + (if (executable-find org-babel-haxe-command) + (org-test-at-id "966875e9-d10e-406c-9211-449555e3d3b2" + (org-babel-next-src-block 4) + (should (string= "42" (org-babel-execute-src-block)))))) + +(ert-deftest ob-haxe/simple-with-public-main-hashlink () + "Hello world program that defines a public main function targeting hashlink." + (if (executable-find org-babel-haxe-command) + (org-test-at-id "966875e9-d10e-406c-9211-449555e3d3b2" + (org-babel-next-src-block 5) + (should (string= "42" (org-babel-execute-src-block)))))) + +(ert-deftest ob-haxe/simple-with-class () + "Hello world program that defines a class." + (if (executable-find org-babel-haxe-command) + (org-test-at-id "966875e9-d10e-406c-9211-449555e3d3b2" + (org-babel-next-src-block 6) + (should (string= "42" (org-babel-execute-src-block)))))) + +(ert-deftest ob-haxe/simple-with-class-and-package () + "Hello world program that defines a class and package." + (if (executable-find org-babel-haxe-command) + (org-test-at-id "966875e9-d10e-406c-9211-449555e3d3b2" + (org-babel-next-src-block 7) + (should (string= "42" (org-babel-execute-src-block)))))) + +(ert-deftest ob-haxe/simple-with-class-attr () + "Hello world program with class header attribute." + (if (executable-find org-babel-haxe-command) + (org-test-at-id "966875e9-d10e-406c-9211-449555e3d3b2" + (org-babel-next-src-block 8) + (should (string= "42" (org-babel-execute-src-block)))))) + +(ert-deftest ob-haxe/simple-with-class-attr-with-package () + "Hello world program with class attr with package." + (if (executable-find org-babel-haxe-command) + (org-test-at-id "966875e9-d10e-406c-9211-449555e3d3b2" + (org-babel-next-src-block 9) + (should (string= "42" (org-babel-execute-src-block)))))) + + +(ert-deftest ob-haxe/integer-var () + "Read and write an integer variable." + (if (executable-find org-babel-haxe-command) + (org-test-at-id "ecbe8740-e254-4c53-84b2-21a61bf1afb4" + (org-babel-next-src-block 1) + (should (string= "42" (org-babel-execute-src-block)))))) + +(ert-deftest ob-haxe/var-with-main () + "Read and write an integer variable, with main function provided." + (if (executable-find org-babel-haxe-command) + (org-test-at-id "ecbe8740-e254-4c53-84b2-21a61bf1afb4" + (org-babel-next-src-block 2) + (should (string= "42" (org-babel-execute-src-block)))))) + +(ert-deftest ob-haxe/var-with-class () + "Read and write an integer variable, with class provided." + (if (executable-find org-babel-haxe-command) + (org-test-at-id "ecbe8740-e254-4c53-84b2-21a61bf1afb4" + (org-babel-next-src-block 3) + (should (string= "42" (org-babel-execute-src-block)))))) + +(ert-deftest ob-haxe/var-with-class-and-package () + "Read and write an integer variable, with class and package provided." + (if (executable-find org-babel-haxe-command) + (org-test-at-id "ecbe8740-e254-4c53-84b2-21a61bf1afb4" + (org-babel-next-src-block 4) + (should (string= "42" (org-babel-execute-src-block)))))) + +(ert-deftest ob-haxe/var-with-class-and-hanging-curlies () + "Read and write an integer variable, with class with hanging curlies." + (if (executable-find org-babel-haxe-command) + (org-test-at-id "ecbe8740-e254-4c53-84b2-21a61bf1afb4" + (org-babel-next-src-block 5) + (should (string= "42" (org-babel-execute-src-block)))))) + +(ert-deftest ob-haxe/two-vars () + "Read two integer variables, combine and write them." + (if (executable-find org-babel-haxe-command) + (org-test-at-id "ecbe8740-e254-4c53-84b2-21a61bf1afb4" + (org-babel-next-src-block 6) + (should (string= "42" (org-babel-execute-src-block)))))) + +(ert-deftest ob-haxe/string-var () + "Read and write a string variable." + (if (executable-find org-babel-haxe-command) + (org-test-at-id "ecbe8740-e254-4c53-84b2-21a61bf1afb4" + (org-babel-next-src-block 7) + (should (string= "forty two, len=9" (org-babel-execute-src-block)))))) + +(ert-deftest ob-haxe/multiline-string-var () + "Read and write a multi-line string variable." + (if (executable-find org-babel-haxe-command) + (org-test-at-id "ecbe8740-e254-4c53-84b2-21a61bf1afb4" + (org-babel-next-src-block 8) + (should (string= "forty\ntwo, len=9" (org-babel-execute-src-block)))))) + + +(ert-deftest ob-haxe/return-vector () + "Return a vector." + (if (executable-find org-babel-haxe-command) + (org-test-at-id "1e93864d-385b-4901-9d12-b566fdb5b813" + (org-babel-next-src-block 1) + (should (equal '((4) (2)) (org-babel-execute-src-block)))))) + +(ert-deftest ob-haxe/read-return-list () + "Return a vector." + (if (executable-find org-babel-haxe-command) + (org-test-at-id "1e93864d-385b-4901-9d12-b566fdb5b813" + (org-babel-next-src-block 2) + (should (equal '("forty" "two") (org-babel-execute-src-block)))))) + +(ert-deftest ob-haxe/read-output-list () + "Return a vector." + (if (executable-find org-babel-haxe-command) + (org-test-at-id "1e93864d-385b-4901-9d12-b566fdb5b813" + (org-babel-next-src-block 3) + (should (equal "forty two\nforty two\n" (org-babel-execute-src-block)))))) + + +(ert-deftest ob-haxe/list-var () + "Read and write a list variable." + (if (executable-find org-babel-haxe-command) + (org-test-at-id "a93bb906-eef8-4089-b490-64f266f5696c" + (org-babel-next-src-block 1) + (should (equal '("forty" "two") (org-babel-execute-src-block)))))) + +(ert-deftest ob-haxe/vector-var () + "Read and write a vector variable." + (if (executable-find org-babel-haxe-command) + (org-test-at-id "a93bb906-eef8-4089-b490-64f266f5696c" + (org-babel-next-src-block 2) + (should (equal '("forty" "two") (org-babel-execute-src-block)))))) + +(ert-deftest ob-haxe/matrix-var () + "Read and write matrix variable." + (if (executable-find org-babel-haxe-command) + (org-test-at-id "a93bb906-eef8-4089-b490-64f266f5696c" + (org-babel-next-src-block 3) + (should (equal '((2 4) (1 2)) (org-babel-execute-src-block)))))) + +(ert-deftest ob-haxe/matrix-var-with-header () + "Read matrix variable and write it with header." + (if (executable-find org-babel-haxe-command) + (org-test-at-id "a93bb906-eef8-4089-b490-64f266f5696c" + (org-babel-next-src-block 4) + (should (equal '(("col1" "col2") hline (2 4) (1 2)) (org-babel-execute-src-block)))))) + +(ert-deftest ob-haxe/output-table-with-header () + "Write a table that includes a header." + (if (executable-find org-babel-haxe-command) + (org-test-at-id "a93bb906-eef8-4089-b490-64f266f5696c" + (org-babel-next-src-block 5) + (should (equal "|col1|col2|\n|-\n|2|1\n|4|2\n" (org-babel-execute-src-block)))))) + + +(ert-deftest ob-haxe/inhomogeneous_table () + "Read and write an inhomogeneous table." + (if (executable-find org-babel-haxe-command) + (org-test-at-id "192cbb7d-9038-47ca-bab3-a0cbf44b487d" + (org-babel-next-src-block 1) + (should (equal + '(("forty" 4) ("two" 2)) + (org-babel-execute-src-block)))))) + + +(ert-deftest ob-haxe/import_library () + "Import a standard haxe library." + (if (executable-find org-babel-haxe-command) + (org-test-at-id "0b945cde-55a1-4723-8d78-5f69d98d09fa" + (org-babel-next-src-block 1) + (should (string= + "encoded=NDI=, decoded=42" + (org-babel-execute-src-block)))))) + +(ert-deftest ob-haxe/import_library_inline () + "Import a standard haxe library." + (if (executable-find org-babel-haxe-command) + (org-test-at-id "0b945cde-55a1-4723-8d78-5f69d98d09fa" + (org-babel-next-src-block 2) + (should (string= + "encoded=NDI=, decoded=42" + (org-babel-execute-src-block)))))) + + +;;; test-ob-haxe.el ends here