;;; gap-buffer.test                                     -*- scheme -*-

;; Copyright (C) 2004, 2007, 2009 Thien-Thi Nguyen
;;
;; This file is part of GUILE
;;
;; GUILE is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;;
;; GUILE is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this software; see the file COPYING.  If not, write to
;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.

(use-modules (ice-9 gap-buffer))

(define gb:test:number 0)

(defmacro check-gb (point point-min point-max buffer-string)
  `(begin
     (set! gb:test:number (1+ gb:test:number))
     (pass-if (fs "~A gb->string" gb:test:number)
       (string=? (gb->string gb) ,buffer-string))
     (pass-if (fs "~A gb-point" gb:test:number)
       (= (gb-point gb) ,point))
     (pass-if (fs "~A gb-point-min" gb:test:number)
       (= (gb-point-min gb) ,point-min))
     (pass-if (fs "~A gb-point-max" gb:test:number)
       (= (gb-point-max gb) ,point-max))))

(let ((gb (make-gap-buffer)))
  (check-gb 1 1 1 "")
  (gb-insert-string! gb "nothing is real")
  (check-gb 16 1 16 "nothing is real")
  (gb-insert-char! gb #\space)
  (gb-insert-char! gb #\newline)
  (check-gb 18 1 18 "nothing is real \n")
  (gb-delete-char! gb 0)                ; does nothing
  (check-gb 18 1 18 "nothing is real \n")
  (gb-delete-char! gb 5)                ; does nothing
  (check-gb 18 1 18 "nothing is real \n")
  (gb-delete-char! gb -5)
  (check-gb 13 1 13 "nothing is r")
  (pass-if "goto-char 0" (zero? (gb-goto-char gb 0)))
  (check-gb 1 1 13 "nothing is r")
  (pass-if "goto-char 14" (= (gb-goto-char gb 14) 14))
  (check-gb 13 1 13 "nothing is r")
  (let ()
    (define (check-port-output beg end exp)
      (do ((pos (gb-point-min gb) (1+ pos)))
          ((= pos (gb-point-max gb)))
        (pass-if (fs "port-output(~A) ~A ~A" pos beg end)
          (string=? exp (call-with-tmpfile
                         (lambda (p) (gb->port! gb p beg end)))))))
    (check-port-output 1 13 "nothing is r")
    (check-port-output 3 11 "thing is")
    (check-port-output 1 10 "nothing i")
    (check-port-output 7 13 "g is r")
    (pass-if "port-output"
      (string=? "nothing is r" (call-with-tmpfile
                                (lambda (p) (gb->port! gb p))))))
  (gb-goto-char gb 1)
  (gb-insert-char! gb #\Z)
  (check-gb 2 1 14 "Znothing is r")
  (gb-delete-char! gb 1)
  (gb-goto-char gb 4)
  (gb-insert-char! gb #\t)
  (gb-delete-char! gb 1)
  (gb-goto-char gb (gb-point-max gb))
  (gb-insert-string! gb "adical!")
  (check-gb 20 1 20 "Zotting is radical!")
  (gb-goto-char gb 8)
  (with-output-to-port (make-gap-buffer-port gb)
    (lambda ()
      (display #\space) (display "hello world!")
      (newline) (display "Hacking")))
  (check-gb 29 1 41 "Zotting hello world!\nHacking is radical!")
  (gb-filter-lines! gb cdr)
  (check-gb 20 1 20 "Hacking is radical!")
  (gb-goto-char gb (gb-point-max gb))
  (gb-insert-char! gb #\newline)
  (check-gb 21 1 21 "Hacking is radical!\n")
  (gb-filter-lines! gb (lambda (lines)
                         (map (lambda (ln)
                                (number->string (string-length ln)))
                              lines)))
  (check-gb 5 1 5 "19\n0")
  (gb-erase! gb)
  (check-gb 1 1 1 ""))

;;; gap-buffer.test ends here
