org-element: Tiny refactoring
[org-mode.git] / testing / lisp / test-org-table.el
blobe619cbc3d8d0adf9a4a3382c29d5fec3fa9ac386
1 ;;; test-org-table.el --- tests for org-table.el
3 ;; Copyright (c) David Maus
4 ;; Authors: David Maus, Michael Brand
6 ;; This file is not part of GNU Emacs.
8 ;; This program is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation, either version 3 of the License, or
11 ;; (at your option) any later version.
13 ;; This program is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
21 ;;;; Comments:
23 ;; Template test file for Org-mode tests. Many tests are also a howto
24 ;; example collection as a user documentation, more or less all those
25 ;; using `org-test-table-target-expect'. See also the doc string of
26 ;; `org-test-table-target-expect'.
28 ;;; Code:
30 (require 'org-table) ; `org-table-make-reference'
32 (ert-deftest test-org-table/simple-formula/no-grouping/no-title-row ()
33 "Simple sum without grouping rows, without title row."
34 (org-test-table-target-expect
36 | 2 |
37 | 4 |
38 | 8 |
39 | replace |
42 | 2 |
43 | 4 |
44 | 8 |
45 | 14 |
48 ;; Calc formula
49 "#+TBLFM: @>$1 = vsum(@<..@>>)"
50 ;; Lisp formula
51 "#+TBLFM: @>$1 = '(+ @<..@>>); N"))
53 (ert-deftest test-org-table/simple-formula/no-grouping/with-title-row ()
54 "Simple sum without grouping rows, with title row."
55 (org-test-table-target-expect
57 | foo |
58 |---------|
59 | 2 |
60 | 4 |
61 | 8 |
62 | replace |
65 | foo |
66 |-----|
67 | 2 |
68 | 4 |
69 | 8 |
70 | 14 |
73 ;; Calc formula
74 "#+TBLFM: @>$1 = vsum(@I..@>>)"
75 ;; Lisp formula
76 "#+TBLFM: @>$1 = '(+ @I..@>>); N"))
78 (ert-deftest test-org-table/simple-formula/with-grouping/no-title-row ()
79 "Simple sum with grouping rows, how not to do."
80 ;; The first example has a problem, see the second example in this
81 ;; ert-deftest.
82 (org-test-table-target-expect
84 | 2 |
85 | 4 |
86 | 8 |
87 |---------|
88 | replace |
91 | 2 |
92 | 4 |
93 | 8 |
94 |----|
95 | 14 |
98 ;; Calc formula
99 "#+TBLFM: $1 = vsum(@<..@>>)"
100 ;; Lisp formula
101 "#+TBLFM: $1 = '(+ @<..@>>); N")
103 ;; The problem is that the first three rows with the summands are
104 ;; considered the header and therefore column formulas are not
105 ;; applied on them as shown below. Also export behaves unexpected.
106 ;; See next ert-deftest how to group rows right.
107 (org-test-table-target-expect
109 | 2 | replace |
110 | 4 | replace |
111 | 8 | replace |
112 |---------+---------|
113 | replace | replace |
116 | 2 | replace |
117 | 4 | replace |
118 | 8 | replace |
119 |----+---------|
120 | 14 | 28 |
123 ;; Calc formula
124 "#+TBLFM: @>$1 = vsum(@<..@>>) :: $2 = 2 * $1"
125 ;; Lisp formula
126 "#+TBLFM: @>$1 = '(+ @<..@>>); N :: $2 = '(* 2 $1); N"))
128 (ert-deftest test-org-table/simple-formula/with-grouping/with-title-row ()
129 "Simple sum with grouping rows, how to do it right."
130 ;; Always add a top row with the column names separated by hline to
131 ;; get the desired header when you want to group rows.
132 (org-test-table-target-expect
134 | foo | bar |
135 |---------+---------|
136 | 2 | replace |
137 | 4 | replace |
138 | 8 | replace |
139 |---------+---------|
140 | replace | replace |
143 | foo | bar |
144 |-----+-----|
145 | 2 | 4 |
146 | 4 | 8 |
147 | 8 | 16 |
148 |-----+-----|
149 | 14 | 28 |
152 ;; Calc formula
153 "#+TBLFM: @>$1 = vsum(@I..@>>) :: $2 = 2 * $1"
154 ;; Lisp formula
155 "#+TBLFM: @>$1 = '(+ @I..@>>); N :: $2 = '(* 2 $1); N"))
157 (ert-deftest test-org-table/align ()
158 "Align columns within Org buffer, depends on `org-table-number-regexp'."
159 (org-test-table-target-expect "
160 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
161 | ab | 12 | 12.2 | 2.4e-08 | 2x10^12 | 4.034+-0.02 | 2.7(10) | >3.5 |
162 | ab | ab | ab | ab | ab | ab | ab | ab |
164 (org-test-table-target-expect "
165 | 0 | 0 | 0 | 0 | 0 | 0 |
166 | <-0x0ab.cf | >-36#0vw.yz | nan | uinf | -inf | inf |
167 | ab | ab | ab | ab | ab | ab |
170 (defconst references/target-normal "
171 | 0 | 1 | replace | replace | replace | replace | replace | replace |
172 | z | 1 | replace | replace | replace | replace | replace | replace |
173 | | 1 | replace | replace | replace | replace | replace | replace |
174 | | | replace | replace | replace | replace | replace | replace |
176 "Normal numbers and non-numbers for Lisp and Calc formula.")
178 (defconst references/target-special "
179 | nan | 1 | replace | replace | replace | replace | replace | replace |
180 | uinf | 1 | replace | replace | replace | replace | replace | replace |
181 | -inf | 1 | replace | replace | replace | replace | replace | replace |
182 | inf | 1 | replace | replace | replace | replace | replace | replace |
184 "Special numbers for Calc formula.")
186 (ert-deftest test-org-table/references/mode-string-EL ()
187 "Basic: Assign field reference, sum of field references, sum
188 and len of simple range reference (no row) and complex range
189 reference (with row). Mode string EL."
190 ;; Empty fields are kept during parsing field but lost as list
191 ;; elements within Lisp formula syntactically when used literally
192 ;; and not enclosed with " within fields, see last columns with len.
193 (org-test-table-target-expect
194 references/target-normal
195 ;; All the #ERROR show that for Lisp calculations N has to be used.
197 | 0 | 1 | 0 | 1 | 1 | 1 | 2 | 2 |
198 | z | 1 | z | #ERROR | #ERROR | #ERROR | 2 | 2 |
199 | | 1 | | 1 | 1 | 1 | 1 | 1 |
200 | | | | 0 | 0 | 0 | 0 | 0 |
202 1 (concat
203 "#+TBLFM: $3 = '(identity \"$1\"); EL :: $4 = '(+ $1 $2); EL :: "
204 "$5 = '(+ $1..$2); EL :: $6 = '(+ @0$1..@0$2); EL :: "
205 "$7 = '(length '($1..$2)); EL :: $8 = '(length '(@0$1..@0$2)); EL"))
207 ;; Empty fields are kept during parsing field _and_ as list elements
208 ;; within Lisp formula syntactically even when used literally when
209 ;; enclosed with " within fields, see last columns with len.
210 (org-test-table-target-expect
212 | \"0\" | \"1\" | repl | repl | repl | repl | repl | repl |
213 | \"z\" | \"1\" | repl | repl | repl | repl | repl | repl |
214 | \"\" | \"1\" | repl | repl | repl | repl | repl | repl |
215 | \"\" | \"\" | repl | repl | repl | repl | repl | repl |
218 | \"0\" | \"1\" | \"0\" | 1 | #ERROR | #ERROR | 2 | 2 |
219 | \"z\" | \"1\" | \"z\" | 1 | #ERROR | #ERROR | 2 | 2 |
220 | \"\" | \"1\" | \"\" | 1 | #ERROR | #ERROR | 2 | 2 |
221 | \"\" | \"\" | \"\" | 0 | #ERROR | #ERROR | 2 | 2 |
223 1 (concat
224 "#+TBLFM: $3 = '(concat \"\\\"\" $1 \"\\\"\"); EL :: "
225 "$4 = '(+ (string-to-number $1) (string-to-number $2)); EL :: "
226 "$5 = '(+ $1..$2); EL :: $6 = '(+ @0$1..@0$2); EL :: "
227 "$7 = '(length '($1..$2)); EL :: $8 = '(length '(@0$1..@0$2)); EL")))
229 (ert-deftest test-org-table/references/mode-string-E ()
230 "Basic: Assign field reference, sum of field references, sum
231 and len of simple range reference (no row) and complex range
232 reference (with row). Mode string E."
233 (let ((lisp
234 (concat
235 "#+TBLFM: $3 = '(identity $1); E :: $4 = '(+ $1 $2); E :: "
236 "$5 = '(+ $1..$2); E :: $6 = '(+ @0$1..@0$2); E :: "
237 "$7 = '(length '($1..$2)); E :: $8 = '(length '(@0$1..@0$2)); E"))
238 (calc
239 (concat
240 "#+TBLFM: $3 = $1; E :: $4 = $1 + $2; E :: "
241 "$5 = vsum($1..$2); E :: $6 = vsum(@0$1..@0$2); E :: "
242 "$7 = vlen($1..$2); E :: $8 = vlen(@0$1..@0$2); E")))
243 (org-test-table-target-expect
244 references/target-normal
245 ;; All the #ERROR show that for Lisp calculations N has to be used.
247 | 0 | 1 | 0 | #ERROR | #ERROR | #ERROR | 2 | 2 |
248 | z | 1 | z | #ERROR | #ERROR | #ERROR | 2 | 2 |
249 | | 1 | | #ERROR | #ERROR | #ERROR | 2 | 2 |
250 | | | | #ERROR | #ERROR | #ERROR | 2 | 2 |
252 1 lisp)
253 (org-test-table-target-expect
254 references/target-normal
256 | 0 | 1 | 0 | 1 | 1 | 1 | 2 | 2 |
257 | z | 1 | z | z + 1 | z + 1 | z + 1 | 2 | 2 |
258 | | 1 | nan | nan | nan | nan | 2 | 2 |
259 | | | nan | nan | nan | nan | 2 | 2 |
261 1 calc)
262 (org-test-table-target-expect
263 references/target-special
265 | nan | 1 | nan | nan | nan | nan | 2 | 2 |
266 | uinf | 1 | uinf | uinf | uinf | uinf | 2 | 2 |
267 | -inf | 1 | -inf | -inf | -inf | -inf | 2 | 2 |
268 | inf | 1 | inf | inf | inf | inf | 2 | 2 |
270 1 calc)))
272 (ert-deftest test-org-table/references/mode-string-EN ()
273 "Basic: Assign field reference, sum of field references, sum
274 and len of simple range reference (no row) and complex range
275 reference (with row). Mode string EN."
276 (let ((lisp (concat
277 "#+TBLFM: $3 = '(identity $1); EN :: $4 = '(+ $1 $2); EN :: "
278 "$5 = '(+ $1..$2); EN :: $6 = '(+ @0$1..@0$2); EN :: "
279 "$7 = '(length '($1..$2)); EN :: "
280 "$8 = '(length '(@0$1..@0$2)); EN"))
281 (calc (concat
282 "#+TBLFM: $3 = $1; EN :: $4 = $1 + $2; EN :: "
283 "$5 = vsum($1..$2); EN :: $6 = vsum(@0$1..@0$2); EN :: "
284 "$7 = vlen($1..$2); EN :: $8 = vlen(@0$1..@0$2); EN")))
285 (org-test-table-target-expect
286 references/target-normal
288 | 0 | 1 | 0 | 1 | 1 | 1 | 2 | 2 |
289 | z | 1 | 0 | 1 | 1 | 1 | 2 | 2 |
290 | | 1 | 0 | 1 | 1 | 1 | 2 | 2 |
291 | | | 0 | 0 | 0 | 0 | 2 | 2 |
293 1 lisp calc)
294 (org-test-table-target-expect
295 references/target-special
297 | nan | 1 | 0 | 1 | 1 | 1 | 2 | 2 |
298 | uinf | 1 | 0 | 1 | 1 | 1 | 2 | 2 |
299 | -inf | 1 | 0 | 1 | 1 | 1 | 2 | 2 |
300 | inf | 1 | 0 | 1 | 1 | 1 | 2 | 2 |
302 1 calc)))
304 (ert-deftest test-org-table/references/mode-string-L ()
305 "Basic: Assign field reference, sum of field references, sum
306 and len of simple range reference (no row) and complex range
307 reference (with row). Mode string L."
308 (org-test-table-target-expect
309 references/target-normal
310 ;; All the #ERROR show that for Lisp calculations N has to be used.
312 | 0 | 1 | 0 | 1 | 1 | 1 | 2 | 2 |
313 | z | 1 | z | #ERROR | #ERROR | #ERROR | 2 | 2 |
314 | | 1 | | 1 | 1 | 1 | 1 | 1 |
315 | | | | 0 | 0 | 0 | 0 | 0 |
317 1 (concat
318 "#+TBLFM: $3 = '(identity \"$1\"); L :: $4 = '(+ $1 $2); L :: "
319 "$5 = '(+ $1..$2); L :: $6 = '(+ @0$1..@0$2); L :: "
320 "$7 = '(length '($1..$2)); L :: $8 = '(length '(@0$1..@0$2)); L")))
322 (ert-deftest test-org-table/references/mode-string-none ()
323 "Basic: Assign field reference, sum of field references, sum
324 and len of simple range reference (no row) and complex range
325 reference (with row). No mode string."
326 (let ((lisp (concat
327 "#+TBLFM: $3 = '(identity $1) :: $4 = '(+ $1 $2) :: "
328 "$5 = '(+ $1..$2) :: $6 = '(+ @0$1..@0$2) :: "
329 "$7 = '(length '($1..$2)) :: $8 = '(length '(@0$1..@0$2))"))
330 (calc (concat
331 "#+TBLFM: $3 = $1 :: $4 = $1 + $2 :: "
332 "$5 = vsum($1..$2) :: $6 = vsum(@0$1..@0$2) :: "
333 "$7 = vlen($1..$2) :: $8 = vlen(@0$1..@0$2)")))
334 (org-test-table-target-expect
335 references/target-normal
336 ;; All the #ERROR show that for Lisp calculations N has to be used.
338 | 0 | 1 | 0 | #ERROR | #ERROR | #ERROR | 2 | 2 |
339 | z | 1 | z | #ERROR | #ERROR | #ERROR | 2 | 2 |
340 | | 1 | | #ERROR | #ERROR | #ERROR | 1 | 1 |
341 | | | | #ERROR | 0 | 0 | 0 | 0 |
343 1 lisp)
344 (org-test-table-target-expect
345 references/target-normal
347 | 0 | 1 | 0 | 1 | 1 | 1 | 2 | 2 |
348 | z | 1 | z | z + 1 | z + 1 | z + 1 | 2 | 2 |
349 | | 1 | 0 | 1 | 1 | 1 | 1 | 1 |
350 | | | 0 | 0 | 0 | 0 | 0 | 0 |
352 1 calc)
353 (org-test-table-target-expect
354 references/target-special
356 | nan | 1 | nan | nan | nan | nan | 2 | 2 |
357 | uinf | 1 | uinf | uinf | uinf | uinf | 2 | 2 |
358 | -inf | 1 | -inf | -inf | -inf | -inf | 2 | 2 |
359 | inf | 1 | inf | inf | inf | inf | 2 | 2 |
361 1 calc)))
363 (ert-deftest test-org-table/references/mode-string-N ()
364 "Basic: Assign field reference, sum of field references, sum
365 and len of simple range reference (no row) and complex range
366 reference (with row). Mode string N."
367 (let ((lisp
368 (concat
369 "#+TBLFM: $3 = '(identity $1); N :: $4 = '(+ $1 $2); N :: "
370 "$5 = '(+ $1..$2); N :: $6 = '(+ @0$1..@0$2); N :: "
371 "$7 = '(length '($1..$2)); N :: $8 = '(length '(@0$1..@0$2)); N"))
372 (calc
373 (concat
374 "#+TBLFM: $3 = $1; N :: $4 = $1 + $2; N :: "
375 "$5 = vsum($1..$2); N :: $6 = vsum(@0$1..@0$2); N :: "
376 "$7 = vlen($1..$2); N :: $8 = vlen(@0$1..@0$2); N")))
377 (org-test-table-target-expect
378 references/target-normal
380 | 0 | 1 | 0 | 1 | 1 | 1 | 2 | 2 |
381 | z | 1 | 0 | 1 | 1 | 1 | 2 | 2 |
382 | | 1 | 0 | 1 | 1 | 1 | 1 | 1 |
383 | | | 0 | 0 | 0 | 0 | 0 | 0 |
385 1 lisp calc)
386 (org-test-table-target-expect
387 references/target-special
389 | nan | 1 | 0 | 1 | 1 | 1 | 2 | 2 |
390 | uinf | 1 | 0 | 1 | 1 | 1 | 2 | 2 |
391 | -inf | 1 | 0 | 1 | 1 | 1 | 2 | 2 |
392 | inf | 1 | 0 | 1 | 1 | 1 | 2 | 2 |
394 1 calc)))
396 (ert-deftest test-org-table/lisp-return-value ()
397 "Basic: Return value of Lisp formulas."
398 (org-test-table-target-expect
400 | | nil | (list) | '() |
401 |-------------------------+-------------+--------+-----|
402 | type-of, no L | replace (r) | r | r |
403 | type-of identity, no L | r | r | r |
404 | identity, no L | r | r | r |
405 |-------------------------+-------------+--------+-----|
406 | type-of \"@1\" | r | r | r |
407 | type-of (identity \"@1\") | r | r | r |
408 | identity \"@1\" | r | r | r |
409 |-------------------------+-------------+--------+-----|
410 | type-of @1 | r | r | r |
411 | type-of (identity @1) | r | r | r |
412 | identity @1 | r | r | r |
415 | | nil | (list) | '() |
416 |-------------------------+--------+--------+--------|
417 | type-of, no L | string | string | string |
418 | type-of identity, no L | string | string | string |
419 | identity, no L | nil | (list) | '() |
420 |-------------------------+--------+--------+--------|
421 | type-of \"@1\" | string | string | string |
422 | type-of (identity \"@1\") | string | string | string |
423 | identity \"@1\" | nil | (list) | '() |
424 |-------------------------+--------+--------+--------|
425 | type-of @1 | symbol | symbol | symbol |
426 | type-of (identity @1) | symbol | symbol | symbol |
427 | identity @1 | nil | nil | nil |
429 1 (concat "#+TBLFM: @2$<<..@2$> = '(type-of @1) :: "
430 "@3$<<..@3$> = '(type-of (identity @1)) :: "
431 "@4$<<..@4$> = '(identity @1) :: @5$<<..@>$> = '(@0$1); L")))
433 (ert-deftest test-org-table/compare ()
434 "Basic: Compare field references in Calc."
435 (org-test-table-target-expect
437 | | 0 | z | | nan | uinf | -inf | inf |
438 |------+------+------+------+------+------+------+------|
439 | 0 | repl | repl | repl | repl | repl | repl | repl |
440 | z | repl | repl | repl | repl | repl | repl | repl |
441 | | repl | repl | repl | repl | repl | repl | repl |
442 | nan | repl | repl | repl | repl | repl | repl | repl |
443 | uinf | repl | repl | repl | repl | repl | repl | repl |
444 | -inf | repl | repl | repl | repl | repl | repl | repl |
445 | inf | repl | repl | repl | repl | repl | repl | repl |
448 | | 0 | z | | nan | uinf | -inf | inf |
449 |------+---+---+---+-----+------+------+-----|
450 | 0 | x | | | | | | |
451 | z | | x | | | | | |
452 | | | | x | | | | |
453 | nan | | | | x | | | |
454 | uinf | | | | | x | | |
455 | -inf | | | | | | x | |
456 | inf | | | | | | | x |
459 ;; Compare field reference ($1) with field reference (@1)
460 "#+TBLFM: @<<$<<..@>$> = if(\"$1\" == \"@1\", x, string(\"\")); E"
461 ;; Compare field reference ($1) with absolute term
462 (concat "#+TBLFM: "
463 "$2 = if(\"$1\" == \"(0)\" , x, string(\"\")); E :: "
464 "$3 = if(\"$1\" == \"(z)\" , x, string(\"\")); E :: "
465 "$4 = if(\"$1\" == \"nan\" , x, string(\"\")); E :: "
466 "$5 = if(\"$1\" == \"(nan)\" , x, string(\"\")); E :: "
467 "$6 = if(\"$1\" == \"(uinf)\", x, string(\"\")); E :: "
468 "$7 = if(\"$1\" == \"(-inf)\", x, string(\"\")); E :: "
469 "$8 = if(\"$1\" == \"(inf)\" , x, string(\"\")); E"))
471 ;; Check field reference converted from an empty field: Despite this
472 ;; field reference will not end up in a result, Calc evaluates it.
473 ;; Make sure that also then there is no Calc error.
474 (org-test-table-target-expect
476 | 0 | replace |
477 | z | replace |
478 | | replace |
479 | nan | replace |
482 | 0 | 1 |
483 | z | z + 1 |
484 | | |
485 | nan | nan |
487 1 "#+TBLFM: $2 = if(\"$1\" == \"nan\", string(\"\"), $1 + 1); E"))
489 (ert-deftest test-org-table/empty-field ()
490 "Examples how to deal with empty fields."
491 ;; Test if one field is empty, else do a calculation
492 (org-test-table-target-expect
494 | -1 | replace |
495 | 0 | replace |
496 | | replace |
499 | -1 | 0 |
500 | 0 | 1 |
501 | | |
504 ;; Calc formula
505 "#+TBLFM: $2 = if(\"$1\" == \"nan\", string(\"\"), $1 + 1); E"
506 ;; Lisp formula
507 "#+TBLFM: $2 = '(if (eq \"$1\" \"\") \"\" (1+ $1)); L")
509 ;; Test if several fields are empty, else do a calculation
510 (org-test-table-target-expect
512 | 1 | 2 | replace |
513 | 4 | | replace |
514 | | 8 | replace |
515 | | | replace |
518 | 1 | 2 | 3 |
519 | 4 | | |
520 | | 8 | |
521 | | | |
524 ;; Calc formula
525 (concat "#+TBLFM: $3 = if(\"$1\" == \"nan\" || \"$2\" == \"nan\", "
526 "string(\"\"), $1 + $2); E")
527 ;; Lisp formula
528 (concat "#+TBLFM: $3 = '(if (or (eq \"$1\" \"\") (eq \"$2\" \"\")) "
529 "\"\" (+ $1 $2)); L"))
531 ;; $2: Use $1 + 0.5 if $1 available, else only reformat $2 if $2 available
532 (org-test-table-target-expect
534 | 1.5 | 0 |
535 | 3.5 | |
536 | | 5 |
537 | | |
540 | 1.5 | 2.0 |
541 | 3.5 | 4.0 |
542 | | 5.0 |
543 | | |
546 ;; Calc formula
547 (concat "#+TBLFM: $2 = if(\"$1\" == \"nan\", "
548 "if(\"$2\" == \"nan\", string(\"\"), $2 +.0), $1 + 0.5); E f-1")
549 ;; Lisp formula not implemented yet
552 ;; Empty fields in simple and complex range reference
553 (org-test-table-target-expect
555 | | | | | repl | repl | repl | repl | repl | repl |
556 | | | 5 | 7 | repl | repl | repl | repl | repl | repl |
557 | 1 | 3 | 5 | 7 | repl | repl | repl | repl | repl | repl |
560 | | | | | | | | | 0 | 0 |
561 | | | 5 | 7 | | | 6 | 6 | 3 | 3 |
562 | 1 | 3 | 5 | 7 | 4 | 4 | 4 | 4 | 4 | 4 |
565 ;; Calc formula
566 (concat
567 "#+TBLFM: "
568 "$5 = if(typeof(vmean($1..$4)) == 12, "
569 "string(\"\"), vmean($1..$4)); E :: "
570 "$6 = if(typeof(vmean(@0$1..@0$4)) == 12, "
571 "string(\"\"), vmean(@0$1..@0$4)); E :: "
572 "$7 = if(\"$1..$4\" == \"[]\", string(\"\"), vmean($1..$4)) :: "
573 "$8 = if(\"@0$1..@0$4\" == \"[]\", string(\"\"), vmean(@0$1..@0$4)) :: "
574 "$9 = vmean($1..$4); EN :: "
575 "$10 = vmean(@0$1..@0$4); EN")
576 ;; Lisp formula
577 (concat
578 "#+TBLFM: "
579 "$5 = '(let ((l '($1..$4))) (if (member \"\" l) \"\" "
580 "(/ (apply '+ (mapcar 'string-to-number l)) (length l)))); E :: "
581 "$6 = '(let ((l '(@0$1..@0$4))) (if (member \"\" l) \"\" "
582 "(/ (apply '+ (mapcar 'string-to-number l)) (length l)))); E :: "
583 "$7 = '(let ((l '($1..$4))) "
584 "(if l (/ (apply '+ l) (length l)) \"\")); N :: "
585 "$8 = '(let ((l '(@0$1..@0$4))) "
586 "(if l (/ (apply '+ l) (length l)) \"\")); N :: "
587 "$9 = '(/ (+ $1..$4) (length '($1..$4))); EN :: "
588 "$10 = '(/ (+ @0$1..@0$4) (length '(@0$1..@0$4))); EN")
591 (ert-deftest test-org-table/copy-field ()
592 "Experiments on how to copy one field into another field.
593 See also `test-org-table/remote-reference-access'."
594 (let ((target "
595 | 0 | replace |
596 | a b | replace |
597 | c d | replace |
598 | | replace |
599 | 2012-12 | replace |
600 | [2012-12-31 Mon] | replace |
602 ;; Lisp formula to copy literally
603 (org-test-table-target-expect
604 target
606 | 0 | 0 |
607 | a b | a b |
608 | c d | c d |
609 | | |
610 | 2012-12 | 2012-12 |
611 | [2012-12-31 Mon] | [2012-12-31 Mon] |
613 1 "#+TBLFM: $2 = '(identity $1)")
615 ;; Calc formula to copy quite literally
616 (org-test-table-target-expect
617 target
619 | 0 | 0 |
620 | a b | a b |
621 | c d | c d |
622 | | |
623 | 2012-12 | 2012-12 |
624 | [2012-12-31 Mon] | <2012-12-31 Mon> |
626 1 (concat "#+TBLFM: $2 = if(\"$1\" == \"nan\", "
627 "string(\"\"), string(subvec(\"$1\", 2, vlen(\"$1\")))); E"))
629 ;; Calc formula simple
630 (org-test-table-target-expect
631 target
633 | 0 | 0 |
634 | a b | a b |
635 | c d | c d |
636 | | |
637 | 2012-12 | 2000 |
638 | [2012-12-31 Mon] | <2012-12-31 Mon> |
640 1 "#+TBLFM: $2 = if(\"$1\" == \"nan\", string(\"\"), $1); E")))
642 (ert-deftest test-org-table/sub-total ()
643 "Grouped rows with sub-total.
644 Begin range with \"@II\" to handle multiline header. Convert
645 integer to float with \"+.0\" for sub-total of items c1 and c2.
646 Sum empty fields as value zero but without ignoring them for
647 \"vlen\" with format specifier \"EN\". Format possibly empty
648 results with the Calc formatter \"f-1\" instead of the printf
649 formatter \"%.1f\"."
650 (org-test-table-target-expect
652 |-------+---------+---------|
653 | Item | Item | Sub- |
654 | name | value | total |
655 |-------+---------+---------|
656 | a1 | 4.1 | replace |
657 | a2 | 8.2 | replace |
658 | a3 | | replace |
659 |-------+---------+---------|
660 | b1 | 16.0 | replace |
661 |-------+---------+---------|
662 | c1 | 32 | replace |
663 | c2 | 64 | replace |
664 |-------+---------+---------|
665 | Total | replace | replace |
666 |-------+---------+---------|
669 |-------+-------+-------|
670 | Item | Item | Sub- |
671 | name | value | total |
672 |-------+-------+-------|
673 | a1 | 4.1 | |
674 | a2 | 8.2 | |
675 | a3 | | 12.3 |
676 |-------+-------+-------|
677 | b1 | 16.0 | 16.0 |
678 |-------+-------+-------|
679 | c1 | 32 | |
680 | c2 | 64 | 96.0 |
681 |-------+-------+-------|
682 | Total | 124.3 | |
683 |-------+-------+-------|
685 1 (concat "#+TBLFM: @>$2 = vsum(@II..@>>) ::"
686 "$3 = if(vlen(@0..@+I) == 1, "
687 "vsum(@-I$2..@+I$2) +.0, string(\"\")); EN f-1 :: "
688 "@>$3 = string(\"\")")))
690 (ert-deftest test-org-table/org-lookup-all ()
691 "Use `org-lookup-all' for several GROUP BY as in SQL and for ranking.
692 See also http://orgmode.org/worg/org-tutorials/org-lookups.html ."
693 (let ((data "
694 #+NAME: data
695 | Purchase | Product | Shop | Rating |
696 |----------+---------+------+--------|
697 | a | p1 | s1 | 1 |
698 | b | p1 | s2 | 4 |
699 | c | p2 | s1 | 2 |
700 | d | p3 | s2 | 8 |
703 ;; Product rating and ranking by average purchase from "#+NAME: data"
704 (org-test-table-target-expect
705 (concat data "
706 | Product | Rating | Ranking |
707 |---------+---------+---------|
708 | p1 | replace | replace |
709 | p2 | replace | replace |
710 | p3 | replace | replace |
712 (concat data "
713 | Product | Rating | Ranking |
714 |---------+--------+---------|
715 | p1 | 2.5 | 2 |
716 | p2 | 2.0 | 3 |
717 | p3 | 8.0 | 1 |
719 2 (concat
720 "#+TBLFM: $2 = '(let ((all (org-lookup-all '$1 "
721 "'(remote(data, @I$2..@>$2)) '(remote(data, @I$4..@>$4))))) "
722 "(/ (apply '+ all) (length all) 1.0)); L :: "
723 "$3 = '(+ 1 (length (org-lookup-all $2 '(@I$2..@>$2) nil '<))); N"))
725 ;; Shop rating and ranking by average purchase from "#+NAME: data"
726 (org-test-table-target-expect
727 (concat data "
728 | Shop | Rating | Ranking |
729 |------+---------+---------|
730 | s1 | replace | replace |
731 | s2 | replace | replace |
733 (concat data "
734 | Shop | Rating | Ranking |
735 |------+--------+---------|
736 | s1 | 1.5 | 2 |
737 | s2 | 6.0 | 1 |
739 2 (concat
740 "#+TBLFM: $2 = '(let ((all (org-lookup-all '$1 "
741 "'(remote(data, @I$3..@>$3)) '(remote(data, @I$4..@>$4))))) "
742 "(/ (apply '+ all) (length all) 1.0)); L :: "
743 "$3 = '(+ 1 (length (org-lookup-all $2 '(@I$2..@>$2) nil '<))); N"))))
745 (ert-deftest test-org-table/org-table-make-reference/mode-string-EL ()
746 (fset 'f 'org-table-make-reference)
747 ;; For Lisp formula only
748 (should (equal "0" (f "0" t nil 'literal)))
749 (should (equal "z" (f "z" t nil 'literal)))
750 (should (equal "" (f "" t nil 'literal)))
751 (should (equal "0 1" (f '("0" "1") t nil 'literal)))
752 (should (equal "z 1" (f '("z" "1") t nil 'literal)))
753 (should (equal " 1" (f '("" "1") t nil 'literal)))
754 (should (equal " " (f '("" "" ) t nil 'literal))))
756 (ert-deftest test-org-table/org-table-make-reference/mode-string-E ()
757 (fset 'f 'org-table-make-reference)
758 ;; For Lisp formula
759 (should (equal "\"0\"" (f "0" t nil t)))
760 (should (equal "\"z\"" (f "z" t nil t)))
761 (should (equal "\"\"" (f "" t nil t)))
762 (should (equal "\"0\" \"1\"" (f '("0" "1") t nil t)))
763 (should (equal "\"z\" \"1\"" (f '("z" "1") t nil t)))
764 (should (equal "\"\" \"1\"" (f '("" "1") t nil t)))
765 (should (equal "\"\" \"\"" (f '("" "" ) t nil t)))
766 ;; For Calc formula
767 (should (equal "(0)" (f "0" t nil nil)))
768 (should (equal "(z)" (f "z" t nil nil)))
769 (should (equal "nan" (f "" t nil nil)))
770 (should (equal "[0,1]" (f '("0" "1") t nil nil)))
771 (should (equal "[z,1]" (f '("z" "1") t nil nil)))
772 (should (equal "[nan,1]" (f '("" "1") t nil nil)))
773 (should (equal "[nan,nan]" (f '("" "" ) t nil nil)))
774 ;; For Calc formula, special numbers
775 (should (equal "(nan)" (f "nan" t nil nil)))
776 (should (equal "(uinf)" (f "uinf" t nil nil)))
777 (should (equal "(-inf)" (f "-inf" t nil nil)))
778 (should (equal "(inf)" (f "inf" t nil nil)))
779 (should (equal "[nan,1]" (f '( "nan" "1") t nil nil)))
780 (should (equal "[uinf,1]" (f '("uinf" "1") t nil nil)))
781 (should (equal "[-inf,1]" (f '("-inf" "1") t nil nil)))
782 (should (equal "[inf,1]" (f '( "inf" "1") t nil nil))))
784 (ert-deftest test-org-table/org-table-make-reference/mode-string-EN ()
785 (fset 'f 'org-table-make-reference)
786 ;; For Lisp formula
787 (should (equal "0" (f "0" t t t)))
788 (should (equal "0" (f "z" t t t)))
789 (should (equal "0" (f "" t t t)))
790 (should (equal "0 1" (f '("0" "1") t t t)))
791 (should (equal "0 1" (f '("z" "1") t t t)))
792 (should (equal "0 1" (f '("" "1") t t t)))
793 (should (equal "0 0" (f '("" "" ) t t t)))
794 ;; For Calc formula
795 (should (equal "(0)" (f "0" t t nil)))
796 (should (equal "(0)" (f "z" t t nil)))
797 (should (equal "(0)" (f "" t t nil)))
798 (should (equal "[0,1]" (f '("0" "1") t t nil)))
799 (should (equal "[0,1]" (f '("z" "1") t t nil)))
800 (should (equal "[0,1]" (f '("" "1") t t nil)))
801 (should (equal "[0,0]" (f '("" "" ) t t nil)))
802 ;; For Calc formula, special numbers
803 (should (equal "(0)" (f "nan" t t nil)))
804 (should (equal "(0)" (f "uinf" t t nil)))
805 (should (equal "(0)" (f "-inf" t t nil)))
806 (should (equal "(0)" (f "inf" t t nil)))
807 (should (equal "[0,1]" (f '( "nan" "1") t t nil)))
808 (should (equal "[0,1]" (f '("uinf" "1") t t nil)))
809 (should (equal "[0,1]" (f '("-inf" "1") t t nil)))
810 (should (equal "[0,1]" (f '( "inf" "1") t t nil))))
812 (ert-deftest test-org-table/org-table-make-reference/mode-string-L ()
813 (fset 'f 'org-table-make-reference)
814 ;; For Lisp formula only
815 (should (equal "0" (f "0" nil nil 'literal)))
816 (should (equal "z" (f "z" nil nil 'literal)))
817 (should (equal "" (f "" nil nil 'literal)))
818 (should (equal "0 1" (f '("0" "1") nil nil 'literal)))
819 (should (equal "z 1" (f '("z" "1") nil nil 'literal)))
820 (should (equal "1" (f '("" "1") nil nil 'literal)))
821 (should (equal "" (f '("" "" ) nil nil 'literal))))
823 (ert-deftest test-org-table/org-table-make-reference/mode-string-none ()
824 (fset 'f 'org-table-make-reference)
825 ;; For Lisp formula
826 (should (equal "\"0\"" (f "0" nil nil t)))
827 (should (equal "\"z\"" (f "z" nil nil t)))
828 (should (equal "" (f "" nil nil t)))
829 (should (equal "\"0\" \"1\"" (f '("0" "1") nil nil t)))
830 (should (equal "\"z\" \"1\"" (f '("z" "1") nil nil t)))
831 (should (equal "\"1\"" (f '("" "1") nil nil t)))
832 (should (equal "" (f '("" "" ) nil nil t)))
833 ;; For Calc formula
834 (should (equal "(0)" (f "0" nil nil nil)))
835 (should (equal "(z)" (f "z" nil nil nil)))
836 (should (equal "(0)" (f "" nil nil nil)))
837 (should (equal "[0,1]" (f '("0" "1") nil nil nil)))
838 (should (equal "[z,1]" (f '("z" "1") nil nil nil)))
839 (should (equal "[1]" (f '("" "1") nil nil nil)))
840 (should (equal "[]" (f '("" "" ) nil nil nil)))
841 ;; For Calc formula, special numbers
842 (should (equal "(nan)" (f "nan" nil nil nil)))
843 (should (equal "(uinf)" (f "uinf" nil nil nil)))
844 (should (equal "(-inf)" (f "-inf" nil nil nil)))
845 (should (equal "(inf)" (f "inf" nil nil nil)))
846 (should (equal "[nan,1]" (f '( "nan" "1") nil nil nil)))
847 (should (equal "[uinf,1]" (f '("uinf" "1") nil nil nil)))
848 (should (equal "[-inf,1]" (f '("-inf" "1") nil nil nil)))
849 (should (equal "[inf,1]" (f '( "inf" "1") nil nil nil))))
851 (ert-deftest test-org-table/org-table-make-reference/mode-string-N ()
852 (fset 'f 'org-table-make-reference)
853 ;; For Lisp formula
854 (should (equal "0" (f "0" nil t t)))
855 (should (equal "0" (f "z" nil t t)))
856 (should (equal "" (f "" nil t t)))
857 (should (equal "0 1" (f '("0" "1") nil t t)))
858 (should (equal "0 1" (f '("z" "1") nil t t)))
859 (should (equal "1" (f '("" "1") nil t t)))
860 (should (equal "" (f '("" "" ) nil t t)))
861 ;; For Calc formula
862 (should (equal "(0)" (f "0" nil t nil)))
863 (should (equal "(0)" (f "z" nil t nil)))
864 (should (equal "(0)" (f "" nil t nil)))
865 (should (equal "[0,1]" (f '("0" "1") nil t nil)))
866 (should (equal "[0,1]" (f '("z" "1") nil t nil)))
867 (should (equal "[1]" (f '("" "1") nil t nil)))
868 (should (equal "[]" (f '("" "" ) nil t nil)))
869 ;; For Calc formula, special numbers
870 (should (equal "(0)" (f "nan" nil t nil)))
871 (should (equal "(0)" (f "uinf" nil t nil)))
872 (should (equal "(0)" (f "-inf" nil t nil)))
873 (should (equal "(0)" (f "inf" nil t nil)))
874 (should (equal "[0,1]" (f '( "nan" "1") nil t nil)))
875 (should (equal "[0,1]" (f '("uinf" "1") nil t nil)))
876 (should (equal "[0,1]" (f '("-inf" "1") nil t nil)))
877 (should (equal "[0,1]" (f '( "inf" "1") nil t nil))))
879 (ert-deftest test-org-table/org-table-convert-refs-to-an/1 ()
880 "Simple reference @1$1."
881 (should
882 (string= "A1" (org-table-convert-refs-to-an "@1$1"))))
884 ;; TODO: Test broken
885 ;; (ert-deftest test-org-table/org-table-convert-refs-to-an/2 ()
886 ;; "Self reference @1$1."
887 ;; (should
888 ;; (string= "A1 = $0" (org-table-convert-refs-to-an "@1$1 = $0"))))
890 (ert-deftest test-org-table/org-table-convert-refs-to-an/3 ()
891 "Remote reference."
892 (should
893 (string= "C& = remote(FOO, @@#B&)" (org-table-convert-refs-to-an "$3 = remote(FOO, @@#$2)"))))
895 (ert-deftest test-org-table/org-table-convert-refs-to-rc/1 ()
896 "Simple reference @1$1."
897 (should
898 (string= "@1$1" (org-table-convert-refs-to-rc "A1"))))
900 (ert-deftest test-org-table/org-table-convert-refs-to-rc/2 ()
901 "Self reference $0."
902 (should
903 (string= "@1$1 = $0" (org-table-convert-refs-to-rc "A1 = $0"))))
905 ;; TODO: Test Broken
906 ;; (ert-deftest test-org-table/org-table-convert-refs-to-rc/3 ()
907 ;; "Remote reference."
908 ;; (should
909 ;; (string= "$3 = remote(FOO, @@#$2)" (org-table-convert-refs-to-rc "C& = remote(FOO, @@#B&)"))))
911 (ert-deftest test-org-table/remote-reference-access ()
912 "Access to remote reference.
913 See also `test-org-table/copy-field'."
914 (org-test-table-target-expect
916 #+NAME: table
917 | | x 42 | |
919 | replace | replace |
922 #+NAME: table
923 | | x 42 | |
925 | x 42 | 84 x |
927 1 (concat "#+TBLFM: "
928 ;; Copy text without calculation: Use Lisp formula
929 "$1 = '(identity remote(table, @1$2)) :: "
930 ;; Do a calculation: Use Calc (or Lisp ) formula
931 "$2 = 2 * remote(table, @1$2)")))
933 (ert-deftest test-org-table/remote-reference-indirect ()
934 "Access to remote reference with indirection of name or ID."
935 (let ((source-tables "
936 #+NAME: 2012
937 | amount |
938 |--------|
939 | 1 |
940 | 2 |
941 |--------|
942 | 3 |
943 #+TBLFM: @>$1 = vsum(@I..@II)
945 #+NAME: 2013
946 | amount |
947 |--------|
948 | 4 |
949 | 8 |
950 |--------|
951 | 12 |
952 #+TBLFM: @>$1 = vsum(@I..@II)
955 ;; Read several remote references from same column
956 (org-test-table-target-expect
957 (concat source-tables "
958 #+NAME: summary
959 | year | amount |
960 |-------+---------|
961 | 2012 | replace |
962 | 2013 | replace |
963 |-------+---------|
964 | total | replace |
966 (concat source-tables "
967 #+NAME: summary
968 | year | amount |
969 |-------+--------|
970 | 2012 | 3 |
971 | 2013 | 12 |
972 |-------+--------|
973 | total | 15 |
976 ;; Calc formula
977 "#+TBLFM: @<<$2..@>>$2 = remote($<, @>$1) :: @>$2 = vsum(@I..@II)"
978 ;; Lisp formula
979 (concat "#+TBLFM: @<<$2..@>>$2 = '(identity remote($<, @>$1)); N :: "
980 "@>$2 = '(+ @I..@II); N"))
982 ;; Read several remote references from same row
983 (org-test-table-target-expect
984 (concat source-tables "
985 #+NAME: summary
986 | year | 2012 | 2013 | total |
987 |--------+---------+---------+---------|
988 | amount | replace | replace | replace |
990 (concat source-tables "
991 #+NAME: summary
992 | year | 2012 | 2013 | total |
993 |--------+------+------+-------|
994 | amount | 3 | 12 | 15 |
997 ;; Calc formula
998 "#+TBLFM: @2$<<..@2$>> = remote(@<, @>$1) :: @2$> = vsum($<<..$>>)"
999 ;; Lisp formula
1000 (concat "#+TBLFM: @2$<<..@2$>> = '(identity remote(@<, @>$1)); N :: "
1001 "@2$> = '(+ $<<..$>>); N"))))
1003 (ert-deftest test-org-table/org-at-TBLFM-p ()
1004 (org-test-with-temp-text-in-file
1006 | 1 |
1007 | 2 |
1008 #+TBLFM: $2=$1*2
1011 (goto-char (point-min))
1012 (forward-line 2)
1013 (should (equal (org-at-TBLFM-p) nil))
1015 (goto-char (point-min))
1016 (forward-line 3)
1017 (should (equal (org-at-TBLFM-p) t))
1019 (goto-char (point-min))
1020 (forward-line 4)
1021 (should (equal (org-at-TBLFM-p) nil))))
1023 (ert-deftest test-org-table/org-table-TBLFM-begin ()
1024 (org-test-with-temp-text-in-file
1026 | 1 |
1027 | 2 |
1028 #+TBLFM: $2=$1*2
1031 (goto-char (point-min))
1032 (should (equal (org-table-TBLFM-begin)
1033 nil))
1035 (goto-char (point-min))
1036 (forward-line 1)
1037 (should (equal (org-table-TBLFM-begin)
1038 nil))
1040 (goto-char (point-min))
1041 (forward-line 3)
1042 (should (= (org-table-TBLFM-begin)
1043 14))
1045 (goto-char (point-min))
1046 (forward-line 4)
1047 (should (= (org-table-TBLFM-begin)
1048 14))
1052 (ert-deftest test-org-table/org-table-TBLFM-begin-for-multiple-TBLFM-lines ()
1053 "For multiple #+TBLFM lines."
1054 (org-test-with-temp-text-in-file
1056 | 1 |
1057 | 2 |
1058 #+TBLFM: $2=$1*1
1059 #+TBLFM: $2=$1*2
1062 (goto-char (point-min))
1063 (should (equal (org-table-TBLFM-begin)
1064 nil))
1066 (goto-char (point-min))
1067 (forward-line 1)
1068 (should (equal (org-table-TBLFM-begin)
1069 nil))
1071 (goto-char (point-min))
1072 (forward-line 3)
1073 (should (= (org-table-TBLFM-begin)
1074 14))
1076 (goto-char (point-min))
1077 (forward-line 4)
1078 (should (= (org-table-TBLFM-begin)
1079 14))
1081 (goto-char (point-min))
1082 (forward-line 5)
1083 (should (= (org-table-TBLFM-begin)
1084 14))
1088 (ert-deftest test-org-table/org-table-TBLFM-begin-for-pultiple-TBLFM-lines-blocks ()
1089 (org-test-with-temp-text-in-file
1091 | 1 |
1092 | 2 |
1093 #+TBLFM: $2=$1*1
1094 #+TBLFM: $2=$1*2
1096 | 6 |
1097 | 7 |
1098 #+TBLFM: $2=$1*1
1099 #+TBLFM: $2=$1*2
1102 (goto-char (point-min))
1103 (should (equal (org-table-TBLFM-begin)
1104 nil))
1106 (goto-char (point-min))
1107 (forward-line 1)
1108 (should (equal (org-table-TBLFM-begin)
1109 nil))
1111 (goto-char (point-min))
1112 (forward-line 3)
1113 (should (= (org-table-TBLFM-begin)
1114 14))
1116 (goto-char (point-min))
1117 (forward-line 4)
1118 (should (= (org-table-TBLFM-begin)
1119 14))
1121 (goto-char (point-min))
1122 (forward-line 5)
1123 (should (= (org-table-TBLFM-begin)
1124 14))
1126 (goto-char (point-min))
1127 (forward-line 6)
1128 (should (= (org-table-TBLFM-begin)
1129 14))
1131 (goto-char (point-min))
1132 (forward-line 8)
1133 (should (= (org-table-TBLFM-begin)
1134 61))
1136 (goto-char (point-min))
1137 (forward-line 9)
1138 (should (= (org-table-TBLFM-begin)
1139 61))
1141 (goto-char (point-min))
1142 (forward-line 10)
1143 (should (= (org-table-TBLFM-begin)
1144 61))))
1146 (ert-deftest test-org-table/org-table-calc-current-TBLFM ()
1147 (org-test-with-temp-text-in-file
1149 | 1 | |
1150 | 2 | |
1151 #+TBLFM: $2=$1*1
1152 #+TBLFM: $2=$1*2
1153 #+TBLFM: $2=$1*3
1155 (let ((got (progn (goto-char (point-min))
1156 (forward-line 3)
1157 (org-table-calc-current-TBLFM)
1158 (buffer-string)))
1159 (expect "
1160 | 1 | 1 |
1161 | 2 | 2 |
1162 #+TBLFM: $2=$1*1
1163 #+TBLFM: $2=$1*2
1164 #+TBLFM: $2=$1*3
1166 (should (string= got
1167 expect)))
1169 (let ((got (progn (goto-char (point-min))
1170 (forward-line 4)
1171 (org-table-calc-current-TBLFM)
1172 (buffer-string)))
1173 (expect "
1174 | 1 | 2 |
1175 | 2 | 4 |
1176 #+TBLFM: $2=$1*1
1177 #+TBLFM: $2=$1*2
1178 #+TBLFM: $2=$1*3
1180 (should (string= got
1181 expect)))))
1183 (ert-deftest test-org-table/org-table-calc-current-TBLFM-when-stop-because-of-error ()
1184 "org-table-calc-current-TBLFM should preserve the input as it was."
1185 (org-test-with-temp-text-in-file
1187 | 1 | 1 |
1188 | 2 | 2 |
1189 #+TBLFM: $2=$1*1
1190 #+TBLFM: $2=$1*2::$2=$1*2
1191 #+TBLFM: $2=$1*3
1193 (let ((expect "
1194 | 1 | 1 |
1195 | 2 | 2 |
1196 #+TBLFM: $2=$1*1
1197 #+TBLFM: $2=$1*2::$2=$1*2
1198 #+TBLFM: $2=$1*3
1200 (goto-char (point-min))
1201 (forward-line 4)
1202 (should-error (org-table-calc-current-TBLFM))
1203 (setq got (buffer-string))
1204 (message "%s" got)
1205 (should (string= got
1206 expect)))))
1208 ;;; Radio Tables
1210 (ert-deftest test-org-table/to-generic ()
1211 "Test `orgtbl-to-generic' specifications."
1212 ;; Test :hline parameter.
1213 (should
1214 (equal "a\nb"
1215 (orgtbl-to-generic (org-table-to-lisp "| a |\n|---|\n| b |")
1216 '(:hline nil))))
1217 (should
1218 (equal "a\n~\nb"
1219 (orgtbl-to-generic (org-table-to-lisp "| a |\n|---|\n| b |")
1220 '(:hline "~"))))
1221 ;; Test :sep parameter.
1222 (should
1223 (equal "a!b\nc!d"
1224 (orgtbl-to-generic
1225 (org-table-to-lisp "| a | b |\n|---+---|\n| c | d |")
1226 '(:sep "!"))))
1227 ;; Test :hsep parameter.
1228 (should
1229 (equal "a!b\nc?d"
1230 (orgtbl-to-generic
1231 (org-table-to-lisp "| a | b |\n|---+---|\n| c | d |")
1232 '(:sep "?" :hsep "!"))))
1233 ;; Test :tstart parameter.
1234 (should
1235 (equal "<begin>\na"
1236 (orgtbl-to-generic (org-table-to-lisp "| a |") '(:tstart "<begin>"))))
1237 (should
1238 (equal "<begin>\na"
1239 (orgtbl-to-generic (org-table-to-lisp "| a |")
1240 '(:tstart (lambda () "<begin>")))))
1241 (should
1242 (equal "a"
1243 (orgtbl-to-generic (org-table-to-lisp "| a |")
1244 '(:tstart "<begin>" :splice t))))
1245 ;; Test :tend parameter.
1246 (should
1247 (equal "a\n<end>"
1248 (orgtbl-to-generic (org-table-to-lisp "| a |") '(:tend "<end>"))))
1249 (should
1250 (equal "a\n<end>"
1251 (orgtbl-to-generic (org-table-to-lisp "| a |")
1252 '(:tend (lambda () "<end>")))))
1253 (should
1254 (equal "a"
1255 (orgtbl-to-generic (org-table-to-lisp "| a |")
1256 '(:tend "<end>" :splice t))))
1257 ;; Test :lstart parameter.
1258 (should
1259 (equal "> a"
1260 (orgtbl-to-generic
1261 (org-table-to-lisp "| a |") '(:lstart "> "))))
1262 (should
1263 (equal "> a"
1264 (orgtbl-to-generic (org-table-to-lisp "| a |")
1265 '(:lstart (lambda () "> ")))))
1266 ;; Test :llstart parameter.
1267 (should
1268 (equal "> a\n>> b"
1269 (orgtbl-to-generic (org-table-to-lisp "| a |\n|---|\n| b |")
1270 '(:lstart "> " :llstart ">> "))))
1271 ;; Test :hlstart parameter.
1272 (should
1273 (equal "!> a\n> b"
1274 (orgtbl-to-generic (org-table-to-lisp "| a |\n|---|\n| b |")
1275 '(:lstart "> " :hlstart "!> "))))
1276 ;; Test :hllstart parameter.
1277 (should
1278 (equal "!> a\n!!> b\n> c"
1279 (orgtbl-to-generic (org-table-to-lisp "| a |\n| b |\n|---|\n| c |")
1280 '(:lstart "> " :hlstart "!> " :hllstart "!!> "))))
1281 ;; Test :lend parameter.
1282 (should
1283 (equal "a <"
1284 (orgtbl-to-generic (org-table-to-lisp "| a |") '(:lend " <"))))
1285 ;; Test :llend parameter.
1286 (should
1287 (equal "a <\nb <<"
1288 (orgtbl-to-generic (org-table-to-lisp "| a |\n|---|\n| b |")
1289 '(:lend " <" :llend " <<"))))
1290 ;; Test :hlend parameter.
1291 (should
1292 (equal "a <!\nb <"
1293 (orgtbl-to-generic (org-table-to-lisp "| a |\n|---|\n| b |")
1294 '(:lend " <" :hlend " <!"))))
1295 ;; Test :hllend parameter.
1296 (should
1297 (equal "a <!\nb <!!\nc <"
1298 (orgtbl-to-generic (org-table-to-lisp "| a |\n| b |\n|---|\n| c |")
1299 '(:lend " <" :hlend " <!" :hllend " <!!"))))
1300 ;; Test :lfmt parameter.
1301 (should
1302 (equal "a!b"
1303 (orgtbl-to-generic (org-table-to-lisp "| a | b |")
1304 '(:lfmt "%s!%s"))))
1305 (should
1306 (equal "a+b"
1307 (orgtbl-to-generic
1308 (org-table-to-lisp "| a | b |")
1309 '(:lfmt (lambda (c) (concat (car c) "+" (cadr c)))))))
1310 (should
1311 (equal "a!b"
1312 (orgtbl-to-generic (org-table-to-lisp "| a | b |")
1313 '(:lfmt "%s!%s" :lstart ">" :lend "<" :sep " "))))
1314 ;; Test :llfmt parameter.
1315 (should
1316 (equal "a!b"
1317 (orgtbl-to-generic (org-table-to-lisp "| a | b |")
1318 '(:llfmt "%s!%s"))))
1319 (should
1320 (equal "a!b\nc+d"
1321 (orgtbl-to-generic
1322 (org-table-to-lisp "| a | b |\n| c | d |")
1323 '(:lfmt "%s!%s" :llfmt (lambda (c) (concat (car c) "+" (cadr c)))))))
1324 (should
1325 (equal "a!b"
1326 (orgtbl-to-generic (org-table-to-lisp "| a | b |")
1327 '(:llfmt "%s!%s" :lstart ">" :lend "<" :sep " "))))
1328 ;; Test :hlfmt parameter.
1329 (should
1330 (equal "a!b\ncd"
1331 (orgtbl-to-generic
1332 (org-table-to-lisp "| a | b |\n|---+---|\n| c | d |")
1333 '(:hlfmt "%s!%s"))))
1334 (should
1335 (equal "a+b\ncd"
1336 (orgtbl-to-generic
1337 (org-table-to-lisp "| a | b |\n|---+---|\n| c | d |")
1338 '(:hlfmt (lambda (c) (concat (car c) "+" (cadr c)))))))
1339 (should
1340 (equal "a!b\n>c d<"
1341 (orgtbl-to-generic
1342 (org-table-to-lisp "| a | b |\n|---+---|\n| c | d |")
1343 '(:hlfmt "%s!%s" :lstart ">" :lend "<" :sep " "))))
1344 ;; Test :hllfmt parameter.
1345 (should
1346 (equal "a!b\ncd"
1347 (orgtbl-to-generic
1348 (org-table-to-lisp "| a | b |\n|---+---|\n| c | d |")
1349 '(:hllfmt "%s!%s"))))
1350 (should
1351 (equal "a+b\ncd"
1352 (orgtbl-to-generic
1353 (org-table-to-lisp "| a | b |\n|---+---|\n| c | d |")
1354 '(:hllfmt (lambda (c) (concat (car c) "+" (cadr c)))))))
1355 (should
1356 (equal "a!b\n>c d<"
1357 (orgtbl-to-generic
1358 (org-table-to-lisp "| a | b |\n|---+---|\n| c | d |")
1359 '(:hllfmt "%s!%s" :lstart ">" :lend "<" :sep " "))))
1360 ;; Test :fmt parameter.
1361 (should
1362 (equal ">a<\n>b<"
1363 (orgtbl-to-generic (org-table-to-lisp "| a |\n|---|\n| b |")
1364 '(:fmt ">%s<"))))
1365 (should
1366 (equal ">a<b"
1367 (orgtbl-to-generic (org-table-to-lisp "| a | b |")
1368 '(:fmt (1 ">%s<" 2 (lambda (c) c))))))
1369 (should
1370 (equal "a b"
1371 (orgtbl-to-generic (org-table-to-lisp "| a | b |")
1372 '(:fmt (2 " %s")))))
1373 (should
1374 (equal ">a<"
1375 (orgtbl-to-generic (org-table-to-lisp "| a |")
1376 '(:fmt (lambda (c) (format ">%s<" c))))))
1377 ;; Test :hfmt parameter.
1378 (should
1379 (equal ">a<\nb"
1380 (orgtbl-to-generic (org-table-to-lisp "| a |\n|---|\n| b |")
1381 '(:hfmt ">%s<"))))
1382 (should
1383 (equal ">a<b\ncd"
1384 (orgtbl-to-generic
1385 (org-table-to-lisp "| a | b |\n|---+---|\n| c | d |")
1386 '(:hfmt (1 ">%s<" 2 identity)))))
1387 (should
1388 (equal "a b\ncd"
1389 (orgtbl-to-generic
1390 (org-table-to-lisp "| a | b |\n|---+---|\n| c | d |")
1391 '(:hfmt (2 " %s")))))
1392 (should
1393 (equal ">a<\nb"
1394 (orgtbl-to-generic (org-table-to-lisp "| a |\n|---|\n| b |")
1395 '(:hfmt (lambda (c) (format ">%s<" c))))))
1396 ;; Test :efmt parameter.
1397 (should
1398 (equal "2x10^3"
1399 (orgtbl-to-generic (org-table-to-lisp "| 2e3 |")
1400 '(:efmt "%sx10^%s"))))
1401 (should
1402 (equal "2x10^3"
1403 (orgtbl-to-generic (org-table-to-lisp "| 2e3 |")
1404 '(:efmt (lambda (m e) (concat m "x10^" e))))))
1405 (should
1406 (equal "2x10^3"
1407 (orgtbl-to-generic (org-table-to-lisp "| 2e3 |")
1408 '(:efmt (1 "%sx10^%s")))))
1409 (should
1410 (equal "2x10^3"
1411 (orgtbl-to-generic
1412 (org-table-to-lisp "| 2e3 |")
1413 '(:efmt (1 (lambda (m e) (format "%sx10^%s" m e)))))))
1414 (should
1415 (equal "2e3"
1416 (orgtbl-to-generic (org-table-to-lisp "| 2e3 |") '(:efmt nil))))
1417 ;; Test :skip parameter.
1418 (should
1419 (equal "cd"
1420 (orgtbl-to-generic
1421 (org-table-to-lisp "| \ | <c> |\n| a | b |\n|---+---|\n| c | d |")
1422 '(:skip 2))))
1423 ;; Test :skipcols parameter.
1424 (should
1425 (equal "a\nc"
1426 (orgtbl-to-generic
1427 (org-table-to-lisp "| a | b |\n| c | d |") '(:skipcols (2)))))
1428 (should
1429 (equal "a\nc"
1430 (orgtbl-to-generic
1431 (org-table-to-lisp
1432 "| / | <c> | <c> |\n| # | a | b |\n|---+---+---|\n| | c | d |")
1433 '(:skipcols (2)))))
1434 ;; Test :raw parameter.
1435 (when (featurep 'ox-latex)
1436 (should
1437 (org-string-match-p
1438 "/a/"
1439 (orgtbl-to-generic (org-table-to-lisp "| /a/ | b |")
1440 '(:backend latex :raw t)))))
1441 ;; Hooks are ignored.
1442 (should
1443 (equal
1444 "a\nb"
1445 (let* ((fun-list (list (lambda (backend) (search-forward "a") (insert "hook"))))
1446 (org-export-before-parsing-hook fun-list)
1447 (org-export-before-processing-hook fun-list))
1448 (orgtbl-to-generic (org-table-to-lisp "| a |\n|---|\n| b |")
1449 '(:hline nil)))))
1450 ;; User-defined export filters are ignored.
1451 (should
1452 (equal
1453 "a\nb"
1454 (let ((org-export-filter-table-cell-functions (list (lambda (c b i) "filter"))))
1455 (orgtbl-to-generic (org-table-to-lisp "| a |\n|---|\n| b |")
1456 '(:hline nil))))))
1458 (ert-deftest test-org-table/to-latex ()
1459 "Test `orgtbl-to-latex' specifications."
1460 (should
1461 (equal "\\begin{tabular}{l}\na\\\\\n\\end{tabular}"
1462 (orgtbl-to-latex (org-table-to-lisp "| a |") nil)))
1463 ;; Test :environment parameter.
1464 (should
1465 (equal "\\begin{tabularx}{l}\na\\\\\n\\end{tabularx}"
1466 (orgtbl-to-latex (org-table-to-lisp "| a |")
1467 '(:environment "tabularx"))))
1468 ;; Test :booktabs parameter.
1469 (should
1470 (org-string-match-p
1471 "\\toprule" (orgtbl-to-latex (org-table-to-lisp "| a |") '(:booktabs t))))
1472 ;; Test pseudo objects and :raw parameter.
1473 (should
1474 (org-string-match-p
1475 "\\$x\\$" (orgtbl-to-latex (org-table-to-lisp "| $x$ |") '(:raw t)))))
1477 (ert-deftest test-org-table/to-html ()
1478 "Test `orgtbl-to-html' specifications."
1479 (should
1480 (equal (orgtbl-to-html (org-table-to-lisp "| a |") nil)
1481 "<table border=\"2\" cellspacing=\"0\" cellpadding=\"6\" rules=\"groups\" frame=\"hsides\">
1484 <colgroup>
1485 <col class=\"left\" />
1486 </colgroup>
1487 <tbody>
1488 <tr>
1489 <td class=\"left\">a</td>
1490 </tr>
1491 </tbody>
1492 </table>"))
1493 ;; Test :attributes parameter.
1494 (should
1495 (org-string-match-p
1496 "<table>"
1497 (orgtbl-to-html (org-table-to-lisp "| a |") '(:attributes nil))))
1498 (should
1499 (org-string-match-p
1500 "<table border=\"2\">"
1501 (orgtbl-to-html (org-table-to-lisp "| a |") '(:attributes (:border "2"))))))
1503 (ert-deftest test-org-table/to-texinfo ()
1504 "Test `orgtbl-to-texinfo' specifications."
1505 (should
1506 (equal "@multitable {a}\n@item a\n@end multitable"
1507 (orgtbl-to-texinfo (org-table-to-lisp "| a |") nil)))
1508 ;; Test :columns parameter.
1509 (should
1510 (equal "@multitable @columnfractions .4 .6\n@item a\n@tab b\n@end multitable"
1511 (orgtbl-to-texinfo (org-table-to-lisp "| a | b |")
1512 '(:columns ".4 .6"))))
1513 (should
1514 (equal "@multitable @columnfractions .4 .6\n@item a\n@tab b\n@end multitable"
1515 (orgtbl-to-texinfo (org-table-to-lisp "| a | b |")
1516 '(:columns "@columnfractions .4 .6"))))
1517 (should
1518 (equal "@multitable {xxx} {xx}\n@item a\n@tab b\n@end multitable"
1519 (orgtbl-to-texinfo (org-table-to-lisp "| a | b |")
1520 '(:columns "{xxx} {xx}")))))
1522 (ert-deftest test-org-table/to-orgtbl ()
1523 "Test `orgtbl-to-orgtbl' specifications."
1524 (should
1525 (equal "| a | b |\n|---+---|\n| c | d |"
1526 (orgtbl-to-orgtbl
1527 (org-table-to-lisp "| a | b |\n|---+---|\n| c | d |") nil))))
1529 (ert-deftest test-org-table/to-unicode ()
1530 "Test `orgtbl-to-unicode' specifications."
1531 (should
1532 (equal "━━━\n a \n━━━"
1533 (orgtbl-to-unicode (org-table-to-lisp "| a |") nil)))
1534 ;; Test :narrow parameter.
1535 (should
1536 (equal "━━━━\n => \n━━━━"
1537 (orgtbl-to-unicode (org-table-to-lisp "| <2> |\n| xxx |")
1538 '(:narrow t)))))
1540 (ert-deftest test-org-table/send-region ()
1541 "Test `orgtbl-send-table' specifications."
1542 ;; Error when not at a table.
1543 (should-error
1544 (org-test-with-temp-text "Paragraph"
1545 (orgtbl-send-table)))
1546 ;; Error when destination is missing.
1547 (should-error
1548 (org-test-with-temp-text "#+ORGTBL: SEND\n<point>| a |"
1549 (orgtbl-send-table)))
1550 ;; Error when transformation function is not specified.
1551 (should-error
1552 (org-test-with-temp-text "
1553 # BEGIN RECEIVE ORGTBL table
1554 # END RECEIVE ORGTBL table
1555 #+ORGTBL: SEND table
1556 <point>| a |"
1557 (orgtbl-send-table)))
1558 ;; Standard test.
1559 (should
1560 (equal "| a |\n|---|\n| b |\n"
1561 (org-test-with-temp-text "
1562 # BEGIN RECEIVE ORGTBL table
1563 # END RECEIVE ORGTBL table
1564 #+ORGTBL: SEND table orgtbl-to-orgtbl :hlines nil
1565 <point>| a |\n|---|\n| b |"
1566 (orgtbl-send-table)
1567 (goto-char (point-min))
1568 (buffer-substring-no-properties
1569 (search-forward "# BEGIN RECEIVE ORGTBL table\n")
1570 (progn (search-forward "# END RECEIVE ORGTBL table")
1571 (match-beginning 0)))))))
1574 ;;; Sorting
1576 (ert-deftest test-org-table/sort-lines ()
1577 "Test `org-table-sort-lines' specifications."
1578 ;; Sort numerically.
1579 (should
1580 (equal "| 1 | 2 |\n| 2 | 4 |\n| 5 | 3 |\n"
1581 (org-test-with-temp-text "| <point>1 | 2 |\n| 5 | 3 |\n| 2 | 4 |\n"
1582 (org-table-sort-lines nil ?n)
1583 (buffer-string))))
1584 (should
1585 (equal "| 5 | 3 |\n| 2 | 4 |\n| 1 | 2 |\n"
1586 (org-test-with-temp-text "| <point>1 | 2 |\n| 5 | 3 |\n| 2 | 4 |\n"
1587 (org-table-sort-lines nil ?N)
1588 (buffer-string))))
1589 ;; Sort alphabetically.
1590 (should
1591 (equal "| a | x |\n| b | 4 |\n| c | 3 |\n"
1592 (org-test-with-temp-text "| <point>a | x |\n| c | 3 |\n| b | 4 |\n"
1593 (org-table-sort-lines nil ?a)
1594 (buffer-string))))
1595 (should
1596 (equal "| c | 3 |\n| b | 4 |\n| a | x |\n"
1597 (org-test-with-temp-text "| <point>a | x |\n| c | 3 |\n| b | 4 |\n"
1598 (org-table-sort-lines nil ?A)
1599 (buffer-string))))
1600 ;; Sort alphabetically with case.
1601 (should
1602 (equal "| C |\n| a |\n| b |\n"
1603 (org-test-with-temp-text "| <point>a |\n| C |\n| b |\n"
1604 (org-table-sort-lines t ?a)
1605 (buffer-string))))
1606 (should
1607 (equal "| C |\n| b |\n| a |\n"
1608 (org-test-with-temp-text "| <point>a |\n| C |\n| b |\n"
1609 (org-table-sort-lines nil ?A)
1610 (buffer-string))))
1611 ;; Sort by time (timestamps)
1612 (should
1613 (equal
1614 "| <2008-08-08 sat.> |\n| <2012-03-29 thu.> |\n| <2014-03-04 tue.> |\n"
1615 (org-test-with-temp-text
1616 "| <2014-03-04 tue.> |\n| <2008-08-08 sat.> |\n| <2012-03-29 thu.> |\n"
1617 (org-table-sort-lines nil ?t)
1618 (buffer-string))))
1619 (should
1620 (equal
1621 "| <2014-03-04 tue.> |\n| <2012-03-29 thu.> |\n| <2008-08-08 sat.> |\n"
1622 (org-test-with-temp-text
1623 "| <2014-03-04 tue.> |\n| <2008-08-08 sat.> |\n| <2012-03-29 thu.> |\n"
1624 (org-table-sort-lines nil ?T)
1625 (buffer-string))))
1626 ;; Sort by time (HH:MM values)
1627 (should
1628 (equal "| 1:00 |\n| 14:00 |\n| 17:00 |\n"
1629 (org-test-with-temp-text "| 14:00 |\n| 17:00 |\n| 1:00 |\n"
1630 (org-table-sort-lines nil ?t)
1631 (buffer-string))))
1632 (should
1633 (equal "| 17:00 |\n| 14:00 |\n| 1:00 |\n"
1634 (org-test-with-temp-text "| 14:00 |\n| 17:00 |\n| 1:00 |\n"
1635 (org-table-sort-lines nil ?T)
1636 (buffer-string))))
1637 ;; Sort with custom functions.
1638 (should
1639 (equal "| 22 |\n| 15 |\n| 18 |\n"
1640 (org-test-with-temp-text "| 15 |\n| 22 |\n| 18 |\n"
1641 (org-table-sort-lines nil ?f
1642 (lambda (s) (% (string-to-number s) 10))
1643 #'<)
1644 (buffer-string))))
1645 (should
1646 (equal "| 18 |\n| 15 |\n| 22 |\n"
1647 (org-test-with-temp-text "| 15 |\n| 22 |\n| 18 |\n"
1648 (org-table-sort-lines nil ?F
1649 (lambda (s) (% (string-to-number s) 10))
1650 #'<)
1651 (buffer-string))))
1652 ;; Sort according to current column.
1653 (should
1654 (equal "| 1 | 2 |\n| 7 | 3 |\n| 5 | 4 |\n"
1655 (org-test-with-temp-text "| 1 | <point>2 |\n| 5 | 4 |\n| 7 | 3 |\n"
1656 (org-table-sort-lines nil ?n)
1657 (buffer-string))))
1658 ;; Sort between horizontal separators if possible.
1659 (should
1660 (equal
1661 "| 9 | 8 |\n|---+---|\n| 5 | 3 |\n| 7 | 4 |\n|---+---|\n| 1 | 2 |\n"
1662 (org-test-with-temp-text
1663 "| 9 | 8 |\n|---+---|\n| <point>7 | 4 |\n| 5 | 3 |\n|---+---|\n| 1 | 2 |\n"
1664 (org-table-sort-lines nil ?n)
1665 (buffer-string)))))
1668 ;;; Field formulas
1670 (ert-deftest test-org-table/field-formula-outside-table ()
1671 "If `org-table-formula-create-columns' is nil, then a formula
1672 that references an out-of-bounds column should do nothing. If it
1673 is t, then new columns should be added as needed"
1675 (let ((org-table-formula-create-columns nil))
1677 (should-error
1678 (org-test-table-target-expect
1680 | 2 |
1681 | 4 |
1682 | 8 |
1685 | 2 |
1686 | 4 |
1687 | 8 |
1690 "#+TBLFM: @1$2=5")
1691 :type (list 'error 'user-error)))
1693 (let ((org-table-formula-create-columns t))
1695 ;; make sure field formulas work
1696 (org-test-table-target-expect
1698 | 2 |
1699 | 4 |
1700 | 8 |
1703 | 2 | 5 |
1704 | 4 | |
1705 | 8 | |
1708 "#+TBLFM: @1$2=5")
1710 ;; and make sure column formulas work too
1711 (org-test-table-target-expect
1713 | 2 |
1714 | 4 |
1715 | 8 |
1718 | 2 | | 15 |
1719 | 4 | | 15 |
1720 | 8 | | 15 |
1723 "#+TBLFM: $3=15")))
1725 (provide 'test-org-table)
1727 ;;; test-org-table.el ends here