| 1 | ;;;; testcover-ses.el -- Example use of `testcover' to test "SES" |
| 2 | |
| 3 | ;; Copyright (C) 2002-2012 Free Software Foundation, Inc. |
| 4 | |
| 5 | ;; Author: Jonathan Yavner <jyavner@engineer.com> |
| 6 | ;; Maintainer: Jonathan Yavner <jyavner@engineer.com> |
| 7 | ;; Keywords: spreadsheet lisp utility |
| 8 | ;; Package: testcover |
| 9 | |
| 10 | ;; GNU Emacs is free software: you can redistribute it and/or modify |
| 11 | ;; it under the terms of the GNU General Public License as published by |
| 12 | ;; the Free Software Foundation, either version 3 of the License, or |
| 13 | ;; (at your option) any later version. |
| 14 | |
| 15 | ;; GNU Emacs is distributed in the hope that it will be useful, |
| 16 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 17 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 18 | ;; GNU General Public License for more details. |
| 19 | |
| 20 | ;; You should have received a copy of the GNU General Public License |
| 21 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. |
| 22 | |
| 23 | (require 'testcover) |
| 24 | |
| 25 | (defvar ses-initial-global-parameters) |
| 26 | (defvar ses-mode-map) |
| 27 | |
| 28 | (declare-function ses-set-curcell "ses") |
| 29 | (declare-function ses-update-cells "ses") |
| 30 | (declare-function ses-load "ses") |
| 31 | (declare-function ses-vector-delete "ses") |
| 32 | (declare-function ses-create-header-string "ses") |
| 33 | (declare-function ses-read-cell "ses") |
| 34 | (declare-function ses-read-symbol "ses") |
| 35 | (declare-function ses-command-hook "ses") |
| 36 | (declare-function ses-jump "ses") |
| 37 | |
| 38 | |
| 39 | ;;;Here are some macros that exercise SES. Set `pause' to t if you want the |
| 40 | ;;;macros to pause after each step. |
| 41 | (let* ((pause nil) |
| 42 | (x (if pause "\18q" "")) |
| 43 | (y "\18\ 6ses-test.ses\r\e<")) |
| 44 | ;;Fiddle with the existing spreadsheet |
| 45 | (fset 'ses-exercise-example |
| 46 | (concat "\18\ 6" data-directory "ses-example.ses\r\e<" |
| 47 | x "\1510\ e" |
| 48 | x "\v" |
| 49 | x "\1f" |
| 50 | x "\10\10\ 6pses-center\r" |
| 51 | x "\ 6p\r" |
| 52 | x "\15\10\t\t" |
| 53 | x "\r\ 2 A9 B9\r" |
| 54 | x "\15\ e\ 2\ 2\ 2" |
| 55 | x "\r\ 1\v2\r" |
| 56 | x "\ e\ e\ 6" |
| 57 | x "50\r" |
| 58 | x "\154\1f" |
| 59 | x "\ 3\e\f" |
| 60 | x "\1f" |
| 61 | x "(+ \18o\ e\ e\ 6\0\ 6\ 6" |
| 62 | x "\15-1\18o\ 3\12 \ 3\13\r\ 2" |
| 63 | x "\1f" |
| 64 | x)) |
| 65 | ;;Create a new spreadsheet |
| 66 | (fset 'ses-exercise-new |
| 67 | (concat y |
| 68 | x "\ 3\10\"%.8g\"\r" |
| 69 | x "2\r" |
| 70 | x "\ f" |
| 71 | x "\10" |
| 72 | x "\152\ f" |
| 73 | x "\"Header\r" |
| 74 | x "(sqrt 1\r\ 2" |
| 75 | x "pses-center\r\ 6" |
| 76 | x "\t" |
| 77 | x "\10(+ A2 A3\r" |
| 78 | x "\ 6(* B2 A3\r" |
| 79 | x "\152\ 3\e\b" |
| 80 | x "\r\7f\7f\7fB3\r" |
| 81 | x "\18\13" |
| 82 | x)) |
| 83 | ;;Basic cell display |
| 84 | (fset 'ses-exercise-display |
| 85 | (concat y "\e:(revert-buffer t t)\r" |
| 86 | x "\ 5" |
| 87 | x "\"Very long\r\ 2" |
| 88 | x "w3\r" |
| 89 | x "w3\r" |
| 90 | x "(/ 1 0\r\ 2" |
| 91 | x "234567\r\ 2" |
| 92 | x "\155w" |
| 93 | x "\t1\r\ 2" |
| 94 | x "\ 2\ 3\ 3" |
| 95 | x "\ 6234567\r\ 2" |
| 96 | x "\t\ 4\ 2" |
| 97 | x "\ 2\ 3\ 3" |
| 98 | x "345678\r\ 2" |
| 99 | x "\153w" |
| 100 | x "\0\e>" |
| 101 | x "\ 3\ 3" |
| 102 | x "\18\18" |
| 103 | x "\ 5" |
| 104 | x "\18\18\ 1" |
| 105 | x "\ 5" |
| 106 | x "\ 6\ 5" |
| 107 | x "\ 3\ 3" |
| 108 | x "1\r\ 2" |
| 109 | x "\ 3\ 3\ 6" |
| 110 | x "\ 5" |
| 111 | x "\ 2\ 2\ 2\"1234567-1234567-1234567\r\ 2" |
| 112 | x "123\r\ 2" |
| 113 | x "\152\ f" |
| 114 | x "\ e\"1234567-1234567-1234567\r\ 2" |
| 115 | x "123\r\ 2" |
| 116 | x "\ 6\ 6w8\r" |
| 117 | x "\ 2\ 2\"1234567\r" |
| 118 | x "\ e\ 2w5\r" |
| 119 | x)) |
| 120 | ;;Cell formulas |
| 121 | (fset 'ses-exercise-formulas |
| 122 | (concat y "\e:(revert-buffer t t)\r" |
| 123 | x "\t\t" |
| 124 | x "\t" |
| 125 | x "(* B1 B2 D1\r\ 2" |
| 126 | x "(* B2 B3\r\ 2" |
| 127 | x "\ e(apply '+ (ses-range B1 B3)\r\ 2" |
| 128 | x "(apply 'ses+ (ses-range B1 B3)\r\ 2" |
| 129 | x "\ e(apply 'ses+ (ses-range A2 A3)\r\ 2" |
| 130 | x "\ e(mapconcat'number-to-string(ses-range B2 B4) \"-\"\r\ 2" |
| 131 | x "\ 2(apply 'concat (reverse (ses-range A3 D3))\r\ 2" |
| 132 | x "\ 2(* (+ A2 A3) (ses+ B2 B3)\r\ 2" |
| 133 | x "\ e" |
| 134 | x "\152\ f" |
| 135 | x "\155\t" |
| 136 | x "\10(apply 'ses+ (ses-range E1 E2)\r\ 2" |
| 137 | x "\10(apply 'ses+ (ses-range A5 B5)\r\ 2" |
| 138 | x "\10(apply 'ses+ (ses-range E1 F1)\r\ 2" |
| 139 | x "\10(apply 'ses+ (ses-range D1 E1)\r\ 2" |
| 140 | x "\t" |
| 141 | x "(ses-average (ses-range A2 A5)\r\ 2" |
| 142 | x "\ e(apply 'ses+ (ses-range A5 A6)\r\ 2" |
| 143 | x "\ 2\ 2\ek" |
| 144 | x "\ e\ e\v" |
| 145 | x "\10\10\10\ f" |
| 146 | x "\ e\152\ f" |
| 147 | x "\10\153\v" |
| 148 | x "\ 2\ 2\ 2\eo" |
| 149 | x "\ 6\152\eo" |
| 150 | x "\ 2\153\ek" |
| 151 | x "\ 6(ses-average (ses-range B3 E3)\r\ 2" |
| 152 | x "\ 2\ek" |
| 153 | x "\ e\1012345678\r\ 2" |
| 154 | x)) |
| 155 | ;;Recalculating and reconstructing |
| 156 | (fset 'ses-exercise-recalc |
| 157 | (concat y "\e:(revert-buffer t t)\r" |
| 158 | x "\ 3\e\f" |
| 159 | x "\t\t" |
| 160 | x "\ 3\ 3" |
| 161 | x "(/ 1 0\r\ 2" |
| 162 | x "\ 3\ 3" |
| 163 | x "\n" |
| 164 | x "\ 3\ 3" |
| 165 | x "\ 3\10\"%.6g\"\r" |
| 166 | x "\ 3\e\f" |
| 167 | x "\e>\18nw\ 6\ 6\ 6" |
| 168 | x "\0\e>\exdelete-region\r" |
| 169 | x "\ 3\e\f" |
| 170 | x "\158\ e" |
| 171 | x "\0\e>\exdelete-region\r" |
| 172 | x "\ 3\e\f" |
| 173 | x "\ 3\ e" |
| 174 | x "\ e\v\ 2\ek" |
| 175 | x "\ 3\f" |
| 176 | x "\ 2\"Very long\r" |
| 177 | x "\10\ 3\14" |
| 178 | x "\ 2\r\r" |
| 179 | x "\ e\ 3\14" |
| 180 | x "\ 6\eo" |
| 181 | x "\ 6\ 3\14" |
| 182 | x "\ 2\ 2\"Very long2\r" |
| 183 | x "\ 2\eo\ 6" |
| 184 | x "\ 3\14" |
| 185 | x "\r\7f\7f\7fC3\r" |
| 186 | x "\ e\r\7f\7f\7fC2\r" |
| 187 | x "\10\0\ e\ 6\ 3\ 3" |
| 188 | x "\r\7f\7fC4\r" |
| 189 | x "\ e\ e\r\7f\7f\7fC2\r" |
| 190 | x "\ 6\0\ 2\10\10" |
| 191 | x "\ 3\ 3" |
| 192 | x "\exses-mode\r" |
| 193 | x "\e<\ f" |
| 194 | x "\152\ek" |
| 195 | x)) |
| 196 | ;;Header line |
| 197 | (fset 'ses-exercise-header-row |
| 198 | (concat y "\e:(revert-buffer t t)\r" |
| 199 | x "\18<" |
| 200 | x "\18>" |
| 201 | x "\156\18<" |
| 202 | x "\18>" |
| 203 | x "\157\18<" |
| 204 | x "\18>" |
| 205 | x "\158\18<" |
| 206 | x "\152\18<" |
| 207 | x "\18>" |
| 208 | x "\ 6\153w\ 2" |
| 209 | x "\1510\18<" |
| 210 | x "\18>" |
| 211 | x "\152\v" |
| 212 | x)) |
| 213 | ;;Detecting unsafe formulas and printers |
| 214 | (fset 'ses-exercise-unsafe |
| 215 | (concat y "\e:(revert-buffer t t)\r" |
| 216 | x "p(lambda (x) (delete-file x))\rn" |
| 217 | x "p(lambda (x) (delete-file \"ses-nothing\"))\ry" |
| 218 | x "\0\ 6\17\19n" |
| 219 | x "\ e(delete-file \"x\"\rn" |
| 220 | x "(delete-file \"ses-nothing\"\ry\ 2" |
| 221 | x "\0\ 6\17\19n" |
| 222 | x "(open-network-stream \"x\" nil \"localhost\" \"smtp\"\ry\ 2" |
| 223 | x "\0\ 6\17\19n" |
| 224 | x)) |
| 225 | ;;Inserting and deleting rows |
| 226 | (fset 'ses-exercise-rows |
| 227 | (concat y "\e:(revert-buffer t t)\r" |
| 228 | x "\ e\ 6" |
| 229 | x "\ 3\10\"%s=\"\r" |
| 230 | x "\1520\ f" |
| 231 | x "\ep\"%s+\"\r" |
| 232 | x "\ e\ f" |
| 233 | x "123456789\r\ 2" |
| 234 | x "\0\1521\ e\ 6" |
| 235 | x "\ 3\ 3" |
| 236 | x "\e\f" |
| 237 | x "\10\10(not B25\r\ 2" |
| 238 | x "\ e\ek" |
| 239 | x "jA3\r" |
| 240 | x "\1519\v" |
| 241 | x "\10\ 6\v" |
| 242 | x "\15100\ f" ;Make this approx your CPU speed in MHz |
| 243 | x)) |
| 244 | ;;Inserting and deleting columns |
| 245 | (fset 'ses-exercise-columns |
| 246 | (concat y "\e:(revert-buffer t t)\r" |
| 247 | x "\ 3\10\"%s@\"\r" |
| 248 | x "\eo" |
| 249 | x "\ f" |
| 250 | x "\eo" |
| 251 | x "\v" |
| 252 | x "\ek" |
| 253 | x "w8\r" |
| 254 | x "\ep\"%.7s*\"\r" |
| 255 | x "\eo" |
| 256 | x "\ 6" |
| 257 | x "\152\eo" |
| 258 | x "\153\ek" |
| 259 | x "\ 3\10\"%.6g\"\r" |
| 260 | x "\1526\eo" |
| 261 | x "\0\1526\t" |
| 262 | x "\1526\eo" |
| 263 | x "\ 3\e\b0\r" |
| 264 | x "\1526\t" |
| 265 | x "\15400\ 2" |
| 266 | x "\1550\ek" |
| 267 | x "\0\ e\ e\ 6\ 6\ 3\e\13D" |
| 268 | x)) |
| 269 | (fset 'ses-exercise-editing |
| 270 | (concat y "\e:(revert-buffer t t)\r" |
| 271 | x "\ e\ e\ e1\r\ 2" |
| 272 | x "\ 6(\ 2'\ 6x\r\ 2" |
| 273 | x "\ 2\10\10\10\ f" |
| 274 | x "\1f" |
| 275 | x "\r\r" |
| 276 | x "w9\r" |
| 277 | x "\ e\r\ 2.5\r" |
| 278 | x "\ e\ 6\r\ 2 10\r" |
| 279 | x "w12\r" |
| 280 | x "\r\ 1'\r" |
| 281 | x "\r\ 1\ 4\r" |
| 282 | x "jA4\r" |
| 283 | x "(+ A2 100\r\ 2" |
| 284 | x "\10\103\r\ 2" |
| 285 | x "jB1\r" |
| 286 | x "(not A1\r\ 2" |
| 287 | x "\ 2\"Very long\r\ 2" |
| 288 | x "\ 3\ 3" |
| 289 | x "\eh" |
| 290 | x "\eH" |
| 291 | x "\ 3\ 3" |
| 292 | x "\e>\t" |
| 293 | x "\10\10\ 4" |
| 294 | x "\10\ 4" |
| 295 | x "\ 6\ 6\152\7f" |
| 296 | x "\10\7f" |
| 297 | x "\eo" |
| 298 | x "\eh" |
| 299 | x "\0\ f\ 6" |
| 300 | x "\"Also very long\r\ 2" |
| 301 | x "\ e\ 6\eH" |
| 302 | x "\0'\r\ 2" |
| 303 | x "'Trial\r\ 2" |
| 304 | x "\ e\ 2'qwerty\r\ 2" |
| 305 | x "\ 6(concat \18o\e<\0\ e\ e" |
| 306 | x "\15-1\18o\ 3\12\r\ 2" |
| 307 | x "(apply '+ \18o\e<\0\ e\ 6\15-1\18o\ 3\13\r\ 2" |
| 308 | x "\10\152\7f" |
| 309 | x "\15-2\7f" |
| 310 | x "\15-2\ 4" |
| 311 | x "\152\ 4" |
| 312 | x "\ 2\10\10\v" |
| 313 | x "\ e\ 6\eH" |
| 314 | x "\ 2\10\0\ f" |
| 315 | x "\"Another long one\r\ 2" |
| 316 | x "\ e\ e\ 6\eH" |
| 317 | x "\ 1\10\ 5" |
| 318 | x "\ 3\ 3\e<" |
| 319 | x "\ e\ 5" |
| 320 | x "\e>\10\ f" |
| 321 | x "\0\ 5\ 6\ 5" |
| 322 | x)) |
| 323 | ;;Sorting of columns |
| 324 | (fset 'ses-exercise-sort-column |
| 325 | (concat y "\e:(revert-buffer t t)\r" |
| 326 | x "\"Very long\r" |
| 327 | x "\ 699\r" |
| 328 | x "\ 6\eo13\r" |
| 329 | x "(+ A3 B3\r" |
| 330 | x "7\r8\r(* A4 B4\r" |
| 331 | x "\0\10\10\10\ 3\e\13A\r" |
| 332 | x "\ e\0\10\10\10\ 3\e\13B\r" |
| 333 | x "\10\10\ 6\0\ e\ e\ 6\ 6\ 3\e\13C\r" |
| 334 | x "\ 6\eo\10\ f" |
| 335 | x "\ 2\0\ e\ e\ e\15\ 3\e\13C\r" |
| 336 | x)) |
| 337 | ;;Simple cell printers |
| 338 | (fset 'ses-exercise-cell-printers |
| 339 | (concat y "\e:(revert-buffer t t)\r" |
| 340 | x "\ 6\"4\11\t76\r\ 2" |
| 341 | x "\"4\11\n7\r\ 2" |
| 342 | x "p\"{%S}\"\r" |
| 343 | x "p(\"[%s]\")\r" |
| 344 | x "p(\"<%s>\")\r" |
| 345 | x "\ 2\0\ 6\ 6" |
| 346 | x "p\r" |
| 347 | x "pnil\r" |
| 348 | x "pses-dashfill\r" |
| 349 | x "48\r\ 2" |
| 350 | x "\t" |
| 351 | x "\ 2\0\ 6p\r" |
| 352 | x "\ 6p\r" |
| 353 | x "pses-dashfill\r" |
| 354 | x "\ 2\0\ 6\ 6pnil\r" |
| 355 | x "5\r\ 2" |
| 356 | x "pses-center\r" |
| 357 | x "\ 3\10\"%s\"\r" |
| 358 | x "w8\r" |
| 359 | x "\ep\r" |
| 360 | x "\ep\"%.7g@\"\r" |
| 361 | x "\ 3\10\r" |
| 362 | x "\ 3\10\"%.6g#\"\r" |
| 363 | x "\ 3\10\"%.6g.\"\r" |
| 364 | x "\ 3\10\"%.6g.\"\r" |
| 365 | x "\epidentity\r" |
| 366 | x "6\r\ 2" |
| 367 | x "\ e\"UPCASE\r\ 2" |
| 368 | x "\epdowncase\r" |
| 369 | x "(* 3 4\r\ 2" |
| 370 | x "p(lambda\11 (x)\11 '(\"Hi\"))\r" |
| 371 | x "p(lambda\11 (x)\11 '(\"Bye\"))\r" |
| 372 | x)) |
| 373 | ;;Spanning cell printers |
| 374 | (fset 'ses-exercise-spanning-printers |
| 375 | (concat y "\e:(revert-buffer t t)\r" |
| 376 | x "\ep\"%.6g*\"\r" |
| 377 | x "pses-dashfill-span\r" |
| 378 | x "5\r\ 2" |
| 379 | x "pses-tildefill-span\r" |
| 380 | x "\"4\r\ 2" |
| 381 | x "\ep\"$%s\"\r" |
| 382 | x "\ep(\"$%s\")\r" |
| 383 | x "8\r\ 2" |
| 384 | x "\ep(\"!%s!\")\r" |
| 385 | x "\t\"12345678\r\ 2" |
| 386 | x "pses-dashfill-span\r" |
| 387 | x "\"23456789\r\ 2" |
| 388 | x "\t" |
| 389 | x "(not t\r\ 2" |
| 390 | x "\ 2w6\r" |
| 391 | x "\"5\r\ 2" |
| 392 | x "\ e\ 6\eo" |
| 393 | x "\ek" |
| 394 | x "\ek" |
| 395 | x "\t" |
| 396 | x "\ 2\10\ 3\ 3" |
| 397 | x "\eo" |
| 398 | x "\ e\152\ek" |
| 399 | x "\ 2\ 2\ek" |
| 400 | x)) |
| 401 | ;;Cut/copy/paste - within same buffer |
| 402 | (fset 'ses-exercise-paste-1buf |
| 403 | (concat y "\e:(revert-buffer t t)\r" |
| 404 | x "\ e\0\ 6\ew" |
| 405 | x "\ 3\ 3\10\ 6\19" |
| 406 | x "\ e\eo" |
| 407 | x "\"middle\r\ 2" |
| 408 | x "\0\ 6\ e\ 6" |
| 409 | x "\ew" |
| 410 | x "\10\0\ 6" |
| 411 | x "\ew" |
| 412 | x "\ 3\ 3\ 6\ e" |
| 413 | x "\19" |
| 414 | x "\152\19y" |
| 415 | x "\ 6\15\19y" |
| 416 | x "\10\10\ 6\15\19y" |
| 417 | x "\e>" |
| 418 | x "\19y" |
| 419 | x "\e>\19y" |
| 420 | x "\e<" |
| 421 | x "p\"<%s>\"\r" |
| 422 | x "\ 6pses-dashfill\r" |
| 423 | x "\ 2\0\ 6\ 6\ 6\ e\ e\ e" |
| 424 | x "\17" |
| 425 | x "\1f" |
| 426 | x "\15\19y" |
| 427 | x "\r\0\ 2\ 2\ 2\ew" |
| 428 | x "\r\ 6\19" |
| 429 | x "\153\10(+ G2 H1\r" |
| 430 | x "\0\ 2\ew" |
| 431 | x "\ 3\ 3\e>\ 2" |
| 432 | x "\19" |
| 433 | x "\ 2\158\10(ses-average (ses-range G2 H2)\r\ 2" |
| 434 | x "\0\ 6\17\ek" |
| 435 | x "\157\ e" |
| 436 | x "\19" |
| 437 | x "\10\ 2(ses-average (ses-range E7 E9)\r\ 2" |
| 438 | x "\0\ 6\17\v" |
| 439 | x "\ e\19" |
| 440 | x "\ 2\ 2\10(ses-average (ses-range E7 F7)\r\ 2" |
| 441 | x "\0\ 6\17\ek" |
| 442 | x "\ 6\19" |
| 443 | x "\ 2\ 2\10(ses-average (ses-range D6 E6)\r\ 2" |
| 444 | x "\0\ 6\17\ek" |
| 445 | x "\ 6\19" |
| 446 | x "\ 1\152\ f" |
| 447 | x "\"Line A\r\ 2" |
| 448 | x "pses-tildefill-span\r" |
| 449 | x "\ e\ 6\"Subline A(1)\r\ 2" |
| 450 | x "pses-dashfill-span\r" |
| 451 | x "\ 2\10\0\ e\ e\ e\ew\ 3\ 3" |
| 452 | x "\ 1\10\10\10\10\10\10" |
| 453 | x "\19" |
| 454 | x "\0\ e\ 6\ 6\ew\ 3\ 3" |
| 455 | x "\ 6\19" |
| 456 | x)) |
| 457 | ;;Cut/copy/paste - between two buffers |
| 458 | (fset 'ses-exercise-paste-2buf |
| 459 | (concat y "\e:(revert-buffer t t)\r" |
| 460 | x "\ 6\ e\eo\"middle\r\ 2\0\ 6\ e\ 6" |
| 461 | x "\17" |
| 462 | x "\184bses-test.txt\r" |
| 463 | x " \ 1\19" |
| 464 | x "\ 5\"xxx\0\ 2\ 2\ 2\ 2" |
| 465 | x "\ew\18o" |
| 466 | x "\1f" |
| 467 | x "\19" |
| 468 | x "\18o\ 5\"\0\ 2\ 2\ 2\ 2\ 2" |
| 469 | x "\ew\18o\19" |
| 470 | x "\18o123.45\0\ 2\ 2\ 2\ 2\ 2\ 2" |
| 471 | x "\17\18o\19" |
| 472 | x "\18o1 \ 2\ 2\0\ 6\ 6\ 6\ 6\ 6\ 6\ 6" |
| 473 | x "\17\18o\19" |
| 474 | x "\e>\19y" |
| 475 | x "\ 6\18o symb\0\ 2\ 2\ 2\ 2" |
| 476 | x "\17\18o\15\19\ey\152\ey" |
| 477 | x "\18o1\t\0\ 2\ 2" |
| 478 | x "\17\18o\ 2\19" |
| 479 | x "w9\n\ep\"<%s>\"\n" |
| 480 | x "\18o\n2\t\"3\nxxx\t5\n\0\10\10" |
| 481 | x "\17\18o\19y" |
| 482 | x)) |
| 483 | ;;Export text, import it back |
| 484 | (fset 'ses-exercise-import-export |
| 485 | (concat y "\e:(revert-buffer t t)\r" |
| 486 | x "\ e\ e\ 6\0\ 6xt" |
| 487 | x "\184bses-test.txt\r" |
| 488 | x "\n\19\15-1\18o" |
| 489 | x "xT\18o\19\15-1\18o" |
| 490 | x "\ 3\ 3\ 6'crunch\r\ 2" |
| 491 | x "\10\10\10pses-center-span\r" |
| 492 | x "\0\ e\ e\ e\ exT" |
| 493 | x "\18o\n\19\15-1\18o" |
| 494 | x "\0\19y" |
| 495 | x "\ 6\0\ 2\10\10xt" |
| 496 | x "\ e\ e\0\15\19y" |
| 497 | x "12345678\r\ 2" |
| 498 | x "\ 6\ 6'bunch\r" |
| 499 | x "\0\10\10xtxT" |
| 500 | x))) |
| 501 | |
| 502 | (defun ses-exercise-macros () |
| 503 | "Executes all SES coverage-test macros." |
| 504 | (dolist (x '(ses-exercise-example |
| 505 | ses-exercise-new |
| 506 | ses-exercise-display |
| 507 | ses-exercise-formulas |
| 508 | ses-exercise-recalc |
| 509 | ses-exercise-header-row |
| 510 | ses-exercise-unsafe |
| 511 | ses-exercise-rows |
| 512 | ses-exercise-columns |
| 513 | ses-exercise-editing |
| 514 | ses-exercise-sort-column |
| 515 | ses-exercise-cell-printers |
| 516 | ses-exercise-spanning-printers |
| 517 | ses-exercise-paste-1buf |
| 518 | ses-exercise-paste-2buf |
| 519 | ses-exercise-import-export)) |
| 520 | (message "<Testing %s>" x) |
| 521 | (execute-kbd-macro x))) |
| 522 | |
| 523 | (defun ses-exercise-signals () |
| 524 | "Exercise code paths that lead to error signals, other than those for |
| 525 | spreadsheet files with invalid formatting." |
| 526 | (message "<Checking for expected errors>") |
| 527 | (switch-to-buffer "ses-test.ses") |
| 528 | (deactivate-mark) |
| 529 | (ses-jump 'A1) |
| 530 | (ses-set-curcell) |
| 531 | (dolist (x '((ses-column-widths 14) |
| 532 | (ses-column-printers "%s") |
| 533 | (ses-column-printers ["%s" "%s" "%s"]) ;Should be two |
| 534 | (ses-column-widths [14]) |
| 535 | (ses-delete-column -99) |
| 536 | (ses-delete-column 2) |
| 537 | (ses-delete-row -1) |
| 538 | (ses-goto-data 'hogwash) |
| 539 | (ses-header-row -56) |
| 540 | (ses-header-row 99) |
| 541 | (ses-insert-column -14) |
| 542 | (ses-insert-row 0) |
| 543 | (ses-jump 'B8) ;Covered by preceding cell |
| 544 | (ses-printer-validate '("%s" t)) |
| 545 | (ses-printer-validate '([47])) |
| 546 | (ses-read-header-row -1) |
| 547 | (ses-read-header-row 32767) |
| 548 | (ses-relocate-all 0 0 -1 1) |
| 549 | (ses-relocate-all 0 0 1 -1) |
| 550 | (ses-select (ses-range A1 A2) 'x (ses-range B1 B1)) |
| 551 | (ses-set-cell 0 0 'hogwash nil) |
| 552 | (ses-set-column-width 0 0) |
| 553 | (ses-yank-cells #("a\nb" |
| 554 | 0 1 (ses (A1 nil nil)) |
| 555 | 2 3 (ses (A3 nil nil))) |
| 556 | nil) |
| 557 | (ses-yank-cells #("ab" |
| 558 | 0 1 (ses (A1 nil nil)) |
| 559 | 1 2 (ses (A2 nil nil))) |
| 560 | nil) |
| 561 | (ses-yank-pop nil) |
| 562 | (ses-yank-tsf "1\t2\n3" nil) |
| 563 | (let ((curcell nil)) (ses-check-curcell)) |
| 564 | (let ((curcell 'A1)) (ses-check-curcell 'needrange)) |
| 565 | (let ((curcell '(A1 . A2))) (ses-check-curcell 'end)) |
| 566 | (let ((curcell '(A1 . A2))) (ses-sort-column "B")) |
| 567 | (let ((curcell '(C1 . D2))) (ses-sort-column "B")) |
| 568 | (execute-kbd-macro "jB10\n\152\ 4") |
| 569 | (execute-kbd-macro [?j ?B ?9 ?\n ?\C-@ ?\C-f ?\C-f cut]) |
| 570 | (progn (kill-new "x") (execute-kbd-macro "\e>\19n")) |
| 571 | (execute-kbd-macro "\ 2\0\ew"))) |
| 572 | (condition-case nil |
| 573 | (progn |
| 574 | (eval x) |
| 575 | (signal 'singularity-error nil)) ;Shouldn't get here |
| 576 | (singularity-error (error "No error from %s?" x)) |
| 577 | (error nil))) |
| 578 | ;;Test quit-handling in ses-update-cells. Cant' use `eval' here. |
| 579 | (let ((inhibit-quit t)) |
| 580 | (setq quit-flag t) |
| 581 | (condition-case nil |
| 582 | (progn |
| 583 | (ses-update-cells '(A1)) |
| 584 | (signal 'singularity-error nil)) |
| 585 | (singularity-error (error "Quit failure in ses-update-cells")) |
| 586 | (error nil)) |
| 587 | (setq quit-flag nil))) |
| 588 | |
| 589 | (defun ses-exercise-invalid-spreadsheets () |
| 590 | "Execute code paths that detect invalid spreadsheet files." |
| 591 | ;;Detect invalid spreadsheets |
| 592 | (let ((p&d "\n\n\f\n(ses-cell A1 nil nil nil nil)\n\n") |
| 593 | (cw "(ses-column-widths [7])\n") |
| 594 | (cp "(ses-column-printers [ses-center])\n") |
| 595 | (dp "(ses-default-printer \"%.7g\")\n") |
| 596 | (hr "(ses-header-row 0)\n") |
| 597 | (p11 "(2 1 1)") |
| 598 | (igp ses-initial-global-parameters)) |
| 599 | (dolist (x (list "(1)" |
| 600 | "(x 2 3)" |
| 601 | "(1 x 3)" |
| 602 | "(1 -1 0)" |
| 603 | "(1 2 x)" |
| 604 | "(1 2 -1)" |
| 605 | "(3 1 1)" |
| 606 | "\n\n\f(2 1 1)" |
| 607 | "\n\n\f\n(ses-cell)(2 1 1)" |
| 608 | "\n\n\f\n(x)\n(2 1 1)" |
| 609 | "\n\n\n\f\n(ses-cell A2)\n(2 2 2)" |
| 610 | "\n\n\n\f\n(ses-cell B1)\n(2 2 2)" |
| 611 | "\n\n\f\n(ses-cell A1 nil nil nil nil)\n(2 1 1)" |
| 612 | (concat p&d "(x)\n(x)\n(x)\n(x)\n" p11) |
| 613 | (concat p&d "(ses-column-widths)(x)\n(x)\n(x)\n" p11) |
| 614 | (concat p&d cw "(x)\n(x)\n(x)\n(2 1 1)") |
| 615 | (concat p&d cw "(ses-column-printers)(x)\n(x)\n" p11) |
| 616 | (concat p&d cw cp "(x)\n(x)\n" p11) |
| 617 | (concat p&d cw cp "(ses-default-printer)(x)\n" p11) |
| 618 | (concat p&d cw cp dp "(x)\n" p11) |
| 619 | (concat p&d cw cp dp "(ses-header-row)" p11) |
| 620 | (concat p&d cw cp dp hr p11) |
| 621 | (concat p&d cw cp dp "\n" hr igp))) |
| 622 | (condition-case nil |
| 623 | (with-temp-buffer |
| 624 | (insert x) |
| 625 | (ses-load) |
| 626 | (signal 'singularity-error nil)) ;Shouldn't get here |
| 627 | (singularity-error (error "%S is an invalid spreadsheet!" x)) |
| 628 | (error nil))))) |
| 629 | |
| 630 | (defun ses-exercise-startup () |
| 631 | "Prepare for coverage tests" |
| 632 | ;;Clean up from any previous runs |
| 633 | (condition-case nil (kill-buffer "ses-example.ses") (error nil)) |
| 634 | (condition-case nil (kill-buffer "ses-test.ses") (error nil)) |
| 635 | (condition-case nil (delete-file "ses-test.ses") (file-error nil)) |
| 636 | (delete-other-windows) ;Needed for "\C-xo" in ses-exercise-editing |
| 637 | (setq ses-mode-map nil) ;Force rebuild |
| 638 | (testcover-unmark-all "ses.el") |
| 639 | ;;Enable |
| 640 | (let ((testcover-1value-functions |
| 641 | ;;forward-line always returns 0, for us. |
| 642 | ;;remove-text-properties always returns t for us. |
| 643 | ;;ses-recalculate-cell returns the same " " any time curcell is a cons |
| 644 | ;;Macros ses-dorange and ses-dotimes-msg generate code that always |
| 645 | ;; returns nil |
| 646 | (append '(forward-line remove-text-properties ses-recalculate-cell |
| 647 | ses-dorange ses-dotimes-msg) |
| 648 | testcover-1value-functions)) |
| 649 | (testcover-constants |
| 650 | ;;These maps get initialized, then never changed again |
| 651 | (append '(ses-mode-map ses-mode-print-map ses-mode-edit-map) |
| 652 | testcover-constants))) |
| 653 | (testcover-start "ses.el" t)) |
| 654 | (require 'unsafep)) ;In case user has safe-functions = t! |
| 655 | |
| 656 | |
| 657 | ;;;######################################################################### |
| 658 | (defun ses-exercise () |
| 659 | "Executes all SES coverage tests and displays the results." |
| 660 | (interactive) |
| 661 | (ses-exercise-startup) |
| 662 | ;;Run the keyboard-macro tests |
| 663 | (let ((safe-functions nil) |
| 664 | (ses-initial-size '(1 . 1)) |
| 665 | (ses-initial-column-width 7) |
| 666 | (ses-initial-default-printer "%.7g") |
| 667 | (ses-after-entry-functions '(forward-char)) |
| 668 | (ses-mode-hook nil)) |
| 669 | (ses-exercise-macros) |
| 670 | (ses-exercise-signals) |
| 671 | (ses-exercise-invalid-spreadsheets) |
| 672 | ;;Upgrade of old-style spreadsheet |
| 673 | (with-temp-buffer |
| 674 | (insert " \n\n\f\n(ses-cell A1 nil nil nil nil)\n\n(ses-column-widths [7])\n(ses-column-printers [nil])\n(ses-default-printer \"%.7g\")\n\n( ;Global parameters (these are read first)\n 1 ;SES file-format\n 1 ;numrows\n 1 ;numcols\n)\n\n") |
| 675 | (ses-load)) |
| 676 | ;;ses-vector-delete is always called from buffer-undo-list with the same |
| 677 | ;;symbol as argument. We'll give it a different one here. |
| 678 | (let ((x [1 2 3])) |
| 679 | (ses-vector-delete 'x 0 0)) |
| 680 | ;;ses-create-header-string behaves differently in a non-window environment |
| 681 | ;;but we always test under windows. |
| 682 | (let ((window-system (not window-system))) |
| 683 | (scroll-left 7) |
| 684 | (ses-create-header-string)) |
| 685 | ;;Test for nonstandard after-entry functions |
| 686 | (let ((ses-after-entry-functions '(forward-line)) |
| 687 | ses-mode-hook) |
| 688 | (ses-read-cell 0 0 1) |
| 689 | (ses-read-symbol 0 0 t))) |
| 690 | ;;Tests with unsafep disabled |
| 691 | (let ((safe-functions t) |
| 692 | ses-mode-hook) |
| 693 | (message "<Checking safe-functions = t>") |
| 694 | (kill-buffer "ses-example.ses") |
| 695 | (find-file "ses-example.ses")) |
| 696 | ;;Checks for nonstandard default values for new spreadsheets |
| 697 | (let (ses-mode-hook) |
| 698 | (dolist (x '(("%.6g" 8 (2 . 2)) |
| 699 | ("%.8g" 6 (3 . 3)))) |
| 700 | (let ((ses-initial-size (nth 2 x)) |
| 701 | (ses-initial-column-width (nth 1 x)) |
| 702 | (ses-initial-default-printer (nth 0 x))) |
| 703 | (with-temp-buffer |
| 704 | (set-buffer-modified-p t) |
| 705 | (ses-mode))))) |
| 706 | ;;Test error-handling in command hook, outside a macro. |
| 707 | ;;This will ring the bell. |
| 708 | (let (curcell-overlay) |
| 709 | (ses-command-hook)) |
| 710 | ;;Due to use of run-with-timer, ses-command-hook sometimes gets called |
| 711 | ;;after we switch to another buffer. |
| 712 | (switch-to-buffer "*scratch*") |
| 713 | (ses-command-hook) |
| 714 | ;;Print results |
| 715 | (message "<Marking source code>") |
| 716 | (testcover-mark-all "ses.el") |
| 717 | (testcover-next-mark) |
| 718 | ;;Cleanup |
| 719 | (delete-other-windows) |
| 720 | (kill-buffer "ses-test.txt") |
| 721 | ;;Could do this here: (testcover-end "ses.el") |
| 722 | (message "Done")) |
| 723 | |
| 724 | ;; testcover-ses.el ends here. |