Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add a unit test for owl_history

Also fix an off-by-one error in bounding the history size. May as well
have those semantics be coherent and testable.
  • Loading branch information...
commit 25891a81c52b4a7460682ef7a3773e6774e73e27 1 parent 650fb2c
@davidben davidben authored
Showing with 97 additions and 1 deletion.
  1. +7 −1 history.c
  2. +90 −0 tester.c
View
8 history.c
@@ -7,6 +7,12 @@ void owl_history_init(owl_history *h)
h->partial = false; /* is the 0th element is partially composed? */
}
+void owl_history_cleanup(owl_history *h)
+{
+ g_queue_foreach(&h->hist, (GFunc)g_free, NULL);
+ g_queue_clear(&h->hist);
+}
+
const char *owl_history_get_prev(owl_history *h)
{
if (!h) return NULL;
@@ -39,7 +45,7 @@ void owl_history_store(owl_history *h, const char *line, bool partial)
return;
/* if we've reached the max history size, pop off the last element */
- if (g_queue_get_length(&h->hist) > OWL_HISTORYSIZE)
+ if (g_queue_get_length(&h->hist) >= OWL_HISTORYSIZE)
g_free(g_queue_pop_head(&h->hist));
/* add the new line */
View
90 tester.c
@@ -22,6 +22,7 @@ int owl_obarray_regtest(void);
int owl_editwin_regtest(void);
int owl_fmtext_regtest(void);
int owl_smartfilter_regtest(void);
+int owl_history_regtest(void);
extern void owl_perl_xs_init(pTHX);
@@ -111,6 +112,7 @@ int owl_regtest(void) {
numfailures += owl_editwin_regtest();
numfailures += owl_fmtext_regtest();
numfailures += owl_smartfilter_regtest();
+ numfailures += owl_history_regtest();
if (numfailures) {
fprintf(stderr, "# *** WARNING: %d failures total\n", numfailures);
}
@@ -802,3 +804,91 @@ int owl_smartfilter_regtest(void) {
return numfailed;
}
+
+int owl_history_regtest(void)
+{
+ int numfailed = 0;
+ int i;
+ owl_history h;
+
+ printf("# BEGIN testing owl_history\n");
+ owl_history_init(&h);
+
+ /* Operations on empty history. */
+ FAIL_UNLESS("prev NULL", owl_history_get_prev(&h) == NULL);
+ FAIL_UNLESS("next NULL", owl_history_get_next(&h) == NULL);
+ FAIL_UNLESS("untouched", !owl_history_is_touched(&h));
+
+ /* Insert a few records. */
+ owl_history_store(&h, "a", false);
+ owl_history_store(&h, "b", false);
+ owl_history_store(&h, "c", false);
+ owl_history_store(&h, "d", true);
+
+ /* Walk up and down the history a bit. */
+ FAIL_UNLESS("untouched", !owl_history_is_touched(&h));
+ FAIL_UNLESS("prev c", strcmp(owl_history_get_prev(&h), "c") == 0);
+ FAIL_UNLESS("touched", owl_history_is_touched(&h));
+ FAIL_UNLESS("next d", strcmp(owl_history_get_next(&h), "d") == 0);
+ FAIL_UNLESS("untouched", !owl_history_is_touched(&h));
+ FAIL_UNLESS("next NULL", owl_history_get_next(&h) == NULL);
+ FAIL_UNLESS("prev c", strcmp(owl_history_get_prev(&h), "c") == 0);
+ FAIL_UNLESS("prev b", strcmp(owl_history_get_prev(&h), "b") == 0);
+ FAIL_UNLESS("prev a", strcmp(owl_history_get_prev(&h), "a") == 0);
+ FAIL_UNLESS("prev NULL", owl_history_get_prev(&h) == NULL);
+
+ /* Now insert something. It should reset and blow away 'd'. */
+ owl_history_store(&h, "e", false);
+ FAIL_UNLESS("untouched", !owl_history_is_touched(&h));
+ FAIL_UNLESS("next NULL", owl_history_get_next(&h) == NULL);
+ FAIL_UNLESS("prev c", strcmp(owl_history_get_prev(&h), "c") == 0);
+ FAIL_UNLESS("touched", owl_history_is_touched(&h));
+ FAIL_UNLESS("next e", strcmp(owl_history_get_next(&h), "e") == 0);
+ FAIL_UNLESS("untouched", !owl_history_is_touched(&h));
+
+ /* Lines get de-duplicated on insert. */
+ owl_history_store(&h, "e", false);
+ owl_history_store(&h, "e", false);
+ owl_history_store(&h, "e", false);
+ FAIL_UNLESS("prev c", strcmp(owl_history_get_prev(&h), "c") == 0);
+ FAIL_UNLESS("next e", strcmp(owl_history_get_next(&h), "e") == 0);
+
+ /* But a partial is not deduplicated, as it'll go away soon. */
+ owl_history_store(&h, "e", true);
+ FAIL_UNLESS("prev e", strcmp(owl_history_get_prev(&h), "e") == 0);
+ FAIL_UNLESS("prev c", strcmp(owl_history_get_prev(&h), "c") == 0);
+ FAIL_UNLESS("next e", strcmp(owl_history_get_next(&h), "e") == 0);
+ FAIL_UNLESS("next e", strcmp(owl_history_get_next(&h), "e") == 0);
+
+ /* Reset moves to the front... */
+ owl_history_store(&h, "f", true);
+ FAIL_UNLESS("prev e", strcmp(owl_history_get_prev(&h), "e") == 0);
+ FAIL_UNLESS("prev c", strcmp(owl_history_get_prev(&h), "c") == 0);
+ owl_history_reset(&h);
+ FAIL_UNLESS("untouched", !owl_history_is_touched(&h));
+ /* ...and destroys any pending partial entry... */
+ FAIL_UNLESS("prev c", strcmp(owl_history_get_prev(&h), "c") == 0);
+ FAIL_UNLESS("prev b", strcmp(owl_history_get_prev(&h), "b") == 0);
+ /* ...but not non-partial ones. */
+ owl_history_reset(&h);
+ FAIL_UNLESS("untouched", !owl_history_is_touched(&h));
+
+ /* Finally, check we are bounded by OWL_HISTORYSIZE. */
+ for (i = 0; i < OWL_HISTORYSIZE; i++) {
+ char *string = g_strdup_printf("mango%d", i);
+ owl_history_store(&h, string, false);
+ g_free(string);
+ }
+ /* The OWL_HISTORYSIZE'th prev gets NULL. */
+ for (i = OWL_HISTORYSIZE - 2; i >= 0; i--) {
+ char *string = g_strdup_printf("mango%d", i);
+ FAIL_UNLESS("prev mango_N", strcmp(owl_history_get_prev(&h), string) == 0);
+ g_free(string);
+ }
+ FAIL_UNLESS("prev NULL", owl_history_get_prev(&h) == NULL);
+
+ owl_history_cleanup(&h);
+
+ printf("# END testing owl_history (%d failures)\n", numfailed);
+ return numfailed;
+}
Please sign in to comment.
Something went wrong with that request. Please try again.