(assert-fail (buffer 123)) (assert (void? (path-make-dir "a/new/dir"))) (assert (path-exists? "a/new/dir")) (assert (void? (path-make-dir "a/new/dir"))) (assert (void? (path-delete "a/new/dir"))) (assert (not (path-exists? "a/new/dir"))) (assert (void? (path-delete "a/new"))) (assert (not (path-exists? "a/new"))) (assert (void? (path-delete "a"))) (assert (not (path-exists? "a"))) (def b (buffer)) (assert (io? b)) (assert (eq? (type-of b) 'io)) (assert (eq? (io-buffer-mode b) :memory)) (assert (= (size-of b) 0)) ; no data (assert (= (io-pos b) 0)) (assert (= (io-pos! b 1) 0)) (assert (eof? (io-read b 'u8))) ; empty - EOF (assert (io-eof? b)) (assert (eof? (io-read b 'u8))) ; still empty - EOF again (assert (io-eof? b)) ;; write one rune (assert (= (io-write b #\¢) 3)) (assert (= (size-of b) 3)) (assert (= (io-pos b) 3)) ;; go back (assert (= (io-pos! b 0) 0)) (assert (not (io-eof? b))) ;; peek and compare (def x (io-peek b 'rune)) (assert (eq? (type-of x) 'rune)) (assert (equal? x #\¢)) (assert (not (io-eof? b))) (assert (= (io-pos b) 0)) ;; read it back and compare (def x (io-read b 'rune)) (assert (eq? (type-of x) 'rune)) (assert (equal? x #\¢)) (assert (not (io-eof? b))) (assert (eof? (io-read b 'rune))) (assert (io-eof? b)) (assert (= (io-pos b) 3)) ;; peek/read as an array of bytes and compare (assert (= (io-pos! b 0) 0)) (assert (equal? (io-peek b 'utf8 0) "")) (assert (equal? (io-read b 'utf8 0) "")) (assert (equal? (io-peek b 'rune 0) (arr 'rune))) (assert (equal? (io-read b 'rune 0) (arr 'rune))) (assert (equal? (io-peek b 'u8 3) (arr 'u8 #xef #xbf #xa0))) (assert (equal? (io-read b 'u8 3) (arr 'u8 #xef #xbf #xa0))) ;; go back and try reading more than there is (assert (= (io-pos! b 0) 0)) (assert (equal? (io-peek b 'u8 4) (arr 'u8 #xef #xbf #xa0))) (assert (equal? (io-read b 'u8 4) (arr 'u8 #xef #xbf #xa0))) (assert (not (io-eof? b))) ; not eof until we try and read nothing (assert (eof? (io-read b 'u8 1))) (assert (io-eof? b)) ; _now_ it's eof ;; go back and read as an utf8 string (assert (= (io-pos! b 0) 0)) (assert (equal? (io-peek b 'utf8) "¢")) (assert (equal? (io-peek b 'rune) #\¢)) (assert (equal? (io-read b 'utf8) "¢")) ;; go back and read as an array of runes (assert (= (io-pos! b 0) 0)) (assert (equal? (io-peek b 'rune 1) (arr 'rune #\¢))) (assert (equal? (io-read b 'rune 1) (arr 'rune #\¢))) ;; skip back and forth (assert (= (io-skip b -1) 2)) (assert (= (io-pos b) 2)) (assert (= (io-skip b -1) 1)) (assert (= (io-pos b) 1)) (assert (= (io-skip b -2 :end T) 1)) (assert (= (io-pos b) 1)) (assert (= (io-skip b -3 :end T) 0)) (assert (= (io-pos b) 0)) (assert (equal? (io-peek b 'utf8) "¢")) (assert (equal? (io-peek b 'rune) #\¢)) (assert (equal? (io-read b 'rune) #\¢)) ;; convert to string - destructive operation (assert (= (io-pos! b 0) 0)) (assert (equal? (io->str b) "¢")) (assert (= (io-pos b) 0)) (assert (= (io-pos! b 9) 0)) (assert (= (size-of b) 0)) ;; filename (assert (equal? (io-filename b) "")) (assert (equal? (io-filename! b "hi") "hi")) (assert (equal? (io-filename b) "hi")) ;; write some more (assert (= (io-write b "hello") 5)) ;; truncate (assert (void? (io-truncate b 3))) ; shrinking (assert (= (size-of b) 3)) (assert (= (io-pos b) 3)) (assert (void? (io-truncate b 0))) ; emptying (assert (eof? (io-read b 'u8))) (assert (io-eof? b)) (assert (= (size-of b) 0)) (assert (= (io-pos b) 0)) (assert (= (io-pos! b 1) 0)) (assert (eof? (io-read b 'u8))) (assert (io-eof? b)) ;; closed from now on (assert (void? (io-close b))) ;; can close again without errors - noop (assert (void? (io-close b))) ;; filename still usable (assert (equal? (io-filename b) "hi")) (assert (equal? (io-filename! b "no") "no")) (assert (equal? (io-filename b) "no")) ;; can't do much (assert-fail (io->str b) io-error) (assert-fail (io-buffer-mode b) io-error) (assert-fail (io-buffer-mode! b NIL) io-error) (assert-fail (io-eof? b) io-error) (assert-fail (io-peek b 'rune) io-error) (assert-fail (io-pos b) io-error) (assert-fail (io-pos! b 0) io-error) (assert-fail (io-read b 'u8) io-error) (assert-fail (io-read-all b) io-error) (assert-fail (io-read-line b) io-error) (assert-fail (io-read-lines b) io-error) (assert-fail (io-read-until b #\x) io-error) (assert-fail (io-skip b 0) io-error) (assert-fail (io-truncate b 0) io-error) (assert-fail (io-write b "") io-error) (def b (buffer)) ;; write an array of runes (assert (= (io-write b (arr 'rune #\¡ #\¿ #\nul #\x #\y #\z)) 8)) (assert (= (io-pos! b 0) 0)) ;; peek/read back as an utf8 string, 3 runes total (assert (equal? (io-peek b 'utf8 3) "¡¿\x00")) (assert (equal? (io-peek b 'rune 3) #arr(rune #\¡ #\¿ #\nul))) (assert (equal? (io-read b 'utf8 3) "¡¿\x00")) (assert (= (io-pos! b 0) 0)) ;; now peek a rune (assert (equal? (io-peek b 'rune) #\¡)) (assert (equal? (io-peek b 'rune) #\¡)) ;; read until #\nul (assert (equal? (io-read-until b #\nul) "¡¿\x00")) ;; read the rest as a line (assert (equal? (io-read-line b) "xyz")) ;; nothing left (assert (equal? (io-read-all b) "")) (assert (eof? (io-read b 'u8))) ;; path-cwd (assert (str? (path-cwd))) (assert (path-cwd ".")) (assert-fail (path-cwd "." ".") arity-error) (assert-fail (path-cwd "does/not/exist") io-error) ;; path-exists? + path-rename + path-delete (assert (path-exists? ".")) (assert (not (path-exists? "doesnotexist.txt"))) (assert-fail (path-delete "doesnotexist.txt") io-error) (def f (file "doesexist.txt" #o644 :write :create :truncate)) (assert (io? f)) (assert (path-exists? "doesexist.txt")) (assert-fail (io-read f 'u8) io-error) ; read on write-only (io-close f) (assert (path-exists? "doesexist.txt")) (assert-fail (file "doesexist.txt" :write :create :truncate :exclusive) io-error) (def f (file "doesexist.txt")) (assert (io? f)) (assert-fail (io-write f (u8 0)) io-error) ; write on read-only (assert (eof? (io-read f 'u8))) (assert (void? (io-close f))) (assert-fail (path-rename "doesnotexist.txt" "moved.txt")) (assert (path-rename "doesexist.txt" "moved.txt")) (assert (not (path-exists? "doesexist.txt"))) (assert (path-exists? "moved.txt")) (assert (path-delete "moved.txt")) (assert (not (path-exists? "doesexist.txt"))) (assert-fail (path-delete "moved.txt")) (def lines '("12345 абвгд weoiwhefohwefoihweoifh wefiweu3209u092039 jhksjdvksdjvbksdvb qwhqhfohwefe weofhweofhoiewhfoiwhefh\n" "hello, world!\n" "\n" "\n" "x")) (def data (apply str lines)) (def f (file "test.txt" :write :create :append :truncate)) (assert (io? f)) (assert (eq? (io-buffer-mode f) :block)) (assert-fail (io-buffer-mode!)) (assert-fail (io-buffer-mode! f)) (assert-fail (io-buffer-mode! f 'blah)) (io-buffer-mode! f :memory) (assert (eq? (io-buffer-mode! f :block) :block)) (assert (eq? (io-buffer-mode f) :block)) (assert (eq? (io-buffer-mode! f :line) :line)) (assert (eq? (io-buffer-mode f) :line)) (assert (eq? (io-buffer-mode! f NIL) NIL)) (assert (eq? (io-buffer-mode f) NIL)) (assert (eq? (io-buffer-mode! f :line) :line)) (assert (= (io-write f data) (size-of data))) (def f2 (file "test.txt")) (assert (= (io-skip f2 0 :end T) (1- (size-of data)))) (assert (io-flush f)) (assert (= (io-skip f2 0 :end T) (size-of data))) (assert (void? (io-close f2))) (assert (void? (io-close f))) (def f (file "test.txt" :read)) (assert (io? f)) (assert (equal? (io-read-lines f) lines)) (assert (= (io-line f) 5)) (assert (= (io-column f) 1)) (assert (= (io-pos! f 0) 0)) (assert (equal? (io-read-all f) data)) (assert (= (io-line f) 5)) (assert (= (io-column f) 1)) (assert-fail (io-truncate f 0)) (assert (void? (io-close f))) (assert (void? (path-delete "test.txt"))) ;; endian-specific read/write (def b (buffer)) (assert (= (io-write b (arr 'u32 #x44556677 #xa001ed0f) :big-endian) 8)) (assert (= (io-pos! b 0) 0)) (assert (= (io-peek b 'u64 :big-endian) #x44556677a001ed0f)) (assert (= (io-read b 'u64 :big-endian) #x44556677a001ed0f)) (assert (= (io-pos! b 0) 0)) (assert (= (io-peek b 'u64 :little-endian) #x0fed01a077665544)) (assert (= (io-read b 'u64 :little-endian) #x0fed01a077665544)) (assert (= (io-pos! b 0) 0)) (assert (= (io-peek b 'u32 :big-endian) #x44556677)) (assert (= (io-read b 'u32 :big-endian) #x44556677)) (assert (= (io-pos! b 0) 0)) (assert (= (io-peek b 'u32 :little-endian) #x77665544)) (assert (= (io-read b 'u32 :little-endian) #x77665544)) (assert (= (io-pos! b 0) 0)) (assert (equal? (io-peek b 'u32 1 :big-endian) (arr 'u32 #xa44556677))) (assert (equal? (io-read b 'u32 1 :big-endian) (arr 'u32 #xa44556677))) (assert (= (io-pos! b 0) 0)) (assert (equal? (io-peek b 'u32 1 :little-endian) (arr 'u32 #x77665544))) (assert (equal? (io-read b 'u32 1 :little-endian) (arr 'u32 #x77665544))) (assert (= (io-pos! b 0) 0)) (assert (equal? (io-peek b 'u16 2 :big-endian) (arr 'u16 #x4455 #x6677))) (assert (equal? (io-read b 'u16 2 :big-endian) (arr 'u16 #x4455 #x6677))) (assert (= (io-pos! b 0) 0)) (assert (equal? (io-peek b 'u16 2 :little-endian) (arr 'u16 #x5544 #x7766))) (assert (equal? (io-read b 'u16 2 :little-endian) (arr 'u16 #x5544 #x7766))) ;; aref/aset!/length with an in-memory io (def x (aref b 0)) (assert (= x #x44)) (assert (eq? (type-of x) 'u8)) (aset! b 2 #x1234) (def x (aref b 2)) (assert (= x #x34)) (assert (= (length b) 8)) (assert-fail (aset! b 8 0) bounds-error) (assert-fail (aref b 8) bounds-error) (assert-fail (aset! b -1 0) arg-error) (assert-fail (aref b -1) arg-error) ;; evaluate during read (def b (buffer)) (io-filename! b "buffer") (io-write b "#fn(unbound-symbol)") (io-pos! b 0) (assert-fail (read b) unbound-error) ;; read-only buffering of underlying data (def a "hello") (def b (buffer a)) (assert-fail (io-truncate b 0)) ; read-only - no truncation (io-discard-buffer b) ; should be a no-op (assert (equal? (io-peek b 'rune) #\h)) (assert (equal? (io-read-all b) a)) (assert (eof? (io-peek b 'rune))) (assert (io-eof? b)) (def b (buffer (u16 #x1111))) (gc) (io-discard-buffer b) ; should be a no-op (assert (= (io-read b 'u16) #x1111)) (def b (buffer (arr 'f32 1.0 2.0 3.0 -4.0))) (gc) (io-discard-buffer b) ; should be a no-op (io-pos! b 8) (assert (equal? (io-peek b 'p32 3) #arr(p32 #x40400000 #xC0800000))) (gc) (gc) (assert (equal? (io-read b 'p32 3) #arr(p32 #x40400000 #xC0800000))) (def b2 (buffer b :start 8 :end 12)) ; buffer on buffer (gc) (assert (equal? (io-peek b2 'p32 2) #arr(p32 #x40400000))) (gc) (assert (equal? (io-read b2 'p32 2) #arr(p32 #x40400000)))