8
8
9
9
(require 'ert )
10
10
(require 'typescript-mode )
11
+ (require 'cl )
11
12
12
13
(defun typescript-test-get-doc ()
13
14
(buffer-substring-no-properties (point-min ) (point-max )))
@@ -211,8 +212,18 @@ a severity set to WARNING, no rule name."
211
212
`(with-temp-buffer
212
213
(insert , content )
213
214
(typescript-mode )
214
- (font-lock-fontify-buffer )
215
215
(goto-char (point-min ))
216
+ ; ; We need this so that tests that simulate user actions operate on the right buffer.
217
+ (switch-to-buffer (current-buffer ))
218
+ ,@body ))
219
+
220
+ (defmacro test-with-fontified-buffer (content &rest body )
221
+ " Fill a temporary buffer with `CONTENT' and eval `BODY' in it."
222
+ (declare (debug t )
223
+ (indent 1 ))
224
+ `(test-with-temp-buffer
225
+ , content
226
+ (font-lock-fontify-buffer )
216
227
,@body ))
217
228
218
229
(defun get-face-at (loc )
@@ -234,7 +245,7 @@ put in the temporary buffer. `EXPECTED' is the expected
234
245
results. It should be a list of (LOCATION . FACE) pairs, where
235
246
LOCATION can be either a single location, or list of locations,
236
247
that are all expected to have the same face."
237
- (test-with-temp -buffer
248
+ (test-with-fontified -buffer
238
249
contents
239
250
; ; Make sure our propertize function has been applied to the whole
240
251
; ; buffer.
@@ -263,7 +274,7 @@ documentation."
263
274
(ert-deftest font-lock/no-documentation-in-non-documentation-comments ()
264
275
" Documentation tags that are not in documentation comments
265
276
should not be fontified as documentation."
266
- (test-with-temp -buffer
277
+ (test-with-fontified -buffer
267
278
(concat " /*\n " font-lock-contents " \n */\n " )
268
279
(let ((loc 3 ))
269
280
; ; Make sure we start with the right face.
@@ -274,7 +285,7 @@ should not be fontified as documentation."
274
285
(ert-deftest font-lock/no-documentation-in-strings ()
275
286
" Documentation tags that are not in strings should not be
276
287
fontified as documentation."
277
- (test-with-temp -buffer
288
+ (test-with-fontified -buffer
278
289
(concat " const x = \" /**" font-lock-contents " */\" ;" )
279
290
(let ((loc (search-forward " \" " )))
280
291
; ; Make sure we start with the right face.
@@ -374,16 +385,16 @@ declare function declareFunctionDefn(x3: xty3, y3: yty3): ret3;"
374
385
375
386
(ert-deftest font-lock/text-after-trailing-regexp-delim-should-not-be-fontified ()
376
387
" Text after trailing regular expression delimiter should not be fontified."
377
- (test-with-temp -buffer
388
+ (test-with-fontified -buffer
378
389
" =/foo/g something // comment"
379
390
(should (eq (get-face-at " g something" ) nil )))
380
- (test-with-temp -buffer
391
+ (test-with-fontified -buffer
381
392
" =/foo\\ bar/g something // comment"
382
393
(should (eq (get-face-at " g something" ) nil )))
383
- (test-with-temp -buffer
394
+ (test-with-fontified -buffer
384
395
" =/foo\\\\ bar/g something // comment"
385
396
(should (eq (get-face-at " g something" ) nil )))
386
- (test-with-temp -buffer
397
+ (test-with-fontified -buffer
387
398
" =/foo\\\\ /g something // comment"
388
399
(should (eq (get-face-at " g something" ) nil ))))
389
400
@@ -412,23 +423,181 @@ import... from...."
412
423
; ; to avoid hitting keywords. Moreover, the end position of the search is important.
413
424
; ; Flyspell puts point at the end of the word before calling the predicate. We must
414
425
; ; replicate that behavior here.
415
- (test-with-temp -buffer
426
+ (test-with-fontified -buffer
416
427
" import 'a';\n import { x } from 'b';\n const foo = 'c';import { x }\n from 'd';"
417
428
(should (not (flyspell-predicate-test " 'a" )))
418
429
(should (not (flyspell-predicate-test " 'b" )))
419
430
(should (flyspell-predicate-test " 'c" ))
420
431
(should (not (flyspell-predicate-test " 'd" ))))
421
- (test-with-temp -buffer
432
+ (test-with-fontified -buffer
422
433
; ; This is valid TypeScript.
423
434
" const from = 'a';"
424
435
(should (flyspell-predicate-test " 'a" )))
425
- (test-with-temp -buffer
436
+ (test-with-fontified -buffer
426
437
; ; TypeScript does not allow a function named "import" but object
427
438
; ; members may be named "import". So this *can* be valid
428
439
; ; TypeScript.
429
440
" x.import('a');"
430
441
(should (flyspell-predicate-test " 'a" )))))
431
442
443
+
444
+ (ert-deftest typescript--move-to-end-of-plain-string ()
445
+ " Unit tests for `typescript--move-to-end-of-plain-string' ."
446
+ (cl-flet
447
+ ((should-fail ()
448
+ (let ((point-before (point )))
449
+ (should (not (typescript--move-to-end-of-plain-string)))
450
+ (should (eq (point ) point-before))))
451
+ (should-not-fail (expected)
452
+ (let ((result (typescript--move-to-end-of-plain-string)))
453
+ (should (eq result expected))
454
+ (should (eq (point ) expected)))))
455
+ ; ;
456
+ ; ; The tests below are structured as follows. For each case:
457
+ ; ;
458
+ ; ; 1. Move point to a new location in the buffer.
459
+ ; ;
460
+ ; ; 2. Check whether typescript--move-to-end-of-plain-string returns the value we expected
461
+ ; ; and changes (point) when successful.
462
+ ; ;
463
+ ; ; Cases often start with a check right away: (point) equal to
464
+ ; ; (point-min) for those cases.
465
+ ; ;
466
+ (dolist (delimiter '(" '" " \" " ))
467
+ (test-with-temp-buffer
468
+ (replace-regexp-in-string " '" delimiter " const a = 'not terminated" )
469
+ (should-fail)
470
+ (re-search-forward delimiter)
471
+ (should-fail))
472
+ (test-with-temp-buffer
473
+ (replace-regexp-in-string " '" delimiter " const a = 'terminated'" )
474
+ (should-fail)
475
+ ; ; This checks that the function works when invoked on the start delimiter of
476
+ ; ; a terminated string.
477
+ (re-search-forward delimiter)
478
+ (should-not-fail (1- (point-max )))
479
+ (goto-char (point-min ))
480
+ (re-search-forward " term" )
481
+ (should-not-fail (1- (point-max )))
482
+ ; ; This checks that the function works when invoked on the end delimiter of
483
+ ; ; a terminated string.
484
+ (goto-char (1- (point-max )))
485
+ (should-not-fail (1- (point-max ))))
486
+ (test-with-temp-buffer
487
+ (replace-regexp-in-string " '" delimiter " const a = 'terminated aaa';\n
488
+ const b = 'not terminated bbb" )
489
+ (should-fail)
490
+ (re-search-forward " term" )
491
+ (should-not-fail (save-excursion (re-search-forward " aaa" )))
492
+ (re-search-forward " const b" )
493
+ (should-fail)
494
+ (re-search-forward " not terminated" )
495
+ (should-fail))
496
+ ; ; Case with escaped delimiter.
497
+ (test-with-temp-buffer
498
+ (replace-regexp-in-string " '" delimiter " const a = 'terminat\\ 'ed aaa';\n
499
+ const b = 'not terminated bbb" )
500
+ (re-search-forward " term" )
501
+ (should-not-fail (save-excursion (re-search-forward " aaa" ))))
502
+ ; ; Delimiters in comments.
503
+ (test-with-temp-buffer
504
+ (replace-regexp-in-string " '" delimiter " const a = 'terminated aaa';\n
505
+ // Comment 'or'\n
506
+ const b = 'not terminated bbb" )
507
+ (re-search-forward " term" )
508
+ (should-not-fail (save-excursion (re-search-forward " aaa" )))
509
+ (re-search-forward " Comment " )
510
+ (should-fail)
511
+ (forward-char )
512
+ (should-fail)
513
+ (re-search-forward " or" )
514
+ (should-fail)))
515
+ ; ; Ignores template strings.
516
+ (test-with-temp-buffer
517
+ " const a = `terminated aaa`"
518
+ (re-search-forward " term" )
519
+ (should-fail))))
520
+
521
+ (ert-deftest typescript-convert-to-template ()
522
+ " Unit tests for `typescript-convert-to-template' ."
523
+ (cl-flet
524
+ ((should-do-nothing (str regexp)
525
+ (test-with-temp-buffer
526
+ str
527
+ (re-search-forward regexp)
528
+ (typescript-convert-to-template)
529
+ (should (string-equal (typescript-test-get-doc) str))))
530
+ (should-modify (str delimiter regexp)
531
+ (test-with-temp-buffer
532
+ str
533
+ (re-search-forward regexp)
534
+ (typescript-convert-to-template)
535
+ (should (string-equal (typescript-test-get-doc)
536
+ (replace-regexp-in-string delimiter " `" str))))))
537
+ (dolist (delimiter '(" '" " \" " ))
538
+ (let ((str (replace-regexp-in-string " '" delimiter " const a = 'not terminated" )))
539
+ (dolist (move-to '(" const" " not" ))
540
+ (should-do-nothing str move-to)))
541
+ (let ((str (replace-regexp-in-string " '" delimiter " const a = 'terminated'" )))
542
+ (should-do-nothing str " const" )
543
+ (should-modify str delimiter delimiter)
544
+ (should-modify str delimiter " term" )
545
+ (should-modify str delimiter " terminated" ))
546
+ ; ; Delimiters in comments.
547
+ (let ((str (replace-regexp-in-string " '" delimiter " const a = 'terminated aaa';\n
548
+ // Comment 'or'\n
549
+ const b = 'not terminated bbb" )))
550
+ (should-do-nothing str " Comment " )))
551
+ ; ; Ignores template strings.
552
+ (let ((str " const a = `terminated aaa`" ))
553
+ (should-do-nothing str " terminated" ))))
554
+
555
+ (ert-deftest typescript-autoconvert-to-template ()
556
+ " Unit tests for `typescript-autoconvert-to-template' ."
557
+ (cl-flet
558
+ ((should-do-nothing (str regexp)
559
+ (test-with-temp-buffer
560
+ str
561
+ (re-search-forward regexp)
562
+ (typescript-autoconvert-to-template)
563
+ (should (string-equal (typescript-test-get-doc) str))))
564
+ (should-modify (str delimiter regexp)
565
+ (test-with-temp-buffer
566
+ str
567
+ (re-search-forward regexp)
568
+ (typescript-autoconvert-to-template)
569
+ (should (string-equal (typescript-test-get-doc)
570
+ (replace-regexp-in-string delimiter " `" str))))))
571
+ (dolist (delimiter '(" '" " \" " ))
572
+ (let ((str (replace-regexp-in-string " '" delimiter " const a = 'terminated'" )))
573
+ (should-do-nothing str " = " )
574
+ (should-do-nothing str " terminated" ))
575
+ (let ((str (replace-regexp-in-string " '" delimiter " const a = '${foo}'" )))
576
+ (should-do-nothing str " = " )
577
+ (should-modify str delimiter (concat " foo}" delimiter))))))
578
+
579
+ (ert-deftest typescript-autoconvert-to-template-is-invoked ()
580
+ " Test that we call `typescript-autoconvert-to-template' as needed."
581
+ (cl-flet
582
+ ((should-do-nothing (str delimiter)
583
+ (test-with-temp-buffer
584
+ str
585
+ (goto-char (point-max ))
586
+ (execute-kbd-macro delimiter)
587
+ (should (string-equal (typescript-test-get-doc) (concat str delimiter)))))
588
+ (should-modify (str delimiter)
589
+ (test-with-temp-buffer
590
+ str
591
+ (goto-char (point-max ))
592
+ (execute-kbd-macro delimiter)
593
+ (should (string-equal (typescript-test-get-doc)
594
+ (replace-regexp-in-string delimiter " `" (concat str delimiter)))))))
595
+ (dolist (delimiter '(" '" " \" " ))
596
+ (let ((str (replace-regexp-in-string " '" delimiter " const a = '${foo}" )))
597
+ (should-do-nothing str delimiter)
598
+ (let ((typescript-autoconvert-to-template-flag t ))
599
+ (should-modify str delimiter))))))
600
+
432
601
(provide 'typescript-mode-tests )
433
602
434
603
; ;; typescript-mode-tests.el ends here
0 commit comments