test-org-colview.el 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478
  1. ;;; test-org-colview.el --- Tests for org-colview.el -*- lexical-binding: t; -*-
  2. ;; Copyright (C) 2016 Nicolas Goaziou
  3. ;; Author: Nicolas Goaziou <mail@nicolasgoaziou.fr>
  4. ;; This program is free software; you can redistribute it and/or modify
  5. ;; it under the terms of the GNU General Public License as published by
  6. ;; the Free Software Foundation, either version 3 of the License, or
  7. ;; (at your option) any later version.
  8. ;; This program is distributed in the hope that it will be useful,
  9. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. ;; GNU General Public License for more details.
  12. ;; You should have received a copy of the GNU General Public License
  13. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. ;;; Code:
  15. ;;; Column view
  16. (require 'cl-lib)
  17. (ert-deftest test-org-colview/get-format ()
  18. "Test `org-columns-get-format' specifications."
  19. ;; Without any clue, use `org-columns-default-format'.
  20. (should
  21. (equal "%A"
  22. (org-test-with-temp-text "* H"
  23. (let ((org-columns-default-format "%A"))
  24. (org-columns-get-format)))))
  25. ;; If COLUMNS keyword is set, use it.
  26. (should
  27. (equal "%B"
  28. (org-test-with-temp-text "#+COLUMNS: %B\n* H"
  29. (let ((org-columns-default-format "%A"))
  30. (org-columns-get-format)))))
  31. (should
  32. (equal "%B"
  33. (org-test-with-temp-text "#+columns: %B\n* H"
  34. (let ((org-columns-default-format "%A"))
  35. (org-columns-get-format)))))
  36. (should
  37. (equal "%B"
  38. (org-test-with-temp-text "* H\n#+COLUMNS: %B"
  39. (let ((org-columns-default-format "%A"))
  40. (org-columns-get-format)))))
  41. ;; When :COLUMNS: property is set somewhere in the tree, use it over
  42. ;; the previous ways.
  43. (should
  44. (equal
  45. "%C"
  46. (org-test-with-temp-text
  47. "#+COLUMNS: %B\n* H\n:PROPERTIES:\n:COLUMNS: %C\n:END:\n** S\n<point>"
  48. (let ((org-columns-default-format "%A"))
  49. (org-columns-get-format)))))
  50. ;; When optional argument is provided, prefer it.
  51. (should
  52. (equal
  53. "%D"
  54. (org-test-with-temp-text
  55. "#+COLUMNS: %B\n* H\n:PROPERTIES:\n:COLUMNS: %C\n:END:\n** S\n<point>"
  56. (let ((org-columns-default-format "%A"))
  57. (org-columns-get-format "%D"))))))
  58. (ert-deftest test-org-colview/columns-scope ()
  59. "Test `org-columns' scope."
  60. ;; Before the first headline, view all document.
  61. (should
  62. (equal
  63. '("H1" "H2" "H3")
  64. (org-test-with-temp-text "Top\n* H1\n** H2\n* H3"
  65. (let ((org-columns-default-format "%ITEM")) (org-columns))
  66. (org-map-entries
  67. (lambda () (get-char-property (point) 'org-columns-value))))))
  68. ;; When :COLUMNS: is set up in the hierarchy, view tree starting
  69. ;; there.
  70. (should
  71. (equal
  72. '(nil "H2" "H3" nil)
  73. (org-test-with-temp-text
  74. "* H1\n** H2\n:PROPERTIES:\n:COLUMNS: %ITEM\n:END:\n*** <point>H3\n* H4"
  75. (let ((org-columns-default-format "%ITEM")) (org-columns))
  76. (org-map-entries
  77. (lambda () (get-char-property (point) 'org-columns-value))))))
  78. ;; Otherwise, view tree starting at the current headline.
  79. (should
  80. (equal
  81. '(nil "H2" "H3" nil)
  82. (org-test-with-temp-text "Top\n* H1\n** <point>H2\n*** H3\n* H4"
  83. (let ((org-columns-default-format "%ITEM")) (org-columns))
  84. (org-map-entries
  85. (lambda () (get-char-property (point) 'org-columns-value))))))
  86. ;; With a non-nil prefix argument, always view all document.
  87. (should
  88. (equal
  89. '("H1" "H2" "H3" "H4")
  90. (org-test-with-temp-text
  91. "* H1\n** H2\n:PROPERTIES:\n:COLUMNS: %ITEM\n:END:\n*** <point>H3\n* H4"
  92. (let ((org-columns-default-format "%ITEM")) (org-columns t))
  93. (org-map-entries
  94. (lambda () (get-char-property (point) 'org-columns-value))))))
  95. (should
  96. (equal
  97. '("1" "1")
  98. (org-test-with-temp-text
  99. "Top\n* H1\n** <point>H2\n:PROPERTIES:\n:A: 1\n:END:"
  100. (let ((org-columns-default-format "%A{+}")) (org-columns t))
  101. (org-map-entries
  102. (lambda () (get-char-property (point) 'org-columns-value)))))))
  103. (ert-deftest test-org-colview/columns-width ()
  104. "Test `org-columns' column widths."
  105. ;; When a width is specified in the format, use it.
  106. (should
  107. (= 9
  108. (org-test-with-temp-text "* H"
  109. (let ((org-columns-default-format "%9ITEM")) (org-columns))
  110. (aref org-columns-current-maxwidths 0))))
  111. ;; Otherwise, use the width of the largest value in the column.
  112. (should
  113. (= 2
  114. (org-test-with-temp-text
  115. "* H\n:PROPERTIES:\n:P: X\n:END:\n** H2\n:PROPERTIES:\n:P: XX\n:END:"
  116. (let ((org-columns-default-format "%P")) (org-columns))
  117. (aref org-columns-current-maxwidths 0))))
  118. ;; If the title is wider than the widest value, use title width
  119. ;; instead.
  120. (should
  121. (= 4
  122. (org-test-with-temp-text "* H"
  123. (let ((org-columns-default-format "%ITEM")) (org-columns))
  124. (aref org-columns-current-maxwidths 0))))
  125. ;; Special case: stars do count for ITEM.
  126. (should
  127. (= 6
  128. (org-test-with-temp-text "* Head"
  129. (let ((org-columns-default-format "%ITEM")) (org-columns))
  130. (aref org-columns-current-maxwidths 0))))
  131. ;; Special case: width takes into account link narrowing in ITEM.
  132. (should
  133. (equal
  134. '("* [123]" . 7)
  135. (org-test-with-temp-text "* [[http://orgmode.org][123]]"
  136. (let ((org-columns-default-format "%ITEM")) (org-columns))
  137. (cons (get-char-property (point) 'org-columns-value-modified)
  138. (aref org-columns-current-maxwidths 0)))))
  139. ;; When a value is too wide for the current column, add ellipses.
  140. ;; Take into consideration length of `org-columns-ellipses'.
  141. (should
  142. (equal "123.. |"
  143. (org-test-with-temp-text "* H\n:PROPERTIES:\n:P: 123456\n:END:"
  144. (let ((org-columns-default-format "%5P")
  145. (org-columns-ellipses ".."))
  146. (org-columns))
  147. (org-trim (get-char-property (point) 'display)))))
  148. (should
  149. (equal "1234… |"
  150. (org-test-with-temp-text "* H\n:PROPERTIES:\n:P: 123456\n:END:"
  151. (let ((org-columns-default-format "%5P")
  152. (org-columns-ellipses "…"))
  153. (org-columns))
  154. (org-trim (get-char-property (point) 'display))))))
  155. (ert-deftest test-org-colview/columns-summary ()
  156. "Test `org-columns' summary types."
  157. ;; {+} and {+;format} add numbers.
  158. (should
  159. (equal
  160. "3"
  161. (org-test-with-temp-text
  162. "* H
  163. ** S1
  164. :PROPERTIES:
  165. :A: 1
  166. :END:
  167. ** S1
  168. :PROPERTIES:
  169. :A: 2
  170. :END:"
  171. (let ((org-columns-default-format "%A{+}")) (org-columns))
  172. (get-char-property (point) 'org-columns-value-modified))))
  173. (should
  174. (equal
  175. "3.0"
  176. (org-test-with-temp-text
  177. "* H
  178. ** S1
  179. :PROPERTIES:
  180. :A: 1
  181. :END:
  182. ** S1
  183. :PROPERTIES:
  184. :A: 2
  185. :END:"
  186. (let ((org-columns-default-format "%A{+;%.1f}")) (org-columns))
  187. (get-char-property (point) 'org-columns-value-modified))))
  188. ;; {$} is a shortcut for {+;%.2f}.
  189. (should
  190. (equal
  191. "3.60"
  192. (org-test-with-temp-text
  193. "* H
  194. ** S1
  195. :PROPERTIES:
  196. :A: 1.50
  197. :END:
  198. ** S1
  199. :PROPERTIES:
  200. :A: 2.10
  201. :END:"
  202. (let ((org-columns-default-format "%A{$}")) (org-columns))
  203. (get-char-property (point) 'org-columns-value-modified))))
  204. ;; Obey to format string even in leaf values.
  205. (should
  206. (equal
  207. "1.0"
  208. (org-test-with-temp-text
  209. "* H
  210. :PROPERTIES:
  211. :A: 1
  212. :END:"
  213. (let ((org-columns-default-format "%A{+;%.1f}")) (org-columns))
  214. (get-char-property (point) 'org-columns-value-modified))))
  215. ;; {:} sums times. Plain numbers are hours.
  216. (should
  217. (equal
  218. "4:10"
  219. (org-test-with-temp-text
  220. "* H
  221. ** S1
  222. :PROPERTIES:
  223. :A: 1:30
  224. :END:
  225. ** S1
  226. :PROPERTIES:
  227. :A: 2:40
  228. :END:"
  229. (let ((org-columns-default-format "%A{:}")) (org-columns))
  230. (get-char-property (point) 'org-columns-value-modified))))
  231. (should
  232. (equal
  233. "3:30"
  234. (org-test-with-temp-text
  235. "* H
  236. ** S1
  237. :PROPERTIES:
  238. :A: 1:30
  239. :END:
  240. ** S1
  241. :PROPERTIES:
  242. :A: 2
  243. :END:"
  244. (let ((org-columns-default-format "%A{:}")) (org-columns))
  245. (get-char-property (point) 'org-columns-value-modified))))
  246. ;; {X}, {X/} and {X%} indicate checkbox status.
  247. (should
  248. (equal
  249. "[ ]"
  250. (org-test-with-temp-text
  251. "* H
  252. ** S1
  253. :PROPERTIES:
  254. :A: [ ]
  255. :END:
  256. ** S1
  257. :PROPERTIES:
  258. :A: [ ]
  259. :END:"
  260. (let ((org-columns-default-format "%A{X}")) (org-columns))
  261. (get-char-property (point) 'org-columns-value-modified))))
  262. (should
  263. (equal
  264. "[-]"
  265. (org-test-with-temp-text
  266. "* H
  267. ** S1
  268. :PROPERTIES:
  269. :A: [ ]
  270. :END:
  271. ** S1
  272. :PROPERTIES:
  273. :A: [X]
  274. :END:"
  275. (let ((org-columns-default-format "%A{X}")) (org-columns))
  276. (get-char-property (point) 'org-columns-value-modified))))
  277. (should
  278. (equal
  279. "[X]"
  280. (org-test-with-temp-text
  281. "* H
  282. ** S1
  283. :PROPERTIES:
  284. :A: [X]
  285. :END:
  286. ** S1
  287. :PROPERTIES:
  288. :A: [X]
  289. :END:"
  290. (let ((org-columns-default-format "%A{X}")) (org-columns))
  291. (get-char-property (point) 'org-columns-value-modified))))
  292. (should
  293. (equal
  294. "[1/2]"
  295. (org-test-with-temp-text
  296. "* H
  297. ** S1
  298. :PROPERTIES:
  299. :A: [ ]
  300. :END:
  301. ** S1
  302. :PROPERTIES:
  303. :A: [X]
  304. :END:"
  305. (let ((org-columns-default-format "%A{X/}")) (org-columns))
  306. (get-char-property (point) 'org-columns-value-modified))))
  307. (should
  308. (equal
  309. "[50%]"
  310. (org-test-with-temp-text
  311. "* H
  312. ** S1
  313. :PROPERTIES:
  314. :A: [ ]
  315. :END:
  316. ** S1
  317. :PROPERTIES:
  318. :A: [X]
  319. :END:"
  320. (let ((org-columns-default-format "%A{X%}")) (org-columns))
  321. (get-char-property (point) 'org-columns-value-modified))))
  322. ;; {X/} handles recursive summaries.
  323. (should
  324. (equal
  325. "[1/2]"
  326. (org-test-with-temp-text
  327. "* H
  328. ** S1
  329. :PROPERTIES:
  330. :A: [ ]
  331. :END:
  332. ** S2
  333. *** S21
  334. :PROPERTIES:
  335. :A: [X]
  336. :END:
  337. *** S22
  338. :PROPERTIES:
  339. :A: [X]
  340. :END:"
  341. (let ((org-columns-default-format "%A{X/}")) (org-columns))
  342. (get-char-property (point) 'org-columns-value-modified))))
  343. (should
  344. (equal
  345. "[1/2]"
  346. (org-test-with-temp-text
  347. "* H
  348. ** S1
  349. :PROPERTIES:
  350. :A: [X]
  351. :END:
  352. ** S2
  353. *** S21
  354. :PROPERTIES:
  355. :A: [ ]
  356. :END:
  357. *** S22
  358. :PROPERTIES:
  359. :A: [ ]
  360. :END:"
  361. (let ((org-columns-default-format "%A{X/}")) (org-columns))
  362. (get-char-property (point) 'org-columns-value-modified))))
  363. ;; {X%} handles recursive summaries.
  364. (should
  365. (equal
  366. "[50%]"
  367. (org-test-with-temp-text
  368. "* H
  369. ** S1
  370. :PROPERTIES:
  371. :A: [ ]
  372. :END:
  373. ** S2
  374. *** S21
  375. :PROPERTIES:
  376. :A: [X]
  377. :END:
  378. *** S22
  379. :PROPERTIES:
  380. :A: [X]
  381. :END:"
  382. (let ((org-columns-default-format "%A{X%}")) (org-columns))
  383. (get-char-property (point) 'org-columns-value-modified))))
  384. (should
  385. (equal
  386. "[50%]"
  387. (org-test-with-temp-text
  388. "* H
  389. ** S1
  390. :PROPERTIES:
  391. :A: [X]
  392. :END:
  393. ** S2
  394. *** S21
  395. :PROPERTIES:
  396. :A: [ ]
  397. :END:
  398. *** S22
  399. :PROPERTIES:
  400. :A: [ ]
  401. :END:"
  402. (let ((org-columns-default-format "%A{X%}")) (org-columns))
  403. (get-char-property (point) 'org-columns-value-modified))))
  404. ;; {min} is the smallest number in column, {max} the largest one.
  405. ;; {mean} is the arithmetic mean of numbers in column.
  406. (should
  407. (equal
  408. "42"
  409. (org-test-with-temp-text
  410. "* H
  411. ** S1
  412. :PROPERTIES:
  413. :A: 99
  414. :END:
  415. ** S1
  416. :PROPERTIES:
  417. :A: 42
  418. :END:"
  419. (let ((org-columns-default-format "%A{min}")) (org-columns))
  420. (get-char-property (point) 'org-columns-value-modified))))
  421. (should
  422. (equal
  423. "99"
  424. (org-test-with-temp-text
  425. "* H
  426. ** S1
  427. :PROPERTIES:
  428. :A: 99
  429. :END:
  430. ** S1
  431. :PROPERTIES:
  432. :A: 42
  433. :END:"
  434. (let ((org-columns-default-format "%A{max}")) (org-columns))
  435. (get-char-property (point) 'org-columns-value-modified))))
  436. (should
  437. (equal
  438. "51.0"
  439. (org-test-with-temp-text
  440. "* H
  441. ** S1
  442. :PROPERTIES:
  443. :A: 60
  444. :END:
  445. ** S1
  446. :PROPERTIES:
  447. :A: 42
  448. :END:"
  449. (let ((org-columns-default-format "%A{mean}")) (org-columns))
  450. (get-char-property (point) 'org-columns-value-modified))))
  451. ;; {:min}, {:max} and {:mean} apply to time values.
  452. (should
  453. (equal
  454. "1:20"
  455. (org-test-with-temp-text
  456. "* H
  457. ** S1
  458. :PROPERTIES:
  459. :A: 4:40
  460. :END:
  461. ** S1
  462. :PROPERTIES:
  463. :A: 1:20
  464. :END:"
  465. (let ((org-columns-default-format "%A{:min}")) (org-columns))
  466. (get-char-property (point) 'org-columns-value-modified))))
  467. (should
  468. (equal
  469. "4:40"
  470. (org-test-with-temp-text
  471. "* H
  472. ** S1
  473. :PROPERTIES:
  474. :A: 4:40
  475. :END:
  476. ** S1
  477. :PROPERTIES:
  478. :A: 1:20
  479. :END:"
  480. (let ((org-columns-default-format "%A{:max}")) (org-columns))
  481. (get-char-property (point) 'org-columns-value-modified))))
  482. (should
  483. (equal
  484. "3:00"
  485. (org-test-with-temp-text
  486. "* H
  487. ** S1
  488. :PROPERTIES:
  489. :A: 4:40
  490. :END:
  491. ** S1
  492. :PROPERTIES:
  493. :A: 1:20
  494. :END:"
  495. (let ((org-columns-default-format "%A{:mean}")) (org-columns))
  496. (get-char-property (point) 'org-columns-value-modified))))
  497. ;; {@min}, {@max} and {@mean} apply to ages.
  498. (should
  499. (equal
  500. "0min"
  501. (cl-letf (((symbol-function 'current-time)
  502. (lambda ()
  503. (apply #'encode-time
  504. (org-parse-time-string "<2014-03-04 Tue>")))))
  505. (org-test-with-temp-text
  506. "* H
  507. ** S1
  508. :PROPERTIES:
  509. :A: <2012-03-29 Thu>
  510. :END:
  511. ** S1
  512. :PROPERTIES:
  513. :A: <2014-03-04 Tue>
  514. :END:"
  515. (let ((org-columns-default-format "%A{@min}")) (org-columns))
  516. (get-char-property (point) 'org-columns-value-modified)))))
  517. (should
  518. (equal
  519. "2d"
  520. (cl-letf (((symbol-function 'current-time)
  521. (lambda ()
  522. (apply #'encode-time
  523. (org-parse-time-string "<2014-03-04 Tue>")))))
  524. (org-test-with-temp-text
  525. "* H
  526. ** S1
  527. :PROPERTIES:
  528. :A: <2014-03-03 Mon>
  529. :END:
  530. ** S1
  531. :PROPERTIES:
  532. :A: <2014-03-02 Sun>
  533. :END:"
  534. (let ((org-columns-default-format "%A{@max}")) (org-columns))
  535. (get-char-property (point) 'org-columns-value-modified)))))
  536. (should
  537. (equal
  538. "1d 12h"
  539. (cl-letf (((symbol-function 'current-time)
  540. (lambda ()
  541. (apply #'encode-time
  542. (org-parse-time-string "<2014-03-04 Tue>")))))
  543. (org-test-with-temp-text
  544. "* H
  545. ** S1
  546. :PROPERTIES:
  547. :A: <2014-03-03 Mon>
  548. :END:
  549. ** S1
  550. :PROPERTIES:
  551. :A: <2014-03-02 Sun>
  552. :END:"
  553. (let ((org-columns-default-format "%A{@mean}")) (org-columns))
  554. (get-char-property (point) 'org-columns-value-modified)))))
  555. ;; If a time value is expressed as a duration, return a duration.
  556. ;; If any of them follows H:MM:SS pattern, use it too. Also handle
  557. ;; combinations of duration and H:MM:SS patterns.
  558. (should
  559. (equal
  560. "3d 4:20"
  561. (org-test-with-temp-text
  562. "* H
  563. ** S1
  564. :PROPERTIES:
  565. :A: 3d 3h
  566. :END:
  567. ** S1
  568. :PROPERTIES:
  569. :A: 1:20
  570. :END:"
  571. (let ((org-columns-default-format "%A{:}")
  572. (org-duration-units '(("d" . 1440) ("h" . 60)))
  573. (org-duration-format '(("d" . nil) (special . h:mm))))
  574. (org-columns))
  575. (get-char-property (point) 'org-columns-value-modified))))
  576. (should
  577. (equal
  578. "6:00:10"
  579. (org-test-with-temp-text
  580. "* H
  581. ** S1
  582. :PROPERTIES:
  583. :A: 4:40:10
  584. :END:
  585. ** S1
  586. :PROPERTIES:
  587. :A: 1:20
  588. :END:"
  589. (let ((org-columns-default-format "%A{:}")) (org-columns))
  590. (get-char-property (point) 'org-columns-value-modified))))
  591. (should
  592. (equal
  593. "3d 4:20"
  594. (org-test-with-temp-text
  595. "* H
  596. ** S1
  597. :PROPERTIES:
  598. :A: 3d 3h
  599. :END:
  600. ** S1
  601. :PROPERTIES:
  602. :A: 0d 1:20
  603. :END:"
  604. (let ((org-columns-default-format "%A{:}")
  605. (org-duration-units '(("d" . 1440) ("h" . 60)))
  606. (org-duration-format '(("d" . nil) (special . h:mm))))
  607. (org-columns))
  608. (get-char-property (point) 'org-columns-value-modified))))
  609. ;; @min, @max and @mean also accept regular duration.
  610. (should
  611. (equal
  612. "1d 10h"
  613. (org-test-with-temp-text
  614. "* H
  615. ** S1
  616. :PROPERTIES:
  617. :A: 1d 10h 0min
  618. :END:
  619. ** S1
  620. :PROPERTIES:
  621. :A: 5d 3h
  622. :END:"
  623. (let ((org-columns-default-format "%A{@min}")) (org-columns))
  624. (get-char-property (point) 'org-columns-value-modified))))
  625. ;; {est+} gives a low-high estimate using mean and standard
  626. ;; deviation.
  627. (should
  628. (equal
  629. "3-17"
  630. (org-test-with-temp-text
  631. "* H
  632. ** S1
  633. :PROPERTIES:
  634. :A: 0-10
  635. :END:
  636. ** S1
  637. :PROPERTIES:
  638. :A: 0-10
  639. :END:"
  640. (let ((org-columns-default-format "%A{est+}")) (org-columns))
  641. (get-char-property (point) 'org-columns-value-modified))))
  642. ;; When using {est+} summary, a single number is understood as
  643. ;; a degenerate range.
  644. (should
  645. (equal
  646. "4-4"
  647. (org-test-with-temp-text
  648. "* H
  649. ** S1
  650. :PROPERTIES:
  651. :A: 4
  652. :END:
  653. "
  654. (let ((org-columns-default-format "%A{est+}")) (org-columns))
  655. (get-char-property (point) 'org-columns-value-modified))))
  656. ;; Allow custom summary types.
  657. (should
  658. (equal
  659. "1|2"
  660. (org-test-with-temp-text
  661. "* H
  662. ** S1
  663. :PROPERTIES:
  664. :A: 1
  665. :END:
  666. ** S1
  667. :PROPERTIES:
  668. :A: 2
  669. :END:"
  670. (let ((org-columns-summary-types
  671. '(("custom" . (lambda (s _) (mapconcat #'identity s "|")))))
  672. (org-columns-default-format "%A{custom}")) (org-columns))
  673. (get-char-property (point) 'org-columns-value-modified))))
  674. ;; Allow multiple summary types applied to the same property.
  675. (should
  676. (equal
  677. '("42" "99")
  678. (org-test-with-temp-text
  679. "* H
  680. ** S1
  681. :PROPERTIES:
  682. :A: 99
  683. :END:
  684. ** S1
  685. :PROPERTIES:
  686. :A: 42
  687. :END:"
  688. (let ((org-columns-default-format "%A{min} %A{max}")) (org-columns))
  689. (list (get-char-property (point) 'org-columns-value-modified)
  690. (get-char-property (1+ (point)) 'org-columns-value-modified)))))
  691. ;; Allow mixing both summarized and non-summarized columns for
  692. ;; a property. However, the first column takes precedence and
  693. ;; updates the value.
  694. (should
  695. (equal
  696. '("1000" "42")
  697. (org-test-with-temp-text
  698. "* H
  699. :PROPERTIES:
  700. :A: 1000
  701. :END:
  702. ** S1
  703. :PROPERTIES:
  704. :A: 99
  705. :END:
  706. ** S1
  707. :PROPERTIES:
  708. :A: 42
  709. :END:"
  710. (let ((org-columns-default-format "%A %A{min}")) (org-columns))
  711. (list (get-char-property (point) 'org-columns-value-modified)
  712. (get-char-property (1+ (point)) 'org-columns-value-modified)))))
  713. (should
  714. (equal
  715. '("42" "42")
  716. (org-test-with-temp-text
  717. "* H
  718. :PROPERTIES:
  719. :A: 1000
  720. :END:
  721. ** S1
  722. :PROPERTIES:
  723. :A: 99
  724. :END:
  725. ** S1
  726. :PROPERTIES:
  727. :A: 42
  728. :END:"
  729. (let ((org-columns-default-format "%A{min} %A")) (org-columns))
  730. (list (get-char-property (point) 'org-columns-value-modified)
  731. (get-char-property (1+ (point)) 'org-columns-value-modified))))))
  732. (ert-deftest test-org-colview/columns-new ()
  733. "Test `org-columns-new' specifications."
  734. ;; Insert new column at the left of the current one.
  735. (should
  736. (equal '("FOO" "ITEM")
  737. (org-test-with-temp-text "* H"
  738. (let ((org-columns-default-format "%ITEM")) (org-columns))
  739. (org-columns-new nil "FOO" "FOO" nil nil nil)
  740. (list (get-char-property (point) 'org-columns-key)
  741. (get-char-property (1+ (point)) 'org-columns-key)))))
  742. (should
  743. (equal '("ITEM" "FOO" "BAR")
  744. (org-test-with-temp-text "* H"
  745. (let ((org-columns-default-format "%ITEM %BAR")) (org-columns))
  746. (forward-char)
  747. (org-columns-new nil "FOO" "FOO" nil nil nil)
  748. (list (get-char-property (1- (point)) 'org-columns-key)
  749. (get-char-property (point) 'org-columns-key)
  750. (get-char-property (1+ (point)) 'org-columns-key)))))
  751. ;; Update #+COLUMNS keyword if needed.
  752. (should
  753. (equal "#+COLUMNS: %FOO %ITEM"
  754. (org-test-with-temp-text "#+COLUMNS: %ITEM\n<point>* H"
  755. (let ((org-columns-default-format "%ITEM")) (org-columns))
  756. (org-columns-new nil "FOO" "FOO" nil nil nil)
  757. (goto-char (point-min))
  758. (buffer-substring-no-properties (point) (line-end-position)))))
  759. (should
  760. (equal "#+COLUMNS: %ITEM %FOO %BAR"
  761. (org-test-with-temp-text "#+COLUMNS: %ITEM %BAR\n<point>* H"
  762. (let ((org-columns-default-format "%ITEM %BAR")) (org-columns))
  763. (forward-char)
  764. (org-columns-new nil "FOO" "FOO" nil nil nil)
  765. (goto-char (point-min))
  766. (buffer-substring-no-properties (point) (line-end-position)))))
  767. ;; Mind case when updating #+COLUMNS.
  768. (should
  769. (equal "#+COLUMNS: %ITEM %Foo %BAR"
  770. (org-test-with-temp-text "#+COLUMNS: %ITEM %BAR\n<point>* H"
  771. (let ((org-columns-default-format "%ITEM %BAR")) (org-columns))
  772. (forward-char)
  773. (org-columns-new nil "Foo" "Foo" nil nil nil)
  774. (goto-char (point-min))
  775. (buffer-substring-no-properties (point) (line-end-position)))))
  776. (should
  777. (equal "#+columns: %ITEM %Foo %BAR"
  778. (org-test-with-temp-text "#+columns: %ITEM %BAR\n<point>* H"
  779. (let ((org-columns-default-format "%ITEM %BAR")) (org-columns))
  780. (forward-char)
  781. (org-columns-new nil "Foo" "Foo" nil nil nil)
  782. (goto-char (point-min))
  783. (buffer-substring-no-properties (point) (line-end-position)))))
  784. ;; Also update :COLUMNS: properties.
  785. (should
  786. (equal "%FOO %ITEM"
  787. (org-test-with-temp-text "* H\n:PROPERTIES:\n:COLUMNS: %ITEM\n:END:"
  788. (let ((org-columns-default-format "%ITEM")) (org-columns))
  789. (org-columns-new nil "FOO" "FOO" nil nil nil)
  790. (org-entry-get nil "COLUMNS"))))
  791. ;; If no keyword nor any property is available, insert one.
  792. (should
  793. (string-match-p (regexp-quote "#+COLUMNS: %FOO %ITEM")
  794. (org-test-with-temp-text "* H"
  795. (let ((org-columns-default-format "%ITEM")) (org-columns))
  796. (org-columns-new nil "FOO" "FOO" nil nil nil)
  797. (buffer-string)))))
  798. (ert-deftest test-org-colview/columns-update ()
  799. "Test `org-columns-update' specifications."
  800. ;; Update display.
  801. (should
  802. (equal
  803. "12 |"
  804. (org-test-with-temp-text
  805. "* H
  806. :PROPERTIES:
  807. :A: 1
  808. :END:
  809. "
  810. (let ((org-columns-default-format "%5A")) (org-columns))
  811. (search-forward "1")
  812. (insert "2")
  813. (org-columns-update "A")
  814. (get-char-property (point-min) 'display))))
  815. ;; Update is case-insensitive.
  816. (should
  817. (equal
  818. "12 |"
  819. (org-test-with-temp-text
  820. "* H
  821. :PROPERTIES:
  822. :A: 1
  823. :END:
  824. "
  825. (let ((org-columns-default-format "%5A")) (org-columns))
  826. (search-forward "1")
  827. (insert "2")
  828. (org-columns-update "a")
  829. (get-char-property (point-min) 'display))))
  830. ;; Update stored values.
  831. (should
  832. (equal
  833. '("12" "12")
  834. (org-test-with-temp-text
  835. "* H
  836. :PROPERTIES:
  837. :A: 1
  838. :END:
  839. "
  840. (let ((org-columns-default-format "%5A")) (org-columns))
  841. (search-forward "1")
  842. (insert "2")
  843. (org-columns-update "A")
  844. (list (get-char-property (point-min) 'org-columns-value)
  845. (get-char-property (point-min) 'org-columns-value-modified)))))
  846. ;; When multiple columns are using the same property, value is
  847. ;; updated according to the specifications of the first one.
  848. (should
  849. (equal
  850. "2"
  851. (org-test-with-temp-text
  852. "* H
  853. :PROPERTIES:
  854. :A: 1
  855. :END:
  856. ** S
  857. :PROPERTIES:
  858. :A: 2
  859. :END:"
  860. (let ((org-columns-default-format "%A{min} %A")) (org-columns))
  861. (org-columns-update "A")
  862. (org-entry-get nil "A"))))
  863. (should
  864. (equal
  865. "1"
  866. (org-test-with-temp-text
  867. "* H
  868. :PROPERTIES:
  869. :A: 1
  870. :END:
  871. ** S
  872. :PROPERTIES:
  873. :A: 2
  874. :END:"
  875. (let ((org-columns-default-format "%A %A{min}")) (org-columns))
  876. (org-columns-update "A")
  877. (org-entry-get nil "A"))))
  878. ;; Ensure modifications propagate in upper levels even when multiple
  879. ;; summary types apply to the same property.
  880. (should
  881. (equal
  882. '("1" "22")
  883. (org-test-with-temp-text
  884. "* H
  885. ** S1
  886. :PROPERTIES:
  887. :A: 1
  888. :END:
  889. ** S2
  890. :PROPERTIES:
  891. :A: <point>2
  892. :END:"
  893. (save-excursion
  894. (goto-char (point-min))
  895. (let ((org-columns-default-format "%A{min} %A{max}")) (org-columns)))
  896. (insert "2")
  897. (org-columns-update "A")
  898. (list (get-char-property 1 'org-columns-value)
  899. (get-char-property 2 'org-columns-value-modified)))))
  900. ;; Ensure additional processing is done (e.g., ellipses, special
  901. ;; keywords fontification...).
  902. (should
  903. (equal
  904. "ve.. |"
  905. (org-test-with-temp-text
  906. "* H
  907. :PROPERTIES:
  908. :A: text
  909. :END:
  910. "
  911. (let ((org-columns-default-format "%4A")
  912. (org-columns-ellipses ".."))
  913. (org-columns))
  914. (search-forward ":A: ")
  915. (insert "very long ")
  916. (org-columns-update "A")
  917. (get-char-property (point-min) 'display))))
  918. ;; Values obtained from inline tasks are at the same level as those
  919. ;; obtained from children of the current node.
  920. (when (featurep 'org-inlinetask)
  921. (should
  922. (equal
  923. "2"
  924. (org-test-with-temp-text
  925. "* H
  926. *************** Inline task
  927. :PROPERTIES:
  928. :A: 2
  929. :END:
  930. *************** END
  931. ** Children
  932. :PROPERTIES:
  933. :A: 3
  934. :END:
  935. "
  936. (let ((org-columns-default-format "%A{min}")
  937. (org-columns-ellipses "..")
  938. (org-inlinetask-min-level 15))
  939. (org-columns))
  940. (get-char-property (point-min) 'org-columns-value)))))
  941. ;; Handle `org-columns-modify-value-for-display-function', even with
  942. ;; multiple titles for the same property.
  943. (should
  944. (equal '("foo" "bar")
  945. (org-test-with-temp-text "* H"
  946. (let ((org-columns-default-format "%ITEM %ITEM(Name)")
  947. (org-columns-modify-value-for-display-function
  948. (lambda (title value)
  949. (pcase title ("ITEM" "foo") ("Name" "bar") (_ "baz")))))
  950. (org-columns))
  951. (list (get-char-property 1 'org-columns-value-modified)
  952. (get-char-property 2 'org-columns-value-modified))))))
  953. (ert-deftest test-org-colview/columns-move-left ()
  954. "Test `org-columns-move-left' specifications."
  955. ;; Error when trying to move the left-most column.
  956. (should-error
  957. (org-test-with-temp-text "* H"
  958. (let ((org-columns-default-format "%ITEM")) (org-columns))
  959. (org-columns-move-left)))
  960. ;; Otherwise, move column to left and update display.
  961. (should
  962. (equal '("2" "1")
  963. (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:B: 2\n:END:"
  964. (let ((org-columns-default-format "%A %B")) (org-columns))
  965. (forward-char)
  966. (org-columns-move-left)
  967. (list (get-char-property (point) 'org-columns-value)
  968. (get-char-property (1+ (point)) 'org-columns-value)))))
  969. ;; Handle multiple columns with the same property.
  970. (should
  971. (equal '("2" "1")
  972. (org-test-with-temp-text
  973. "* H
  974. ** S1
  975. :PROPERTIES:
  976. :A: 1
  977. :END:
  978. ** S1
  979. :PROPERTIES:
  980. :A: 2
  981. :END:"
  982. (let ((org-columns-default-format "%ITEM %A{min} %A{max}"))
  983. (org-columns))
  984. (forward-char 2)
  985. (org-columns-move-left)
  986. (list (get-char-property (point) 'org-columns-value)
  987. (get-char-property (1+ (point)) 'org-columns-value)))))
  988. ;; Special case: do not update values even if move entails changing
  989. ;; them.
  990. (should
  991. (equal "1"
  992. (org-test-with-temp-text
  993. "* H
  994. :PROPERTIES:
  995. :A: 1
  996. :END:
  997. ** S1
  998. :PROPERTIES:
  999. :A: 99
  1000. :END:"
  1001. (let ((org-columns-default-format "%A %A{max}"))
  1002. (org-columns))
  1003. (forward-char)
  1004. (org-columns-move-left)
  1005. ;; Since the first column matching a given property
  1006. ;; determines how a value is computed, the following
  1007. ;; should return "99" instead. However, this behavior is
  1008. ;; in practice surprising so we just ignore the value
  1009. ;; change. It can be computed later.
  1010. (org-entry-get (point) "A")))))
  1011. (ert-deftest test-org-colview/columns-move-right ()
  1012. "Test `org-columns-move-right' specifications."
  1013. ;; Error when trying to move the right-most column.
  1014. (should-error
  1015. (org-test-with-temp-text "* H"
  1016. (let ((org-columns-default-format "%ITEM")) (org-columns))
  1017. (org-columns-move-right)))
  1018. ;; Otherwise, move column to left and update display.
  1019. (should
  1020. (equal '("2" "1")
  1021. (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:B: 2\n:END:"
  1022. (let ((org-columns-default-format "%A %B")) (org-columns))
  1023. (org-columns-move-right)
  1024. (list (get-char-property (1- (point)) 'org-columns-value)
  1025. (get-char-property (point) 'org-columns-value)))))
  1026. ;; Handle multiple columns with the same property.
  1027. (should
  1028. (equal '("2" "1")
  1029. (org-test-with-temp-text
  1030. "* H
  1031. ** S1
  1032. :PROPERTIES:
  1033. :A: 1
  1034. :END:
  1035. ** S1
  1036. :PROPERTIES:
  1037. :A: 2
  1038. :END:"
  1039. (let ((org-columns-default-format "%ITEM %A{min} %A{max}"))
  1040. (org-columns))
  1041. (forward-char)
  1042. (org-columns-move-right)
  1043. (list (get-char-property (1- (point)) 'org-columns-value)
  1044. (get-char-property (point) 'org-columns-value)))))
  1045. ;; Special case: do not update values even if move entails changing
  1046. ;; them.
  1047. (should
  1048. (equal "1"
  1049. (org-test-with-temp-text
  1050. "* H
  1051. :PROPERTIES:
  1052. :A: 1
  1053. :END:
  1054. ** S1
  1055. :PROPERTIES:
  1056. :A: 99
  1057. :END:"
  1058. (let ((org-columns-default-format "%A %A{max}"))
  1059. (org-columns))
  1060. (org-columns-move-right)
  1061. ;; See `test-org-colview/columns-move-left' for an
  1062. ;; explanation.
  1063. (org-entry-get (point) "A")))))
  1064. (ert-deftest test-org-colview/columns-next-allowed-value ()
  1065. "Test `org-columns-next-allowed-value' specifications."
  1066. ;; Cannot shift "ITEM" property.
  1067. (should-error
  1068. (org-test-with-temp-text "* H"
  1069. (let ((org-columns-default-format "%ITEM")) (org-columns))
  1070. (org-columns-next-allowed-value)))
  1071. ;; Throw an error when allowed values are not defined.
  1072. (should-error
  1073. (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:END:"
  1074. (let ((org-columns-default-format "%A")) (org-columns))
  1075. (org-columns-next-allowed-value)))
  1076. ;; Throw an error when there's only one value to select.
  1077. (should-error
  1078. (org-test-with-temp-text "* H\n:PROPERTIES:\n:A: 1\n:A_ALL: 1\n:END:"
  1079. (let ((org-columns-default-format "%A")) (org-columns))
  1080. (org-columns-next-allowed-value)))
  1081. ;; By default select the next allowed value. Where there is no more
  1082. ;; value, start again from first possible one.
  1083. (should
  1084. (equal "2"
  1085. (org-test-with-temp-text
  1086. "* H\n:PROPERTIES:\n:A: 1\n:A_ALL: 1 2 3\n:END:"
  1087. (let ((org-columns-default-format "%A")) (org-columns))
  1088. (org-columns-next-allowed-value)
  1089. (org-entry-get (point) "A"))))
  1090. (should
  1091. (equal "3"
  1092. (org-test-with-temp-text
  1093. "* H\n:PROPERTIES:\n:A: 2\n:A_ALL: 1 2 3\n:END:"
  1094. (let ((org-columns-default-format "%A")) (org-columns))
  1095. (org-columns-next-allowed-value)
  1096. (org-entry-get (point) "A"))))
  1097. (should
  1098. (equal "1"
  1099. (org-test-with-temp-text
  1100. "* H\n:PROPERTIES:\n:A: 3\n:A_ALL: 1 2 3\n:END:"
  1101. (let ((org-columns-default-format "%A")) (org-columns))
  1102. (org-columns-next-allowed-value)
  1103. (org-entry-get (point) "A"))))
  1104. ;; PREVIOUS argument moves backward.
  1105. (should
  1106. (equal "1"
  1107. (org-test-with-temp-text
  1108. "* H\n:PROPERTIES:\n:A: 2\n:A_ALL: 1 2 3\n:END:"
  1109. (let ((org-columns-default-format "%A")) (org-columns))
  1110. (org-columns-next-allowed-value 'previous)
  1111. (org-entry-get (point) "A"))))
  1112. (should
  1113. (equal "2"
  1114. (org-test-with-temp-text
  1115. "* H\n:PROPERTIES:\n:A: 3\n:A_ALL: 1 2 3\n:END:"
  1116. (let ((org-columns-default-format "%A")) (org-columns))
  1117. (org-columns-next-allowed-value 'previous)
  1118. (org-entry-get (point) "A"))))
  1119. (should
  1120. (equal "3"
  1121. (org-test-with-temp-text
  1122. "* H\n:PROPERTIES:\n:A: 1\n:A_ALL: 1 2 3\n:END:"
  1123. (let ((org-columns-default-format "%A")) (org-columns))
  1124. (org-columns-next-allowed-value 'previous)
  1125. (org-entry-get (point) "A"))))
  1126. ;; Select Nth element with optional argument NTH.
  1127. (should
  1128. (equal "1"
  1129. (org-test-with-temp-text
  1130. "* H\n:PROPERTIES:\n:A: 2\n:A_ALL: 1 2 3\n:END:"
  1131. (let ((org-columns-default-format "%A")) (org-columns))
  1132. (org-columns-next-allowed-value nil 1)
  1133. (org-entry-get (point) "A"))))
  1134. ;; If NTH is negative, go backwards, 0 being the last one and -1 the
  1135. ;; penultimate.
  1136. (should
  1137. (equal "3"
  1138. (org-test-with-temp-text
  1139. "* H\n:PROPERTIES:\n:A: 2\n:A_ALL: 1 2 3\n:END:"
  1140. (let ((org-columns-default-format "%A")) (org-columns))
  1141. (org-columns-next-allowed-value nil 0)
  1142. (org-entry-get (point) "A"))))
  1143. (should
  1144. (equal "2"
  1145. (org-test-with-temp-text
  1146. "* H\n:PROPERTIES:\n:A: 2\n:A_ALL: 1 2 3\n:END:"
  1147. (let ((org-columns-default-format "%A")) (org-columns))
  1148. (org-columns-next-allowed-value nil -1)
  1149. (org-entry-get (point) "A"))))
  1150. ;; Throw an error if NTH is greater than the number of allowed
  1151. ;; values.
  1152. (should-error
  1153. (org-test-with-temp-text
  1154. "* H\n:PROPERTIES:\n:A: 2\n:A_ALL: 1 2 3\n:END:"
  1155. (let ((org-columns-default-format "%A")) (org-columns))
  1156. (org-columns-next-allowed-value nil 4)
  1157. (org-entry-get (point) "A")))
  1158. ;; Pathological case: when shifting the value alters the current
  1159. ;; heading, make sure all columns are still at their correct
  1160. ;; location.
  1161. (should
  1162. (equal '("H" "" "" "" "TODO")
  1163. (let ((org-todo-keywords '((sequence "TODO" "DONE"))))
  1164. (org-test-with-temp-text "* H"
  1165. (let ((org-columns-default-format "%ITEM %A %B %C %TODO"))
  1166. (org-columns)
  1167. (forward-char 4)
  1168. (org-columns-next-allowed-value)
  1169. (list (get-char-property (- (point) 4) 'org-columns-value)
  1170. (get-char-property (- (point) 3) 'org-columns-value)
  1171. (get-char-property (- (point) 2) 'org-columns-value)
  1172. (get-char-property (- (point) 1) 'org-columns-value)
  1173. (get-char-property (point) 'org-columns-value)))))))
  1174. (should
  1175. (equal '("H" "VERYLONGTODO")
  1176. (let ((org-todo-keywords '((sequence "TODO" "VERYLONGTODO"))))
  1177. (org-test-with-temp-text "* TODO H"
  1178. (let ((org-columns-default-format "%ITEM %TODO"))
  1179. (org-columns)
  1180. (forward-char)
  1181. (org-columns-next-allowed-value)
  1182. (list (get-char-property (- (point) 1) 'org-columns-value)
  1183. (get-char-property (point) 'org-columns-value))))))))
  1184. ;;; Dynamic block
  1185. (ert-deftest test-org-colview/dblock ()
  1186. "Test the column view table."
  1187. (should
  1188. (equal
  1189. "#+BEGIN: columnview
  1190. | ITEM |
  1191. |------|
  1192. | H |
  1193. #+END:"
  1194. (org-test-with-temp-text
  1195. "* H\n<point>#+BEGIN: columnview\n#+END:"
  1196. (let ((org-columns-default-format "%ITEM")) (org-update-dblock))
  1197. (buffer-substring-no-properties (point) (point-max)))))
  1198. (should
  1199. (equal
  1200. "#+BEGIN: columnview
  1201. | ITEM | A |
  1202. |------+---|
  1203. | H | 1 |
  1204. #+END:"
  1205. (org-test-with-temp-text
  1206. "* H\n:PROPERTIES:\n:A: 1\n:END:\n<point>#+BEGIN: columnview\n#+END:"
  1207. (let ((org-columns-default-format "%ITEM %A")) (org-update-dblock))
  1208. (buffer-substring-no-properties (point) (point-max)))))
  1209. ;; Properties are case insensitive.
  1210. (should
  1211. (equal
  1212. "#+BEGIN: columnview
  1213. | a |
  1214. |---|
  1215. | 1 |
  1216. #+END:"
  1217. (org-test-with-temp-text
  1218. "* H\n:PROPERTIES:\n:A: 1\n:END:\n<point>#+BEGIN: columnview\n#+END:"
  1219. (let ((org-columns-default-format "%a")) (org-update-dblock))
  1220. (buffer-substring-no-properties (point) (point-max)))))
  1221. ;; Test titles given to columns.
  1222. (should
  1223. (equal
  1224. "#+BEGIN: columnview
  1225. | Name | Prop |
  1226. |------+------|
  1227. | H | 1 |
  1228. #+END:"
  1229. (org-test-with-temp-text
  1230. "* H\n:PROPERTIES:\n:A: 1\n:END:\n<point>#+BEGIN: columnview\n#+END:"
  1231. (let ((org-columns-default-format "%ITEM(Name) %A(Prop)"))
  1232. (org-update-dblock))
  1233. (buffer-substring-no-properties (point) (point-max)))))
  1234. ;; Test `:id' parameter
  1235. (should
  1236. (equal
  1237. "#+BEGIN: columnview :id local
  1238. | ITEM |
  1239. |------|
  1240. | H1 |
  1241. | H1.1 |
  1242. #+END:
  1243. "
  1244. (org-test-with-temp-text
  1245. "* H1\n<point>#+BEGIN: columnview :id local\n#+END:\n** H1.1\n* H2"
  1246. (let ((org-columns-default-format "%ITEM")) (org-update-dblock))
  1247. (buffer-substring-no-properties (point) (outline-next-heading)))))
  1248. (should
  1249. (equal
  1250. "#+BEGIN: columnview :id global
  1251. | ITEM |
  1252. |------|
  1253. | H1 |
  1254. | H1.1 |
  1255. | H2 |
  1256. #+END:
  1257. "
  1258. (org-test-with-temp-text
  1259. "\n* H1\n<point>#+BEGIN: columnview :id global\n#+END:\n** H1.1\n* H2"
  1260. (let ((org-columns-default-format "%ITEM")) (org-update-dblock))
  1261. (buffer-substring-no-properties (point) (outline-next-heading)))))
  1262. ;; Test `:hlines' parameter.
  1263. (should
  1264. (equal
  1265. "#+BEGIN: columnview :hlines t :id global
  1266. | ITEM |
  1267. |------|
  1268. | H |
  1269. |------|
  1270. | H2 |
  1271. |------|
  1272. | H2.1 |
  1273. #+END:\n"
  1274. (org-test-with-temp-text
  1275. "
  1276. * H
  1277. <point>#+BEGIN: columnview :hlines t :id global
  1278. #+END:
  1279. * H2
  1280. ** H2.1"
  1281. (let ((org-columns-default-format "%ITEM")) (org-update-dblock))
  1282. (buffer-substring-no-properties (point) (outline-next-heading)))))
  1283. (should
  1284. (equal
  1285. "#+BEGIN: columnview :hlines 1 :id global
  1286. | ITEM |
  1287. |------|
  1288. | H |
  1289. |------|
  1290. | H2 |
  1291. | H2.1 |
  1292. #+END:\n"
  1293. (org-test-with-temp-text
  1294. "
  1295. * H
  1296. <point>#+BEGIN: columnview :hlines 1 :id global
  1297. #+END:
  1298. * H2
  1299. ** H2.1"
  1300. (let ((org-columns-default-format "%ITEM")) (org-update-dblock))
  1301. (buffer-substring-no-properties (point) (outline-next-heading)))))
  1302. (should
  1303. (equal
  1304. "#+BEGIN: columnview :hlines 1 :id \"id\"
  1305. | ITEM |
  1306. |------|
  1307. | H2 |
  1308. | H2.1 |
  1309. #+END:
  1310. "
  1311. (org-test-with-temp-text
  1312. "
  1313. * H
  1314. <point>#+BEGIN: columnview :hlines 1 :id \"id\"
  1315. #+END:
  1316. * H2
  1317. :PROPERTIES:
  1318. :ID: id
  1319. :END:
  1320. ** H2.1"
  1321. (let ((org-columns-default-format "%ITEM")) (org-update-dblock))
  1322. (buffer-substring-no-properties (point) (outline-next-heading)))))
  1323. (should
  1324. (equal
  1325. "#+BEGIN: columnview :hlines 1 :id id
  1326. | ITEM |
  1327. |------|
  1328. | H2 |
  1329. | H2.1 |
  1330. #+END:
  1331. "
  1332. (org-test-with-temp-text
  1333. "
  1334. * H
  1335. <point>#+BEGIN: columnview :hlines 1 :id id
  1336. #+END:
  1337. * H2
  1338. :PROPERTIES:
  1339. :ID: id
  1340. :END:
  1341. ** H2.1"
  1342. (let ((org-columns-default-format "%ITEM")) (org-update-dblock))
  1343. (buffer-substring-no-properties (point) (outline-next-heading)))))
  1344. ;; Test `:indent' parameter.
  1345. (should
  1346. (equal
  1347. "#+BEGIN: columnview :indent t
  1348. | ITEM |
  1349. |----------|
  1350. | H1 |
  1351. | \\_ H1.1 |
  1352. #+END:
  1353. "
  1354. (org-test-with-temp-text
  1355. "* H1\n<point>#+BEGIN: columnview :indent t\n#+END:\n** H1.1"
  1356. (let ((org-columns-default-format "%ITEM")) (org-update-dblock))
  1357. (buffer-substring-no-properties (point) (outline-next-heading)))))
  1358. (should
  1359. (equal
  1360. "#+BEGIN: columnview :indent t
  1361. | Prop | Name |
  1362. |------+----------|
  1363. | | H1 |
  1364. | | \\_ H1.1 |
  1365. #+END:
  1366. "
  1367. (org-test-with-temp-text
  1368. "* H1\n<point>#+BEGIN: columnview :indent t\n#+END:\n** H1.1"
  1369. (let ((org-columns-default-format "%A(Prop) %ITEM(Name)"))
  1370. (org-update-dblock))
  1371. (buffer-substring-no-properties (point) (outline-next-heading)))))
  1372. ;; Test `:vlines' parameter.
  1373. (should
  1374. (equal
  1375. "#+BEGIN: columnview :vlines t
  1376. | | ITEM | A |
  1377. |---+------+----|
  1378. | | H | 1 |
  1379. | / | <> | <> |
  1380. #+END:"
  1381. (org-test-with-temp-text
  1382. "* H\n:PROPERTIES:\n:A: 1\n:END:\n<point>#+BEGIN: columnview :vlines t\n#+END:"
  1383. (let ((org-columns-default-format "%ITEM %A")) (org-update-dblock))
  1384. (buffer-substring-no-properties (point) (point-max)))))
  1385. ;; Test `:skip-empty-rows' parameter.
  1386. (should
  1387. (equal
  1388. "#+BEGIN: columnview :skip-empty-rows t
  1389. | ITEM | A |
  1390. |------+---|
  1391. | H1.1 | 1 |
  1392. #+END:
  1393. "
  1394. (org-test-with-temp-text
  1395. "
  1396. * H1
  1397. <point>#+BEGIN: columnview :skip-empty-rows t
  1398. #+END:
  1399. ** H1.1
  1400. :PROPERTIES:
  1401. :A: 1
  1402. :END:"
  1403. (let ((org-columns-default-format "%ITEM %A")) (org-update-dblock))
  1404. (buffer-substring-no-properties (point) (outline-next-heading)))))
  1405. ;; Test `:format' parameter.
  1406. (should
  1407. (equal
  1408. "#+BEGIN: columnview :format \"%ITEM(Name)\"
  1409. | Name |
  1410. |------|
  1411. | H |
  1412. #+END:"
  1413. (org-test-with-temp-text
  1414. "* H\n<point>#+BEGIN: columnview :format \"%ITEM(Name)\"\n#+END:"
  1415. (let ((org-columns-default-format "%ITEM")) (org-update-dblock))
  1416. (buffer-substring-no-properties (point) (point-max)))))
  1417. ;; Test `:width' parameter
  1418. (should
  1419. (equal
  1420. "#+BEGIN: columnview :width t
  1421. | ITEM | A |
  1422. |------------+---|
  1423. | H | |
  1424. | <10> | |
  1425. #+END:"
  1426. (org-test-with-temp-text
  1427. "* H\n<point>#+BEGIN: columnview :width t\n#+END:"
  1428. (let ((org-columns-default-format "%10ITEM %A")) (org-update-dblock))
  1429. (buffer-substring-no-properties (point) (point-max)))))
  1430. ;; When inserting ITEM values, make sure to clean sensitive
  1431. ;; contents, like unique targets or forbidden inline src-blocks.
  1432. (should
  1433. (equal
  1434. "#+BEGIN: columnview
  1435. | ITEM |
  1436. |------|
  1437. | H 1 |
  1438. #+END:"
  1439. (org-test-with-temp-text
  1440. "* H <<target>> 1\n<point>#+BEGIN: columnview\n#+END:"
  1441. (let ((org-columns-default-format "%ITEM")) (org-update-dblock))
  1442. (buffer-substring-no-properties (point) (point-max)))))
  1443. (should
  1444. (equal
  1445. "#+BEGIN: columnview
  1446. | ITEM |
  1447. |------|
  1448. | H 1 |
  1449. #+END:"
  1450. (org-test-with-temp-text
  1451. "* H src_emacs-lisp{(+ 1 1)} 1\n<point>#+BEGIN: columnview\n#+END:"
  1452. (let ((org-columns-default-format "%ITEM")) (org-update-dblock))
  1453. (buffer-substring-no-properties (point) (point-max))))))
  1454. (provide 'test-org-colview)
  1455. ;;; test-org-colview.el ends here