forked from nikclayton/ob-sql-mode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathob-sql-mode-test.el
175 lines (148 loc) · 4.77 KB
/
ob-sql-mode-test.el
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
;;; ob-sql-mode-test.el --- Tests for ob-sql-mode.el -*- lexical-binding: t -*-
;; Create the test database with
;;
;; sqlite3 test.db < test.sql
;;
;; Run the test with
;;
;; ls *.el | entr emacs -batch -l ert -l ob-sql-mode-test.el -f ert-run-tests-batch-and-exit
;;; Code:
(load-file "./ob-sql-mode.el")
(defvar ob-sql-mode-test-database-path
"test.db"
"Path to the test database.")
(defun results-block-contents (&optional position)
"Return the contents of the *only* results block in the buffer.
Assume the source block is at POSITION if non-nil."
(interactive)
(save-excursion
(progn
(if position
(goto-char position)
(goto-char 0)
(org-babel-next-src-block))
(goto-char (org-babel-where-is-src-block-result))
(let ((result (org-babel-read-result)))
result))))
(defmacro with-buffer-contents (s &rest forms)
"Create a temporary buffer with contents S and execute FORMS."
`(save-excursion
(with-temp-buffer
(progn
(goto-char 0)
(insert ,s)
(goto-char 0)
,@forms))))
(defun setup (body)
"Initialise the test environment and run BODY."
(let ((old-sql-get-login (symbol-function 'sql-get-login)))
(unwind-protect
(progn
(let ((org-babel-sql-mode-start-interpreter-prompt
(lambda (&rest _) t))
(org-confirm-babel-evaluate
(lambda (lang body)
(not (string= lang "sql-mode"))))
(sql-database ob-sql-mode-test-database-path))
(defalias 'sql-get-login 'ignore)
(funcall body)))
(defalias 'sql-get-login 'old-sql-get-login))))
(defun simple-test (sql want)
"Execute SQL in a `sql-mode' Babel block comparing the result against WANT."
(setup
(lambda ()
(let ((buffer-contents (format "Simple select.
#+BEGIN_SRC sql-mode :product sqlite
%s
#+END_SRC" sql)))
(with-buffer-contents buffer-contents
(org-babel-next-src-block)
(org-ctrl-c-ctrl-c)
(should (string= want (results-block-contents))))))))
(ert-deftest test-simple-select ()
"Simple select from no table."
(simple-test "SELECT 1, 2, 3;" "1|2|3"))
(ert-deftest test-select-sqlite-master ()
"Selecting from sqlite_master."
(simple-test
"SELECT * FROM sqlite_master;"
"table|tbl1|tbl1|2|CREATE TABLE tbl1(one varchar(10), two smallint)"))
(ert-deftest test-select-varchar-column ()
"Selecting two rows from a varchar column."
(simple-test
"SELECT one FROM tbl1;"
"hello
world"))
(ert-deftest test-select-smallint-column ()
"Selecting two rows from a smallint column."
(simple-test
"SELECT two FROM tbl1;"
"10
20"))
(ert-deftest test-select-multiple-columns ()
"Selecting two rows from multiple columns."
(simple-test
"SELECT one, two FROM tbl1;"
"hello|10
world|20"))
(ert-deftest test-select-with-comments ()
"Comments in various places."
(simple-test
"-- First line comment.
SELECT one, -- End of line comment.
-- In-query comment.
two
FROM
tbl1;"
"hello|10
world|20"))
(ert-deftest test-no-session()
"Two blocks that do not share a session should not affect one another."
(setup
(lambda ()
(with-buffer-contents "SQL Content
First, verify that case_sensitive_like returns no results for this
query.
#+BEGIN_SRC sql-mode :product sqlite
PRAGMA case_sensitive_like = true;
SELECT two FROM tbl1 WHERE one LIKE 'HELLO';
#+END_SRC"
(org-babel-next-src-block)
(org-ctrl-c-ctrl-c)
(should (eq nil (results-block-contents))))
(with-buffer-contents "SQL Content
Now have two blocks. Evaluate them both. The first should not return
any results, but the second should, because they run in different
sessions, so the PRAGMA in the first should not affect the second.
#+BEGIN_SRC sql-mode :product sqlite
PRAGMA case_sensitive_like = true;
SELECT two FROM tbl1 WHERE one LIKE 'HELLO';
#+END_SRC
A different block in the same session should still be nil.
#+BEGIN_SRC sql-mode :product sqlite
SELECT two FROM tbl1 WHERE one LIKE 'HELLO';
#+END_SRC"
(org-babel-next-src-block)
(org-ctrl-c-ctrl-c)
(should (eq nil (results-block-contents)))
(org-babel-next-src-block)
(org-ctrl-c-ctrl-c)
(should (eq nil (results-block-contents (point)))))
(with-buffer-contents "SQL Content
The same two blocks, but put them in different sessions.
#+BEGIN_SRC sql-mode :product sqlite :session first
PRAGMA case_sensitive_like = true;
SELECT two FROM tbl1 WHERE one LIKE 'HELLO';
#+END_SRC
A different block in a different session should return 10.
#+BEGIN_SRC sql-mode :product sqlite :session second
SELECT two FROM tbl1 WHERE one LIKE 'HELLO';
#+END_SRC"
(org-babel-next-src-block)
(org-ctrl-c-ctrl-c)
(should (eq nil (results-block-contents)))
(org-babel-next-src-block)
(org-ctrl-c-ctrl-c)
(should (eq 10 (results-block-contents (point))))))))
(provide 'ob-sql-mode-test)
;;; ob-sql-mode-test.el ends here