From 40e59f8805e6b980ff4960cf7090b522fdd3d81a Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Sun, 30 Oct 2016 22:01:24 -0400 Subject: [PATCH] Added more unit tests for buf.c --- Makefile | 2 +- buf.c | 19 ++- tests/buf.c | 416 +++++++++++++++++++++++++++++++++++----------------- 3 files changed, 292 insertions(+), 145 deletions(-) diff --git a/Makefile b/Makefile index d51b015..dcb9697 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ PREFIX = /usr/local GCOV = --coverage LDFLAGS = $(GCOV) -L/opt/X11/lib -lX11 -lXft -lfontconfig -CFLAGS = $(GCOV) -Os --std=gnu99 -Wall -Wextra -I. -I/opt/X11/include -I/opt/local/include/freetype2 -I/usr/include/freetype2 +CFLAGS = $(GCOV) -O0 --std=gnu99 -Wall -Wextra -I. -I/opt/X11/include -I/opt/local/include/freetype2 -I/usr/include/freetype2 OBJS = buf.o screen.o utf8.o keyboard.o mouse.o charset.o utils.o TESTOBJS = tests/tests.o tests/buf.o tests/utf8.o diff --git a/buf.c b/buf.c index fabe810..754d24f 100644 --- a/buf.c +++ b/buf.c @@ -204,8 +204,8 @@ Rune buf_get(Buf* buf, unsigned off) { } void buf_setlocked(Buf* buf, bool locked) { - if (locked) - buf->undo->locked =true; + if (locked && buf->undo) + buf->undo->locked = true; buf->locked = locked; } @@ -238,14 +238,17 @@ unsigned buf_eow(Buf* buf, unsigned off) { return off-1; } -unsigned buf_lscan(Buf* buf, unsigned off, Rune r) { - for (; r != buf_get(buf, off); off--); - return off; +unsigned buf_lscan(Buf* buf, unsigned pos, Rune r) { + unsigned off = pos; + for (; (off > 0) && (r != buf_get(buf, off)); off--); + return (buf_get(buf, off) == r ? off : pos); } -unsigned buf_rscan(Buf* buf, unsigned off, Rune r) { - for (; r != buf_get(buf, off); off++); - return off; +unsigned buf_rscan(Buf* buf, unsigned pos, Rune r) { + unsigned off = pos; + unsigned end = buf_end(buf); + for (; (off < end) && (r != buf_get(buf, off)); off++); + return (buf_get(buf, off) == r ? off : pos); } static int range_match(Buf* buf, unsigned dbeg, unsigned dend, unsigned mbeg, unsigned mend) { diff --git a/tests/buf.c b/tests/buf.c index aa3aa74..4619e8f 100644 --- a/tests/buf.c +++ b/tests/buf.c @@ -36,14 +36,43 @@ TEST_SUITE(BufferTests) { *************************************************************************/ /* Resizing *************************************************************************/ - /* Insertions - *************************************************************************/ - /* Deletions - *************************************************************************/ /* Undo/Redo *************************************************************************/ /* Locking *************************************************************************/ + TEST(buf_setlocked should lock the buffer to prevent changes) { + TestBuf.locked = false; + if (TestBuf.undo) { free(TestBuf.undo); TestBuf.undo = NULL; } + buf_setlocked(&TestBuf, true); + CHECK(TestBuf.locked); + } + + TEST(buf_setlocked should lock the buffer to prevent changes and lock the last undo op) { + Log log; + TestBuf.locked = false; + TestBuf.undo = &log; + buf_setlocked(&TestBuf, true); + CHECK(TestBuf.locked); + CHECK(TestBuf.undo->locked); + } + + TEST(buf_setlocked should unlock the buffer) { + Log log; + TestBuf.locked = true; + TestBuf.undo = &log; + buf_setlocked(&TestBuf, false); + CHECK(!TestBuf.locked); + } + + TEST(buf_islocked should return true if locked) { + TestBuf.locked = true; + CHECK(buf_locked(&TestBuf)); + } + + TEST(buf_islocked should return false if locked) { + TestBuf.locked = false; + CHECK(!buf_locked(&TestBuf)); + } /* Accessors *************************************************************************/ @@ -120,151 +149,266 @@ TEST_SUITE(BufferTests) { } // End of Line + TEST(buf_eol should return 2 if column 1 of first line) { + set_buffer_text("ab\ncd"); + CHECK(2 == buf_eol(&TestBuf, 0)); + } + + TEST(buf_eol should return 2 if column 2 of first line) { + set_buffer_text("ab\ncd"); + CHECK(2 == buf_eol(&TestBuf, 1)); + } + + TEST(buf_eol should return 2 if column 3 of first line) { + set_buffer_text("ab\ncd"); + CHECK(2 == buf_eol(&TestBuf, 2)); + } + + TEST(buf_eol should return 5 if column 1 of second line) { + set_buffer_text("ab\ncd"); + CHECK(5 == buf_eol(&TestBuf, 3)); + } + + TEST(buf_eol should return 5 if column 2 of second line) { + set_buffer_text("ab\ncd"); + CHECK(5 == buf_eol(&TestBuf, 4)); + } + + TEST(buf_eol should return 5 if column 3 of second line) { + set_buffer_text("ab\ncd"); + CHECK(5 == buf_eol(&TestBuf, 5)); + } + // Start of Word + TEST(buf_bow should return input when pointing to whitespace before word) { + set_buffer_text(" abc "); + CHECK(0 == buf_bow(&TestBuf, 0)); + } + + TEST(buf_bow should return 1 when first rune of word) { + set_buffer_text(" abc "); + CHECK(1 == buf_bow(&TestBuf, 1)); + } + + TEST(buf_bow should return 1 when second rune of word) { + set_buffer_text(" abc "); + CHECK(1 == buf_bow(&TestBuf, 2)); + } + + TEST(buf_bow should return 1 when third rune of word) { + set_buffer_text(" abc "); + CHECK(1 == buf_bow(&TestBuf, 3)); + } + + TEST(buf_bow should return input when pointing to whitespace after word) { + set_buffer_text(" abc "); + CHECK(4 == buf_bow(&TestBuf, 4)); + } + // End of Word + TEST(buf_eow should return input when pointing to whitespace before word) { + set_buffer_text(" abc "); + CHECK(0 == buf_eow(&TestBuf, 0)); + } + + TEST(buf_eow should return 3 when first rune of word) { + set_buffer_text(" abc "); + CHECK(3 == buf_eow(&TestBuf, 1)); + } + + TEST(buf_eow should return 3 when second rune of word) { + set_buffer_text(" abc "); + CHECK(3 == buf_eow(&TestBuf, 2)); + } + + TEST(buf_eow should return 3 when third rune of word) { + set_buffer_text(" abc "); + CHECK(3 == buf_eow(&TestBuf, 3)); + } + + TEST(buf_eow should return input when pointing to whitespace after word) { + set_buffer_text(" abc "); + CHECK(4 == buf_eow(&TestBuf, 4)); + } + // Scan Left + TEST(buf_lscan should return location of token to the left) { + set_buffer_text("a{bc}"); + CHECK(1 == buf_lscan(&TestBuf, 4, '{')); + } + + TEST(buf_lscan should return input location if token not found) { + set_buffer_text("{ab}"); + CHECK(3 == buf_lscan(&TestBuf, 3, '[')); + } + // Scan Right + TEST(buf_rscan should return location of token to the right) { + set_buffer_text("{ab}c"); + CHECK(3 == buf_rscan(&TestBuf, 0, '}')); + } + + TEST(buf_rscan should return input location if token not found) { + set_buffer_text("{ab}c"); + CHECK(0 == buf_rscan(&TestBuf, 0, ']')); + } + // By Rune + TEST(buf_byrune should do nothing for -1 at beginning of file) { + set_buffer_text("abc\n"); + CHECK(0 == buf_byrune(&TestBuf, 0, -1)); + } + + TEST(buf_byrune should move to first rune for -1 at second rune of file) { + set_buffer_text("abc\n"); + CHECK(0 == buf_byrune(&TestBuf, 1, -2)); + } + + TEST(buf_byrune should move to just after last rune for +1 at end of file) { + set_buffer_text("abc\n"); + CHECK(4 == buf_byrune(&TestBuf, 3, 2)); + } + + TEST(buf_byrune should move to just after last rune for +2 at second to last rune) { + set_buffer_text("abc\n"); + CHECK(4 == buf_byrune(&TestBuf, 2, 3)); + } + + TEST(buf_byrune should move from blank line to non-blank line for +1) { + set_buffer_text("ab\n\ncd\n"); + CHECK(4 == buf_byrune(&TestBuf, 3, 1)); + } + // By Line + TEST(buf_byline should not move before first line) { + set_buffer_text("ab\n\ncd\n"); + CHECK(0 == buf_byline(&TestBuf, 0, -1)); + } + + TEST(buf_byline should not move before first line) { + set_buffer_text("a\nb\nc\nd\n"); + CHECK(0 == buf_byline(&TestBuf, 7, -10)); + } + + TEST(buf_byline should move back multiple lines) { + set_buffer_text("a\nb\nc\nd\n"); + CHECK(2 == buf_byline(&TestBuf, 7, -2)); + } + + TEST(buf_byline should move back a line) { + set_buffer_text("abc\ndef"); + CHECK(0 == buf_byline(&TestBuf, 4, -1)); + } + + TEST(buf_byline should move forward a line) { + set_buffer_text("abc\ndef"); + CHECK(4 == buf_byline(&TestBuf, 2, 1)); + } + + TEST(buf_byline should not move after last line) { + set_buffer_text("abc\ndef"); + CHECK(6 == buf_byline(&TestBuf, 6, 1)); + } + + TEST(buf_byline should do nothing at end of buffer) { + set_buffer_text("abc\ndef"); + CHECK(7 == buf_byline(&TestBuf, buf_end(&TestBuf), 1)); + } /* Literal Find *************************************************************************/ + TEST(buf_find should find next occurrence of the selection) { + set_buffer_text("foofodfoo"); + unsigned beg = 0, end = 2; + buf_find(&TestBuf, &beg, &end); + CHECK(beg == 6); + CHECK(end == 8); + } + + TEST(buf_find should wrap around to beginning of file) { + set_buffer_text("foobarfoo"); + unsigned beg = 6, end = 8; + buf_find(&TestBuf, &beg, &end); + CHECK(beg == 0); + CHECK(end == 2); + } + /* Cursor Column Tracking *************************************************************************/ + TEST(buf_getcol should return the column associated with the position) { + set_buffer_text("abcdef"); + CHECK(4 == buf_getcol(&TestBuf, 4)); + } + + TEST(buf_getcol should return the column associated with the position on second line) { + set_buffer_text("abcdef\nabcdef"); + CHECK(0 == buf_getcol(&TestBuf, 7)); + } + + TEST(buf_getcol should handle tab characters) { + set_buffer_text("\tabcdef"); + CHECK(4 == buf_getcol(&TestBuf, 1)); + } + + TEST(buf_setcol should set the column to column 1 of second line) { + set_buffer_text("abc\ndef"); + CHECK(4 == buf_setcol(&TestBuf, 4, 0)); + } + + TEST(buf_setcol should set the column to column 2 of second line) { + set_buffer_text("abc\ndef"); + CHECK(5 == buf_setcol(&TestBuf, 4, 1)); + } + + TEST(buf_setcol should handle tabs) { + set_buffer_text("abc\n\tdef"); + CHECK(5 == buf_setcol(&TestBuf, 4, 4)); + } + + /* Insertions + *************************************************************************/ + TEST(buf_ins should insert at 0 in empty buf) { + buf_clr(&TestBuf); + buf_ins(&TestBuf, 0, 'a'); + CHECK(buf_text_eq("a")); + } + + TEST(buf_ins should insert at 0) { + buf_clr(&TestBuf); + buf_ins(&TestBuf, 0, 'b'); + buf_ins(&TestBuf, 0, 'a'); + CHECK(buf_text_eq("ab")); + } + + TEST(buf_ins should insert at 1) { + buf_clr(&TestBuf); + buf_ins(&TestBuf, 0, 'a'); + buf_ins(&TestBuf, 1, 'b'); + CHECK(buf_text_eq("ab")); + } + TEST(buf_ins should insert at 1) { + buf_clr(&TestBuf); + buf_ins(&TestBuf, 0, 'a'); + buf_ins(&TestBuf, 1, 'c'); + buf_ins(&TestBuf, 1, 'b'); + CHECK(buf_text_eq("abc")); + } + TEST(buf_ins should sentence in larger text) { + set_buffer_text( + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam elementum eros quis venenatis. " + ); - ///* Insertions - // *************************************************************************/ - //TEST(buf_ins should insert at 0 in empty buf) { - // buf_clr(&TestBuf); - // buf_ins(&TestBuf, 0, 'a'); - // CHECK(buf_text_eq("a")); - //} - - //TEST(buf_ins should insert at 0) { - // buf_clr(&TestBuf); - // buf_ins(&TestBuf, 0, 'b'); - // buf_ins(&TestBuf, 0, 'a'); - // CHECK(buf_text_eq("ab")); - //} - - //TEST(buf_ins should insert at 1) { - // buf_clr(&TestBuf); - // buf_ins(&TestBuf, 0, 'a'); - // buf_ins(&TestBuf, 1, 'b'); - // CHECK(buf_text_eq("ab")); - //} - - //TEST(buf_ins should insert at 1) { - // buf_clr(&TestBuf); - // buf_ins(&TestBuf, 0, 'a'); - // buf_ins(&TestBuf, 1, 'c'); - // buf_ins(&TestBuf, 1, 'b'); - // CHECK(buf_text_eq("abc")); - //} - - //TEST(buf_ins should sentence in larger text) { - // set_buffer_text( - // "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam elementum eros quis venenatis. " - // ); - - // buf_ins(&TestBuf, 5, ' '); - // buf_ins(&TestBuf, 6, 'a'); - - // CHECK(buf_text_eq( - // "Lorem a ipsum dolor sit amet, consectetur adipiscing elit. Aliquam elementum eros quis venenatis. " - // )); - //} - - ///* Deletions - // *************************************************************************/ - - ///* Beginning and End of line - // *************************************************************************/ - //TEST(buf_bol should move to first non newline character of line) { - // set_buffer_text("\nabc\n"); - // CHECK(1 == buf_bol(&TestBuf, 3)); - //} - - //TEST(buf_bol should do nothing for blank line) { - // set_buffer_text("\n\n"); - // CHECK(1 == buf_bol(&TestBuf, 1)); - //} - - //TEST(buf_eol should move to last character of line) { - // set_buffer_text("\nabc\n"); - // CHECK(4 == buf_eol(&TestBuf, 1)); - //} - - //TEST(buf_eol should do nothing for blank line) { - // set_buffer_text("\n\n"); - // CHECK(1 == buf_eol(&TestBuf, 1)); - //} - - ///* Movement by Rune - // *************************************************************************/ - //TEST(buf_byrune should do nothing for -1 at beginning of file) - //{ - // set_buffer_text("abc\n"); - // CHECK(0 == buf_byrune(&TestBuf, 0, -1)); - //} - - //TEST(buf_byrune should do nothing for -2 at beginning of file) - //{ - // set_buffer_text("abc\n"); - // CHECK(0 == buf_byrune(&TestBuf, 0, -2)); - //} - - //TEST(buf_byrune should move to just after last rune for +1 at end of file) - //{ - // set_buffer_text("abc\n"); - // CHECK(4 == buf_byrune(&TestBuf, 3, 1)); - //} - - //TEST(buf_byrune should move to just after last rune for +2 at end of file) - //{ - // set_buffer_text("abc\n"); - // CHECK(4 == buf_byrune(&TestBuf, 3, 2)); - //} - - ////TEST(buf_byrune should skip newlines for -1) - ////{ - //// set_buffer_text("ab\ncd\n"); - //// CHECK(1 == buf_byrune(&TestBuf, 3, -1)); - ////} - - ////TEST(buf_byrune should skip newlines for +1) - ////{ - //// set_buffer_text("ab\ncd\n"); - //// CHECK(3 == buf_byrune(&TestBuf, 1, 1)); - ////} - - ////TEST(buf_byrune should not skip blank lines for -1) - ////{ - //// set_buffer_text("ab\n\ncd\n"); - //// CHECK(3 == buf_byrune(&TestBuf, 4, -1)); - ////} - - ////TEST(buf_byrune should not skip blank lines for +1) - ////{ - //// set_buffer_text("ab\n\ncd\n"); - //// CHECK(3 == buf_byrune(&TestBuf, 1, 1)); - ////} - - ////TEST(buf_byrune should move from blank line to non-blank line for -1) - ////{ - //// set_buffer_text("ab\n\ncd\n"); - //// CHECK(1 == buf_byrune(&TestBuf, 3, -1)); - ////} - - //TEST(buf_byrune should move from blank line to non-blank line for +1) - //{ - // set_buffer_text("ab\n\ncd\n"); - // CHECK(4 == buf_byrune(&TestBuf, 3, 1)); - //} - - ///* Movement by Line - // *************************************************************************/ + buf_ins(&TestBuf, 5, ' '); + buf_ins(&TestBuf, 6, 'a'); + + CHECK(buf_text_eq( + "Lorem a ipsum dolor sit amet, consectetur adipiscing elit. Aliquam elementum eros quis venenatis. " + )); + } + + /* Deletions + *************************************************************************/ } -- 2.49.0