From ff8898476685e6b7dff03231275a6a8bc2cbaf17 Mon Sep 17 00:00:00 2001 From: "Rafael G. Martins" Date: Fri, 11 Sep 2020 01:07:43 +0200 Subject: blogc: generate table of contents tree this commit allows users to use the `{{ TOCTREE }}` variable in their templates, to get automatically generated table of contents for entries. The variable is binded to each entry, so it can be used in any block that runs in entry context, like `{% block entry %}`. There's a small performance penalty for this, because the table of contents is rendered for any entry, despite being used or not, and not generated on-demand. still missing documentation. tests are good enough. --- .gitignore | 3 + Makefile.am | 21 ++ src/blogc/content-parser.c | 34 +- src/blogc/content-parser.h | 6 +- src/blogc/loader.c | 20 +- src/blogc/loader.h | 5 +- src/blogc/main.c | 2 +- src/blogc/source-parser.c | 36 ++- src/blogc/source-parser.h | 4 +- src/blogc/toctree.c | 103 ++++++ src/blogc/toctree.h | 26 ++ tests/blogc/check_content_parser.c | 625 ++++++++++++++++++++++++++++++------- tests/blogc/check_loader.c | 88 +++++- tests/blogc/check_renderer.c | 2 +- tests/blogc/check_source_parser.c | 238 ++++++++++++-- tests/blogc/check_toctree.c | 234 ++++++++++++++ 16 files changed, 1283 insertions(+), 164 deletions(-) create mode 100644 src/blogc/toctree.c create mode 100644 src/blogc/toctree.h create mode 100644 tests/blogc/check_toctree.c diff --git a/.gitignore b/.gitignore index 5336760..659c5f2 100644 --- a/.gitignore +++ b/.gitignore @@ -66,6 +66,7 @@ blogc*.html /tests/blogc/check_sysinfo /tests/blogc/check_sysinfo2 /tests/blogc/check_template_parser +/tests/blogc/check_toctree /tests/blogc-git-receiver/check_pre_receive_parser /tests/blogc-git-receiver/check_pre_receive.sh /tests/blogc-git-receiver/check_post_receive.sh @@ -105,3 +106,5 @@ blogc-*.rpm /root/ /maint/releases/ + +.gdb_history diff --git a/Makefile.am b/Makefile.am index 3f00119..8eae1d3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -48,6 +48,7 @@ noinst_HEADERS = \ src/blogc/sysinfo.h \ src/blogc/source-parser.h \ src/blogc/template-parser.h \ + src/blogc/toctree.h \ src/blogc-git-receiver/post-receive.h \ src/blogc-git-receiver/pre-receive.h \ src/blogc-git-receiver/pre-receive-parser.h \ @@ -137,6 +138,7 @@ libblogc_la_SOURCES = \ src/blogc/sysinfo.c \ src/blogc/source-parser.c \ src/blogc/template-parser.c \ + src/blogc/toctree.c \ $(NULL) libblogc_la_CFLAGS = \ @@ -474,6 +476,7 @@ check_PROGRAMS += \ tests/blogc/check_renderer \ tests/blogc/check_source_parser \ tests/blogc/check_template_parser \ + tests/blogc/check_toctree \ tests/common/check_config_parser \ tests/common/check_error \ tests/common/check_sort \ @@ -735,6 +738,24 @@ tests_blogc_check_template_parser_LDADD = \ libblogc_common.la \ $(NULL) +tests_blogc_check_toctree_SOURCES = \ + tests/blogc/check_toctree.c \ + $(NULL) + +tests_blogc_check_toctree_CFLAGS = \ + $(CMOCKA_CFLAGS) \ + $(NULL) + +tests_blogc_check_toctree_LDFLAGS = \ + -no-install \ + $(NULL) + +tests_blogc_check_toctree_LDADD = \ + $(CMOCKA_LIBS) \ + libblogc.la \ + libblogc_common.la \ + $(NULL) + tests_common_check_config_parser_SOURCES = \ tests/common/check_config_parser.c \ $(NULL) diff --git a/src/blogc/content-parser.c b/src/blogc/content-parser.c index 047af4b..a42f6f6 100644 --- a/src/blogc/content-parser.c +++ b/src/blogc/content-parser.c @@ -1,6 +1,6 @@ /* * blogc: A blog compiler. - * Copyright (C) 2014-2019 Rafael G. Martins + * Copyright (C) 2014-2020 Rafael G. Martins * * This program can be distributed under the terms of the BSD License. * See the file LICENSE. @@ -11,6 +11,7 @@ #include #include "content-parser.h" +#include "toctree.h" #include "../common/utils.h" // this is a half ass implementation of a markdown-like syntax. bugs are @@ -676,7 +677,7 @@ blogc_is_ordered_list_item(const char *str, size_t prefix_len) char* blogc_content_parse(const char *src, size_t *end_excerpt, char **first_header, - char **description) + char **description, char **endl, bc_slist_t **headers) { // src is always nul-terminated. size_t src_len = strlen(src); @@ -696,11 +697,28 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **first_header, char *parsed = NULL; char *slug = NULL; + char *line_ending = NULL; + bool line_ending_found = false; + if (endl != NULL) { + if (*endl != NULL) { + line_ending_found = true; + } + else { + *endl = bc_malloc(3 * sizeof(char)); + } + line_ending = *endl; + } + else { + line_ending = bc_malloc(3 * sizeof(char)); + } + // this isn't empty because we need some reasonable default value in the // unlikely case that we need to print some line ending before evaluating // the "real" value. - char line_ending[3] = "\n"; - bool line_ending_found = false; + if (!line_ending_found) { + line_ending[0] = '\n'; + line_ending[1] = '\0'; + } char d = '\0'; @@ -840,6 +858,8 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **first_header, *first_header = blogc_htmlentities(tmp); parsed = blogc_content_parse_inline(tmp); slug = blogc_slugify(tmp); + if (headers != NULL) + *headers = blogc_toctree_append(*headers, header_level, slug, parsed); if (slug == NULL) bc_string_append_printf(rv, "%s%s", header_level, parsed, header_level, line_ending); @@ -922,7 +942,7 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **first_header, // do not propagate title and description to blockquote parsing, // because we just want paragraphs from first level of // content. - tmp = blogc_content_parse(tmp_str->str, NULL, NULL, NULL); + tmp = blogc_content_parse(tmp_str->str, NULL, NULL, NULL, endl, NULL); bc_string_append_printf(rv, "
%s
%s", tmp, line_ending); free(tmp); @@ -1280,5 +1300,9 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **first_header, current++; } + if (endl == NULL) { + free(line_ending); + } + return bc_string_free(rv, false); } diff --git a/src/blogc/content-parser.h b/src/blogc/content-parser.h index ea5d29d..a321155 100644 --- a/src/blogc/content-parser.h +++ b/src/blogc/content-parser.h @@ -1,6 +1,6 @@ /* * blogc: A blog compiler. - * Copyright (C) 2014-2019 Rafael G. Martins + * Copyright (C) 2014-2020 Rafael G. Martins * * This program can be distributed under the terms of the BSD License. * See the file LICENSE. @@ -11,6 +11,7 @@ #include #include +#include "../common/utils.h" char* blogc_slugify(const char *str); char* blogc_htmlentities(const char *str); @@ -18,6 +19,7 @@ char* blogc_fix_description(const char *paragraph); char* blogc_content_parse_inline(const char *src); bool blogc_is_ordered_list_item(const char *str, size_t prefix_len); char* blogc_content_parse(const char *src, size_t *end_excerpt, - char **first_header, char **description); + char **first_header, char **description, char **endl, + bc_slist_t **headers); #endif /* _CONTENT_PARSER_H */ diff --git a/src/blogc/loader.c b/src/blogc/loader.c index d620988..4e03ec3 100644 --- a/src/blogc/loader.c +++ b/src/blogc/loader.c @@ -1,6 +1,6 @@ /* * blogc: A blog compiler. - * Copyright (C) 2014-2019 Rafael G. Martins + * Copyright (C) 2014-2020 Rafael G. Martins * * This program can be distributed under the terms of the BSD License. * See the file LICENSE. @@ -76,7 +76,7 @@ blogc_template_parse_from_file(const char *f, bc_error_t **err) bc_trie_t* -blogc_source_parse_from_file(const char *f, bc_error_t **err) +blogc_source_parse_from_file(bc_trie_t *conf, const char *f, bc_error_t **err) { if (err == NULL || *err != NULL) return NULL; @@ -85,7 +85,19 @@ blogc_source_parse_from_file(const char *f, bc_error_t **err) char *s = bc_file_get_contents(f, true, &len, err); if (s == NULL) return NULL; - bc_trie_t *rv = blogc_source_parse(s, len, err); + + int toctree_maxdepth = -1; + const char *maxdepth = bc_trie_lookup(conf, "TOCTREE_MAXDEPTH"); + if (maxdepth != NULL) { + char *endptr; + toctree_maxdepth = strtol(maxdepth, &endptr, 10); + if (*maxdepth != '\0' && *endptr != '\0') { + fprintf(stderr, "warning: invalid value for 'TOCTREE_MAXDEPTH' " + "variable: %s. using %d instead\n", maxdepth, toctree_maxdepth); + } + } + + bc_trie_t *rv = blogc_source_parse(s, len, toctree_maxdepth, err); // set FILENAME variable if (rv != NULL) { @@ -133,7 +145,7 @@ blogc_source_parse_from_files(bc_trie_t *conf, bc_slist_t *l, bc_error_t **err) size_t with_date = 0; for (bc_slist_t *tmp = l; tmp != NULL; tmp = tmp->next) { char *f = tmp->data; - bc_trie_t *s = blogc_source_parse_from_file(f, &tmp_err); + bc_trie_t *s = blogc_source_parse_from_file(conf, f, &tmp_err); if (s == NULL) { *err = bc_error_new_printf(BLOGC_ERROR_LOADER, "An error occurred while parsing source file: %s\n\n%s", diff --git a/src/blogc/loader.h b/src/blogc/loader.h index 66da7d0..fe88730 100644 --- a/src/blogc/loader.h +++ b/src/blogc/loader.h @@ -1,6 +1,6 @@ /* * blogc: A blog compiler. - * Copyright (C) 2014-2019 Rafael G. Martins + * Copyright (C) 2014-2020 Rafael G. Martins * * This program can be distributed under the terms of the BSD License. * See the file LICENSE. @@ -14,7 +14,8 @@ char* blogc_get_filename(const char *f); bc_slist_t* blogc_template_parse_from_file(const char *f, bc_error_t **err); -bc_trie_t* blogc_source_parse_from_file(const char *f, bc_error_t **err); +bc_trie_t* blogc_source_parse_from_file(bc_trie_t *conf, const char *f, + bc_error_t **err); bc_slist_t* blogc_source_parse_from_files(bc_trie_t *conf, bc_slist_t *l, bc_error_t **err); diff --git a/src/blogc/main.c b/src/blogc/main.c index f952957..7024967 100644 --- a/src/blogc/main.c +++ b/src/blogc/main.c @@ -307,7 +307,7 @@ main(int argc, char **argv) listing_entries_source = bc_slist_append(listing_entries_source, NULL); continue; } - bc_trie_t *e = blogc_source_parse_from_file(tmp->data, &err); + bc_trie_t *e = blogc_source_parse_from_file(config, tmp->data, &err); if (err != NULL) { bc_error_print(err, "blogc"); rv = 1; diff --git a/src/blogc/source-parser.c b/src/blogc/source-parser.c index 18cf95a..13df9e3 100644 --- a/src/blogc/source-parser.c +++ b/src/blogc/source-parser.c @@ -1,6 +1,6 @@ /* * blogc: A blog compiler. - * Copyright (C) 2014-2019 Rafael G. Martins + * Copyright (C) 2014-2020 Rafael G. Martins * * This program can be distributed under the terms of the BSD License. * See the file LICENSE. @@ -11,6 +11,7 @@ #include "content-parser.h" #include "source-parser.h" +#include "toctree.h" #include "../common/error.h" #include "../common/utils.h" @@ -27,7 +28,8 @@ typedef enum { bc_trie_t* -blogc_source_parse(const char *src, size_t src_len, bc_error_t **err) +blogc_source_parse(const char *src, size_t src_len, int toctree_maxdepth, + bc_error_t **err) { if (err == NULL || *err != NULL) return NULL; @@ -153,8 +155,11 @@ blogc_source_parse(const char *src, size_t src_len, bc_error_t **err) bc_trie_insert(rv, "RAW_CONTENT", tmp); char *first_header = NULL; char *description = NULL; + char *endl = NULL; + bc_slist_t *headers = NULL; + bool read_headers = (NULL == bc_trie_lookup(rv, "TOCTREE")); content = blogc_content_parse(tmp, &end_excerpt, - &first_header, &description); + &first_header, &description, &endl, read_headers ? &headers : NULL); if (first_header != NULL) { // do not override source-provided first_header. if (NULL == bc_trie_lookup(rv, "FIRST_HEADER")) { @@ -177,6 +182,31 @@ blogc_source_parse(const char *src, size_t src_len, bc_error_t **err) free(description); } } + if (headers != NULL) { + // we already validated that the user do not defined TOCTREE + // manually in source file. + const char *maxdepth = bc_trie_lookup(rv, "TOCTREE_MAXDEPTH"); + if (maxdepth != NULL) { + char *endptr; + toctree_maxdepth = strtol(maxdepth, &endptr, 10); + if (*maxdepth != '\0' && *endptr != '\0') { + *err = bc_error_parser(BLOGC_ERROR_SOURCE_PARSER, src, src_len, + current, + "Invalid value for 'TOCTREE_MAXDEPTH' variable: %s.", + maxdepth); + blogc_toctree_free(headers); + free(endl); + free(content); + break; + } + } + char *toctree = blogc_toctree_render(headers, toctree_maxdepth, endl); + blogc_toctree_free(headers); + if (toctree != NULL) { + bc_trie_insert(rv, "TOCTREE", toctree); + } + } + free(endl); bc_trie_insert(rv, "CONTENT", content); bc_trie_insert(rv, "EXCERPT", end_excerpt == 0 ? bc_strdup(content) : bc_strndup(content, end_excerpt)); diff --git a/src/blogc/source-parser.h b/src/blogc/source-parser.h index 8672fb0..2acd753 100644 --- a/src/blogc/source-parser.h +++ b/src/blogc/source-parser.h @@ -1,6 +1,6 @@ /* * blogc: A blog compiler. - * Copyright (C) 2014-2019 Rafael G. Martins + * Copyright (C) 2014-2020 Rafael G. Martins * * This program can be distributed under the terms of the BSD License. * See the file LICENSE. @@ -13,7 +13,7 @@ #include "../common/error.h" #include "../common/utils.h" -bc_trie_t* blogc_source_parse(const char *src, size_t src_len, +bc_trie_t* blogc_source_parse(const char *src, size_t src_len, int toctree_maxdepth, bc_error_t **err); #endif /* _SOURCE_PARSER_H */ diff --git a/src/blogc/toctree.c b/src/blogc/toctree.c new file mode 100644 index 0000000..307c62c --- /dev/null +++ b/src/blogc/toctree.c @@ -0,0 +1,103 @@ +/* + * blogc: A blog compiler. + * Copyright (C) 2014-2020 Rafael G. Martins + * + * This program can be distributed under the terms of the BSD License. + * See the file LICENSE. + */ + +#include +#include "../common/utils.h" +#include "toctree.h" + +bc_slist_t* +blogc_toctree_append(bc_slist_t *headers, size_t level, const char *slug, const char *text) +{ + if (level == 0) + return headers; + + blogc_toctree_header_t *t = bc_malloc(sizeof(blogc_toctree_header_t)); + t->level = level; + t->slug = bc_strdup(slug); + t->text = bc_strdup(text); + return bc_slist_append(headers, t); +} + + +char* +blogc_toctree_render(bc_slist_t *headers, int maxdepth, const char *endl) +{ + if (headers == NULL || maxdepth == 0) + return NULL; + + // find lower level + size_t lower_level = 0; + for (bc_slist_t *l = headers; l != NULL; l = l->next) { + size_t lv = ((blogc_toctree_header_t*) l->data)->level; + if (lower_level == 0 || lower_level > lv) { + lower_level = lv; + } + } + + if (lower_level == 0) + return NULL; + + // render + bc_string_t *rv = bc_string_new(); + bc_string_append_printf(rv, "
    %s", endl == NULL ? "\n" : endl); + size_t spacing = 4; + size_t current_level = lower_level; + for (bc_slist_t *l = headers; l != NULL; l = l->next) { + blogc_toctree_header_t *t = l->data; + if (t->level - lower_level >= maxdepth) { + continue; + } + while (current_level > t->level) { + spacing -= 4; + bc_string_append_printf(rv, "%*s
%s", spacing, "", + endl == NULL ? "\n" : endl); + current_level--; + } + while (current_level < t->level) { + bc_string_append_printf(rv, "%*s
    %s", spacing, "", + endl == NULL ? "\n" : endl); + current_level++; + spacing += 4; + } + bc_string_append_printf(rv, "%*s
  • ", spacing, ""); + if (t->slug != NULL) { + bc_string_append_printf(rv, "%s", t->slug, + t->text != NULL ? t->text : ""); + } + else { + bc_string_append(rv, t->text); + } + bc_string_append_printf(rv, "
  • %s", endl == NULL ? "\n" : endl); + } + + // close leftovers + while (current_level >= lower_level) { + spacing -= 4; + bc_string_append_printf(rv, "%*s
%s", spacing, "", + endl == NULL ? "\n" : endl); + current_level--; + } + + return bc_string_free(rv, false); +} + + +static void +free_header(blogc_toctree_header_t *h) +{ + free(h->slug); + free(h->text); + free(h); +} + + +void +blogc_toctree_free(bc_slist_t *l) +{ + bc_slist_free_full(l, (bc_free_func_t) free_header); +} diff --git a/src/blogc/toctree.h b/src/blogc/toctree.h new file mode 100644 index 0000000..460119b --- /dev/null +++ b/src/blogc/toctree.h @@ -0,0 +1,26 @@ +/* + * blogc: A blog compiler. + * Copyright (C) 2014-2020 Rafael G. Martins + * + * This program can be distributed under the terms of the BSD License. + * See the file LICENSE. + */ + +#ifndef ___TOCTREE_H +#define ___TOCTREE_H + +#include "../common/utils.h" + +typedef struct { + size_t level; + char *slug; + char *text; +} blogc_toctree_header_t; + +bc_slist_t* blogc_toctree_append(bc_slist_t *headers, size_t level, + const char *slug, const char *text); +char* blogc_toctree_render(bc_slist_t *headers, int maxdepth, + const char *endl); +void blogc_toctree_free(bc_slist_t *l); + +#endif /* ___TOCTREE_H */ diff --git a/tests/blogc/check_content_parser.c b/tests/blogc/check_content_parser.c index de15bac..5fa8f06 100644 --- a/tests/blogc/check_content_parser.c +++ b/tests/blogc/check_content_parser.c @@ -1,6 +1,6 @@ /* * blogc: A blog compiler. - * Copyright (C) 2014-2019 Rafael G. Martins + * Copyright (C) 2014-2020 Rafael G. Martins * * This program can be distributed under the terms of the BSD License. * See the file LICENSE. @@ -11,6 +11,7 @@ #include #include #include +#include "../../src/blogc/toctree.h" #include "../../src/blogc/content-parser.h" @@ -125,6 +126,8 @@ test_content_parse(void **state) size_t l = 0; char *t = NULL; char *d = NULL; + char *n = NULL; + bc_slist_t *h = NULL; char *html = blogc_content_parse( "# um\n" "## dois\n" @@ -166,13 +169,17 @@ test_content_parse(void **state) "\n" "-- asd\n" "\n" - "--- lol\n", &l, &t, &d); + "--- lol\n", &l, &t, &d, &n, &h); assert_non_null(html); assert_int_equal(l, 0); assert_non_null(t); assert_string_equal(t, "um"); assert_non_null(d); assert_string_equal(d, "bola chunda"); + assert_non_null(n); + assert_string_equal(n, "\n"); + assert_non_null(h); + assert_int_equal(bc_slist_length(h), 6); assert_string_equal(html, "

um

\n" "

dois

\n" @@ -212,6 +219,8 @@ test_content_parse(void **state) free(html); free(t); free(d); + free(n); + blogc_toctree_free(h); } @@ -221,6 +230,8 @@ test_content_parse_crlf(void **state) size_t l = 0; char *t = NULL; char *d = NULL; + char *n = NULL; + bc_slist_t *h = NULL; char *html = blogc_content_parse( "# um\r\n" "## dois\r\n" @@ -262,13 +273,17 @@ test_content_parse_crlf(void **state) "\r\n" "-- asd\r\n" "\r\n" - "--- lol\r\n", &l, &t, &d); + "--- lol\r\n", &l, &t, &d, &n, &h); assert_non_null(html); assert_int_equal(l, 0); assert_non_null(t); assert_string_equal(t, "um"); assert_non_null(d); assert_string_equal(d, "bola chunda"); + assert_non_null(n); + assert_string_equal(n, "\r\n"); + assert_non_null(h); + assert_int_equal(bc_slist_length(h), 6); assert_string_equal(html, "

um

\r\n" "

dois

\r\n" @@ -308,6 +323,8 @@ test_content_parse_crlf(void **state) free(html); free(t); free(d); + free(n); + blogc_toctree_free(h); } @@ -317,6 +334,8 @@ test_content_parse_with_excerpt(void **state) size_t l = 0; char *t = NULL; char *d = NULL; + char *n = NULL; + bc_slist_t *h = NULL; char *html = blogc_content_parse( "# test\n" "\n" @@ -325,13 +344,17 @@ test_content_parse_with_excerpt(void **state) "..\n" "\n" "guda\n" - "lol", &l, &t, &d); + "lol", &l, &t, &d, &n, &h); assert_non_null(html); assert_int_equal(l, 38); assert_non_null(t); assert_string_equal(t, "test"); assert_non_null(d); assert_string_equal(d, "chunda"); + assert_non_null(n); + assert_string_equal(n, "\n"); + assert_non_null(h); + assert_int_equal(bc_slist_length(h), 1); assert_string_equal(html, "

test

\n" "

chunda

\n" @@ -341,8 +364,12 @@ test_content_parse_with_excerpt(void **state) l = 0; free(t); free(d); + free(n); + blogc_toctree_free(h); t = NULL; d = NULL; + n = NULL; + h = NULL; html = blogc_content_parse( "# test\n" "\n" @@ -351,13 +378,17 @@ test_content_parse_with_excerpt(void **state) "...\n" "\n" "guda\n" - "lol", &l, &t, &d); + "lol", &l, &t, &d, &n, &h); assert_non_null(html); assert_int_equal(l, 38); assert_non_null(t); assert_string_equal(t, "test"); assert_non_null(d); assert_string_equal(d, "chunda"); + assert_non_null(n); + assert_string_equal(n, "\n"); + assert_non_null(h); + assert_int_equal(bc_slist_length(h), 1); assert_string_equal(html, "

test

\n" "

chunda

\n" @@ -366,6 +397,8 @@ test_content_parse_with_excerpt(void **state) free(html); free(t); free(d); + free(n); + blogc_toctree_free(h); } @@ -375,6 +408,8 @@ test_content_parse_with_excerpt_crlf(void **state) size_t l = 0; char *t = NULL; char *d = NULL; + char *n = NULL; + bc_slist_t *h = NULL; char *html = blogc_content_parse( "# test\r\n" "\r\n" @@ -383,13 +418,17 @@ test_content_parse_with_excerpt_crlf(void **state) "..\r\n" "\r\n" "guda\r\n" - "lol", &l, &t, &d); + "lol", &l, &t, &d, &n, &h); assert_non_null(html); assert_int_equal(l, 40); assert_non_null(t); assert_string_equal(t, "test"); assert_non_null(d); assert_string_equal(d, "chunda"); + assert_non_null(n); + assert_string_equal(n, "\r\n"); + assert_non_null(h); + assert_int_equal(bc_slist_length(h), 1); assert_string_equal(html, "

test

\r\n" "

chunda

\r\n" @@ -399,8 +438,12 @@ test_content_parse_with_excerpt_crlf(void **state) l = 0; free(t); free(d); + free(n); + blogc_toctree_free(h); t = NULL; d = NULL; + n = NULL; + h = NULL; html = blogc_content_parse( "# test\r\n" "\r\n" @@ -409,13 +452,17 @@ test_content_parse_with_excerpt_crlf(void **state) "...\r\n" "\r\n" "guda\r\n" - "lol", &l, &t, &d); + "lol", &l, &t, &d, &n, &h); assert_non_null(html); assert_int_equal(l, 40); assert_non_null(t); assert_string_equal(t, "test"); assert_non_null(d); assert_string_equal(d, "chunda"); + assert_non_null(n); + assert_string_equal(n, "\r\n"); + assert_non_null(h); + assert_int_equal(bc_slist_length(h), 1); assert_string_equal(html, "

test

\r\n" "

chunda

\r\n" @@ -424,17 +471,19 @@ test_content_parse_with_excerpt_crlf(void **state) free(html); free(t); free(d); + free(n); + blogc_toctree_free(h); } static void test_content_parse_header(void **state) { - char *html = blogc_content_parse("## bola", NULL, NULL, NULL); + char *html = blogc_content_parse("## bola", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

bola

\n"); free(html); - html = blogc_content_parse("## bola\n", NULL, NULL, NULL); + html = blogc_content_parse("## bola\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

bola

\n"); free(html); @@ -443,7 +492,7 @@ test_content_parse_header(void **state) "\n" "## bola\n" "\n" - "guda\n", NULL, NULL, NULL); + "guda\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

bola

\n" @@ -456,11 +505,11 @@ test_content_parse_header(void **state) static void test_content_parse_header_crlf(void **state) { - char *html = blogc_content_parse("## bola", NULL, NULL, NULL); + char *html = blogc_content_parse("## bola", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

bola

\n"); free(html); - html = blogc_content_parse("## bola\r\n", NULL, NULL, NULL); + html = blogc_content_parse("## bola\r\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

bola

\r\n"); free(html); @@ -469,7 +518,7 @@ test_content_parse_header_crlf(void **state) "\r\n" "## bola\r\n" "\r\n" - "guda\r\n", NULL, NULL, NULL); + "guda\r\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

bola

\r\n" @@ -482,11 +531,11 @@ test_content_parse_header_crlf(void **state) static void test_content_parse_html(void **state) { - char *html = blogc_content_parse("
\n
", NULL, NULL, NULL); + char *html = blogc_content_parse("
\n
", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "
\n
\n"); free(html); - html = blogc_content_parse("
\n
\n", NULL, NULL, NULL); + html = blogc_content_parse("
\n
\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "
\n
\n"); free(html); @@ -496,7 +545,7 @@ test_content_parse_html(void **state) "
\n" "
\n" "\n" - "chunda\n", NULL, NULL, NULL); + "chunda\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

bola

\n" @@ -509,11 +558,11 @@ test_content_parse_html(void **state) static void test_content_parse_html_crlf(void **state) { - char *html = blogc_content_parse("
\r\n
", NULL, NULL, NULL); + char *html = blogc_content_parse("
\r\n
", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "
\r\n
\r\n"); free(html); - html = blogc_content_parse("
\r\n
\r\n", NULL, NULL, NULL); + html = blogc_content_parse("
\r\n
\r\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "
\r\n
\r\n"); free(html); @@ -523,7 +572,7 @@ test_content_parse_html_crlf(void **state) "
\r\n" "
\r\n" "\r\n" - "chunda\r\n", NULL, NULL, NULL); + "chunda\r\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

bola

\r\n" @@ -536,14 +585,14 @@ test_content_parse_html_crlf(void **state) static void test_content_parse_blockquote(void **state) { - char *html = blogc_content_parse("> bola\n> guda", NULL, NULL, NULL); + char *html = blogc_content_parse("> bola\n> guda", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

bola\n" "guda

\n" "
\n"); free(html); - html = blogc_content_parse("> bola\n> guda\n", NULL, NULL, NULL); + html = blogc_content_parse("> bola\n> guda\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

bola\n" @@ -555,7 +604,7 @@ test_content_parse_blockquote(void **state) "\n" "> bola\n" "\n" - "chunda\n", NULL, NULL, NULL); + "chunda\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

bola

\n" @@ -569,7 +618,7 @@ test_content_parse_blockquote(void **state) "> bola\n" "> guda\n" "\n" - "chunda\n", NULL, NULL, NULL); + "chunda\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

bola

\n" @@ -584,14 +633,14 @@ test_content_parse_blockquote(void **state) static void test_content_parse_blockquote_crlf(void **state) { - char *html = blogc_content_parse("> bola\r\n> guda", NULL, NULL, NULL); + char *html = blogc_content_parse("> bola\r\n> guda", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

bola\r\n" "guda

\r\n" "
\r\n"); free(html); - html = blogc_content_parse("> bola\r\n> guda\r\n", NULL, NULL, NULL); + html = blogc_content_parse("> bola\r\n> guda\r\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

bola\r\n" @@ -603,7 +652,7 @@ test_content_parse_blockquote_crlf(void **state) "\r\n" "> bola\r\n" "\r\n" - "chunda\r\n", NULL, NULL, NULL); + "chunda\r\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

bola

\r\n" @@ -617,7 +666,7 @@ test_content_parse_blockquote_crlf(void **state) "> bola\r\n" "> guda\r\n" "\r\n" - "chunda\r\n", NULL, NULL, NULL); + "chunda\r\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

bola

\r\n" @@ -632,13 +681,13 @@ test_content_parse_blockquote_crlf(void **state) static void test_content_parse_code(void **state) { - char *html = blogc_content_parse(" bola\n guda", NULL, NULL, NULL); + char *html = blogc_content_parse(" bola\n guda", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "
bola\n"
         "guda
\n"); free(html); - html = blogc_content_parse(" bola\n guda\n", NULL, NULL, NULL); + html = blogc_content_parse(" bola\n guda\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "
bola\n"
@@ -650,7 +699,7 @@ test_content_parse_code(void **state)
         "   bola\n"
         "   guda\n"
         "\n"
-        "chunda\n", NULL, NULL, NULL);
+        "chunda\n", NULL, NULL, NULL, NULL, NULL);
     assert_non_null(html);
     assert_string_equal(html,
         "

bola

\n" @@ -664,13 +713,13 @@ test_content_parse_code(void **state) static void test_content_parse_code_crlf(void **state) { - char *html = blogc_content_parse(" bola\r\n guda", NULL, NULL, NULL); + char *html = blogc_content_parse(" bola\r\n guda", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "
bola\r\n"
         "guda
\r\n"); free(html); - html = blogc_content_parse(" bola\r\n guda\r\n", NULL, NULL, NULL); + html = blogc_content_parse(" bola\r\n guda\r\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "
bola\r\n"
@@ -682,7 +731,7 @@ test_content_parse_code_crlf(void **state)
         "   bola\r\n"
         "   guda\r\n"
         "\r\n"
-        "chunda\r\n", NULL, NULL, NULL);
+        "chunda\r\n", NULL, NULL, NULL, NULL, NULL);
     assert_non_null(html);
     assert_string_equal(html,
         "

bola

\r\n" @@ -696,28 +745,28 @@ test_content_parse_code_crlf(void **state) static void test_content_parse_horizontal_rule(void **state) { - char *html = blogc_content_parse("bola\nguda\n\n***", NULL, NULL, NULL); + char *html = blogc_content_parse("bola\nguda\n\n***", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

bola\n" "guda

\n" "
\n"); free(html); - html = blogc_content_parse("bola\nguda\n\n++++", NULL, NULL, NULL); + html = blogc_content_parse("bola\nguda\n\n++++", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

bola\n" "guda

\n" "
\n"); free(html); - html = blogc_content_parse("bola\nguda\n\n---\n", NULL, NULL, NULL); + html = blogc_content_parse("bola\nguda\n\n---\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

bola\n" "guda

\n" "
\n"); free(html); - html = blogc_content_parse("bola\nguda\n\n****\n", NULL, NULL, NULL); + html = blogc_content_parse("bola\nguda\n\n****\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

bola\n" @@ -729,7 +778,7 @@ test_content_parse_horizontal_rule(void **state) "\n" "***\n" "\n" - "chunda\n", NULL, NULL, NULL); + "chunda\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

bola

\n" @@ -741,7 +790,7 @@ test_content_parse_horizontal_rule(void **state) "\n" "----\n" "\n" - "chunda\n", NULL, NULL, NULL); + "chunda\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

bola

\n" @@ -754,28 +803,28 @@ test_content_parse_horizontal_rule(void **state) static void test_content_parse_horizontal_rule_crlf(void **state) { - char *html = blogc_content_parse("bola\r\nguda\r\n\r\n***", NULL, NULL, NULL); + char *html = blogc_content_parse("bola\r\nguda\r\n\r\n***", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

bola\r\n" "guda

\r\n" "
\r\n"); free(html); - html = blogc_content_parse("bola\r\nguda\r\n\r\n++++", NULL, NULL, NULL); + html = blogc_content_parse("bola\r\nguda\r\n\r\n++++", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

bola\r\n" "guda

\r\n" "
\r\n"); free(html); - html = blogc_content_parse("bola\r\nguda\r\n\r\n---\r\n", NULL, NULL, NULL); + html = blogc_content_parse("bola\r\nguda\r\n\r\n---\r\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

bola\r\n" "guda

\r\n" "
\r\n"); free(html); - html = blogc_content_parse("bola\r\nguda\r\n\r\n****\r\n", NULL, NULL, NULL); + html = blogc_content_parse("bola\r\nguda\r\n\r\n****\r\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

bola\r\n" @@ -787,7 +836,7 @@ test_content_parse_horizontal_rule_crlf(void **state) "\r\n" "***\r\n" "\r\n" - "chunda\r\n", NULL, NULL, NULL); + "chunda\r\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

bola

\r\n" @@ -799,7 +848,7 @@ test_content_parse_horizontal_rule_crlf(void **state) "\r\n" "----\r\n" "\r\n" - "chunda\r\n", NULL, NULL, NULL); + "chunda\r\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

bola

\r\n" @@ -817,7 +866,7 @@ test_content_parse_unordered_list(void **state) "\n" "* asd\n" "* qwe\n" - "* zxc", NULL, NULL, NULL); + "* zxc", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

lol

\n" @@ -832,7 +881,7 @@ test_content_parse_unordered_list(void **state) "\n" "* asd\n" "* qwe\n" - "* zxc\n", NULL, NULL, NULL); + "* zxc\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

lol

\n" @@ -849,7 +898,7 @@ test_content_parse_unordered_list(void **state) "* qwe\n" "* zxc\n" "\n" - "fuuuu\n", NULL, NULL, NULL); + "fuuuu\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

lol

\n" @@ -869,7 +918,7 @@ test_content_parse_unordered_list(void **state) "* zxc\n" " 1234\n" "\n" - "fuuuu\n", NULL, NULL, NULL); + "fuuuu\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

lol

\n" @@ -885,7 +934,7 @@ test_content_parse_unordered_list(void **state) html = blogc_content_parse( "* asd\n" "* qwe\n" - "* zxc", NULL, NULL, NULL); + "* zxc", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "
    \n" @@ -905,7 +954,7 @@ test_content_parse_unordered_list_crlf(void **state) "\r\n" "* asd\r\n" "* qwe\r\n" - "* zxc", NULL, NULL, NULL); + "* zxc", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

    lol

    \r\n" @@ -920,7 +969,7 @@ test_content_parse_unordered_list_crlf(void **state) "\r\n" "* asd\r\n" "* qwe\r\n" - "* zxc\r\n", NULL, NULL, NULL); + "* zxc\r\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

    lol

    \r\n" @@ -937,7 +986,7 @@ test_content_parse_unordered_list_crlf(void **state) "* qwe\r\n" "* zxc\r\n" "\r\n" - "fuuuu\r\n", NULL, NULL, NULL); + "fuuuu\r\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

    lol

    \r\n" @@ -957,7 +1006,7 @@ test_content_parse_unordered_list_crlf(void **state) "* zxc\r\n" " 1234\r\n" "\r\n" - "fuuuu\r\n", NULL, NULL, NULL); + "fuuuu\r\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

    lol

    \r\n" @@ -973,7 +1022,7 @@ test_content_parse_unordered_list_crlf(void **state) html = blogc_content_parse( "* asd\r\n" "* qwe\r\n" - "* zxc", NULL, NULL, NULL); + "* zxc", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "
      \r\n" @@ -993,7 +1042,7 @@ test_content_parse_ordered_list(void **state) "\n" "1. asd\n" "2. qwe\n" - "3. zxc", NULL, NULL, NULL); + "3. zxc", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

      lol

      \n" @@ -1008,7 +1057,7 @@ test_content_parse_ordered_list(void **state) "\n" "1. asd\n" "2. qwe\n" - "3. zxc\n", NULL, NULL, NULL); + "3. zxc\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

      lol

      \n" @@ -1025,7 +1074,7 @@ test_content_parse_ordered_list(void **state) "2. qwe\n" "3. zxc\n" "\n" - "fuuuu\n", NULL, NULL, NULL); + "fuuuu\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

      lol

      \n" @@ -1045,7 +1094,7 @@ test_content_parse_ordered_list(void **state) "3. zxc\n" " 1234\n" "\n" - "fuuuu\n", NULL, NULL, NULL); + "fuuuu\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

      lol

      \n" @@ -1061,7 +1110,7 @@ test_content_parse_ordered_list(void **state) html = blogc_content_parse( "1. asd\n" "2. qwe\n" - "3. zxc", NULL, NULL, NULL); + "3. zxc", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "
        \n" @@ -1081,7 +1130,7 @@ test_content_parse_ordered_list_crlf(void **state) "\r\n" "1. asd\r\n" "2. qwe\r\n" - "3. zxc", NULL, NULL, NULL); + "3. zxc", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

        lol

        \r\n" @@ -1096,7 +1145,7 @@ test_content_parse_ordered_list_crlf(void **state) "\r\n" "1. asd\r\n" "2. qwe\r\n" - "3. zxc\r\n", NULL, NULL, NULL); + "3. zxc\r\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

        lol

        \r\n" @@ -1113,7 +1162,7 @@ test_content_parse_ordered_list_crlf(void **state) "2. qwe\r\n" "3. zxc\r\n" "\r\n" - "fuuuu\r\n", NULL, NULL, NULL); + "fuuuu\r\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

        lol

        \r\n" @@ -1133,7 +1182,7 @@ test_content_parse_ordered_list_crlf(void **state) "3. zxc\r\n" " 1234\r\n" "\r\n" - "fuuuu\r\n", NULL, NULL, NULL); + "fuuuu\r\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

        lol

        \r\n" @@ -1149,7 +1198,7 @@ test_content_parse_ordered_list_crlf(void **state) html = blogc_content_parse( "1. asd\r\n" "2. qwe\r\n" - "3. zxc", NULL, NULL, NULL); + "3. zxc", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "
          \r\n" @@ -1165,7 +1214,7 @@ static void test_content_parse_first_header(void **state) { char *t = NULL; - char *html = blogc_content_parse("# foo", NULL, &t, NULL); + char *html = blogc_content_parse("# foo", NULL, &t, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          foo

          \n"); assert_non_null(t); @@ -1173,7 +1222,7 @@ test_content_parse_first_header(void **state) free(html); free(t); t = NULL; - html = blogc_content_parse("# foo\n", NULL, &t, NULL); + html = blogc_content_parse("# foo\n", NULL, &t, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          foo

          \n"); assert_non_null(t); @@ -1184,7 +1233,7 @@ test_content_parse_first_header(void **state) html = blogc_content_parse( "# foo\n" "## bar\n" - "### baz", NULL, &t, NULL); + "### baz", NULL, &t, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          foo

          \n" @@ -1198,7 +1247,7 @@ test_content_parse_first_header(void **state) html = blogc_content_parse( "# foo\n" "## bar\n" - "### baz\n", NULL, &t, NULL); + "### baz\n", NULL, &t, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          foo

          \n" @@ -1212,7 +1261,7 @@ test_content_parse_first_header(void **state) html = blogc_content_parse( "## bar\n" "# foo\n" - "### baz", NULL, &t, NULL); + "### baz", NULL, &t, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          bar

          \n" @@ -1226,7 +1275,7 @@ test_content_parse_first_header(void **state) html = blogc_content_parse( "## bar\n" "# foo\n" - "### baz\n", NULL, &t, NULL); + "### baz\n", NULL, &t, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          bar

          \n" @@ -1243,7 +1292,7 @@ static void test_content_parse_first_header_crlf(void **state) { char *t = NULL; - char *html = blogc_content_parse("# foo\r\n", NULL, &t, NULL); + char *html = blogc_content_parse("# foo\r\n", NULL, &t, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          foo

          \r\n"); assert_non_null(t); @@ -1254,7 +1303,7 @@ test_content_parse_first_header_crlf(void **state) html = blogc_content_parse( "# foo\r\n" "## bar\r\n" - "### baz", NULL, &t, NULL); + "### baz", NULL, &t, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          foo

          \r\n" @@ -1268,7 +1317,7 @@ test_content_parse_first_header_crlf(void **state) html = blogc_content_parse( "# foo\r\n" "## bar\r\n" - "### baz\r\n", NULL, &t, NULL); + "### baz\r\n", NULL, &t, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          foo

          \r\n" @@ -1282,7 +1331,7 @@ test_content_parse_first_header_crlf(void **state) html = blogc_content_parse( "## bar\r\n" "# foo\r\n" - "### baz", NULL, &t, NULL); + "### baz", NULL, &t, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          bar

          \r\n" @@ -1296,7 +1345,7 @@ test_content_parse_first_header_crlf(void **state) html = blogc_content_parse( "## bar\r\n" "# foo\r\n" - "### baz\r\n", NULL, &t, NULL); + "### baz\r\n", NULL, &t, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          bar

          \r\n" @@ -1309,6 +1358,251 @@ test_content_parse_first_header_crlf(void **state) } +static void +test_content_parse_headers(void **state) +{ + bc_slist_t *h = NULL; + char *html = blogc_content_parse("# foo", NULL, NULL, NULL, NULL, &h); + assert_non_null(html); + assert_string_equal(html, "

          foo

          \n"); + assert_non_null(h); + assert_int_equal(((blogc_toctree_header_t*) h->data)->level, 1); + assert_string_equal(((blogc_toctree_header_t*) h->data)->slug, "foo"); + assert_string_equal(((blogc_toctree_header_t*) h->data)->text, "foo"); + assert_null(h->next); + blogc_toctree_free(h); + h = NULL; + free(html); + html = blogc_content_parse("# foo\n", NULL, NULL, NULL, NULL, &h); + assert_non_null(html); + assert_string_equal(html, "

          foo

          \n"); + assert_non_null(h); + assert_int_equal(((blogc_toctree_header_t*) h->data)->level, 1); + assert_string_equal(((blogc_toctree_header_t*) h->data)->slug, "foo"); + assert_string_equal(((blogc_toctree_header_t*) h->data)->text, "foo"); + assert_null(h->next); + blogc_toctree_free(h); + h = NULL; + free(html); + html = blogc_content_parse( + "# foo\n" + "## bar\n" + "### baz", NULL, NULL, NULL, NULL, &h); + assert_non_null(html); + assert_string_equal(html, + "

          foo

          \n" + "

          bar

          \n" + "

          baz

          \n"); + assert_non_null(h); + assert_int_equal(((blogc_toctree_header_t*) h->data)->level, 1); + assert_string_equal(((blogc_toctree_header_t*) h->data)->slug, "foo"); + assert_string_equal(((blogc_toctree_header_t*) h->data)->text, "foo"); + assert_non_null(h->next); + assert_int_equal(((blogc_toctree_header_t*) h->next->data)->level, 2); + assert_string_equal(((blogc_toctree_header_t*) h->next->data)->slug, "bar"); + assert_string_equal(((blogc_toctree_header_t*) h->next->data)->text, "bar"); + assert_non_null(h); + assert_int_equal(((blogc_toctree_header_t*) h->next->next->data)->level, 3); + assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->slug, "baz"); + assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->text, "baz"); + assert_null(h->next->next->next); + blogc_toctree_free(h); + h = NULL; + free(html); + html = blogc_content_parse( + "# foo\n" + "## bar\n" + "### baz\n", NULL, NULL, NULL, NULL, &h); + assert_non_null(html); + assert_string_equal(html, + "

          foo

          \n" + "

          bar

          \n" + "

          baz

          \n"); + assert_non_null(h); + assert_int_equal(((blogc_toctree_header_t*) h->data)->level, 1); + assert_string_equal(((blogc_toctree_header_t*) h->data)->slug, "foo"); + assert_string_equal(((blogc_toctree_header_t*) h->data)->text, "foo"); + assert_non_null(h->next); + assert_int_equal(((blogc_toctree_header_t*) h->next->data)->level, 2); + assert_string_equal(((blogc_toctree_header_t*) h->next->data)->slug, "bar"); + assert_string_equal(((blogc_toctree_header_t*) h->next->data)->text, "bar"); + assert_non_null(h); + assert_int_equal(((blogc_toctree_header_t*) h->next->next->data)->level, 3); + assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->slug, "baz"); + assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->text, "baz"); + assert_null(h->next->next->next); + blogc_toctree_free(h); + h = NULL; + free(html); + html = blogc_content_parse( + "## bar\n" + "# foo\n" + "### baz", NULL, NULL, NULL, NULL, &h); + assert_non_null(html); + assert_string_equal(html, + "

          bar

          \n" + "

          foo

          \n" + "

          baz

          \n"); + assert_non_null(h); + assert_int_equal(((blogc_toctree_header_t*) h->data)->level, 2); + assert_string_equal(((blogc_toctree_header_t*) h->data)->slug, "bar"); + assert_string_equal(((blogc_toctree_header_t*) h->data)->text, "bar"); + assert_non_null(h->next); + assert_int_equal(((blogc_toctree_header_t*) h->next->data)->level, 1); + assert_string_equal(((blogc_toctree_header_t*) h->next->data)->slug, "foo"); + assert_string_equal(((blogc_toctree_header_t*) h->next->data)->text, "foo"); + assert_non_null(h); + assert_int_equal(((blogc_toctree_header_t*) h->next->next->data)->level, 3); + assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->slug, "baz"); + assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->text, "baz"); + assert_null(h->next->next->next); + blogc_toctree_free(h); + h = NULL; + free(html); + html = blogc_content_parse( + "## bar\n" + "# foo\n" + "### baz\n", NULL, NULL, NULL, NULL, &h); + assert_non_null(html); + assert_string_equal(html, + "

          bar

          \n" + "

          foo

          \n" + "

          baz

          \n"); + assert_non_null(h); + assert_int_equal(((blogc_toctree_header_t*) h->data)->level, 2); + assert_string_equal(((blogc_toctree_header_t*) h->data)->slug, "bar"); + assert_string_equal(((blogc_toctree_header_t*) h->data)->text, "bar"); + assert_non_null(h->next); + assert_int_equal(((blogc_toctree_header_t*) h->next->data)->level, 1); + assert_string_equal(((blogc_toctree_header_t*) h->next->data)->slug, "foo"); + assert_string_equal(((blogc_toctree_header_t*) h->next->data)->text, "foo"); + assert_non_null(h); + assert_int_equal(((blogc_toctree_header_t*) h->next->next->data)->level, 3); + assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->slug, "baz"); + assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->text, "baz"); + assert_null(h->next->next->next); + blogc_toctree_free(h); + free(html); +} + + +static void +test_content_parse_headers_crlf(void **state) +{ + bc_slist_t *h = NULL; + char *html = blogc_content_parse("# foo\r\n", NULL, NULL, NULL, NULL, &h); + assert_non_null(html); + assert_string_equal(html, "

          foo

          \r\n"); + assert_non_null(h); + assert_int_equal(((blogc_toctree_header_t*) h->data)->level, 1); + assert_string_equal(((blogc_toctree_header_t*) h->data)->slug, "foo"); + assert_string_equal(((blogc_toctree_header_t*) h->data)->text, "foo"); + assert_null(h->next); + blogc_toctree_free(h); + h = NULL; + free(html); + html = blogc_content_parse( + "# foo\r\n" + "## bar\r\n" + "### baz", NULL, NULL, NULL, NULL, &h); + assert_non_null(html); + assert_string_equal(html, + "

          foo

          \r\n" + "

          bar

          \r\n" + "

          baz

          \r\n"); + assert_non_null(h); + assert_int_equal(((blogc_toctree_header_t*) h->data)->level, 1); + assert_string_equal(((blogc_toctree_header_t*) h->data)->slug, "foo"); + assert_string_equal(((blogc_toctree_header_t*) h->data)->text, "foo"); + assert_non_null(h->next); + assert_int_equal(((blogc_toctree_header_t*) h->next->data)->level, 2); + assert_string_equal(((blogc_toctree_header_t*) h->next->data)->slug, "bar"); + assert_string_equal(((blogc_toctree_header_t*) h->next->data)->text, "bar"); + assert_non_null(h); + assert_int_equal(((blogc_toctree_header_t*) h->next->next->data)->level, 3); + assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->slug, "baz"); + assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->text, "baz"); + assert_null(h->next->next->next); + blogc_toctree_free(h); + h = NULL; + free(html); + html = blogc_content_parse( + "# foo\r\n" + "## bar\r\n" + "### baz\r\n", NULL, NULL, NULL, NULL, &h); + assert_non_null(html); + assert_string_equal(html, + "

          foo

          \r\n" + "

          bar

          \r\n" + "

          baz

          \r\n"); + assert_non_null(h); + assert_int_equal(((blogc_toctree_header_t*) h->data)->level, 1); + assert_string_equal(((blogc_toctree_header_t*) h->data)->slug, "foo"); + assert_string_equal(((blogc_toctree_header_t*) h->data)->text, "foo"); + assert_non_null(h->next); + assert_int_equal(((blogc_toctree_header_t*) h->next->data)->level, 2); + assert_string_equal(((blogc_toctree_header_t*) h->next->data)->slug, "bar"); + assert_string_equal(((blogc_toctree_header_t*) h->next->data)->text, "bar"); + assert_non_null(h); + assert_int_equal(((blogc_toctree_header_t*) h->next->next->data)->level, 3); + assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->slug, "baz"); + assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->text, "baz"); + assert_null(h->next->next->next); + blogc_toctree_free(h); + h = NULL; + free(html); + html = blogc_content_parse( + "## bar\r\n" + "# foo\r\n" + "### baz", NULL, NULL, NULL, NULL, &h); + assert_non_null(html); + assert_string_equal(html, + "

          bar

          \r\n" + "

          foo

          \r\n" + "

          baz

          \r\n"); + assert_non_null(h); + assert_int_equal(((blogc_toctree_header_t*) h->data)->level, 2); + assert_string_equal(((blogc_toctree_header_t*) h->data)->slug, "bar"); + assert_string_equal(((blogc_toctree_header_t*) h->data)->text, "bar"); + assert_non_null(h->next); + assert_int_equal(((blogc_toctree_header_t*) h->next->data)->level, 1); + assert_string_equal(((blogc_toctree_header_t*) h->next->data)->slug, "foo"); + assert_string_equal(((blogc_toctree_header_t*) h->next->data)->text, "foo"); + assert_non_null(h); + assert_int_equal(((blogc_toctree_header_t*) h->next->next->data)->level, 3); + assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->slug, "baz"); + assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->text, "baz"); + assert_null(h->next->next->next); + blogc_toctree_free(h); + h = NULL; + free(html); + html = blogc_content_parse( + "## bar\r\n" + "# foo\r\n" + "### baz\r\n", NULL, NULL, NULL, NULL, &h); + assert_non_null(html); + assert_string_equal(html, + "

          bar

          \r\n" + "

          foo

          \r\n" + "

          baz

          \r\n"); + assert_non_null(h); + assert_int_equal(((blogc_toctree_header_t*) h->data)->level, 2); + assert_string_equal(((blogc_toctree_header_t*) h->data)->slug, "bar"); + assert_string_equal(((blogc_toctree_header_t*) h->data)->text, "bar"); + assert_non_null(h->next); + assert_int_equal(((blogc_toctree_header_t*) h->next->data)->level, 1); + assert_string_equal(((blogc_toctree_header_t*) h->next->data)->slug, "foo"); + assert_string_equal(((blogc_toctree_header_t*) h->next->data)->text, "foo"); + assert_non_null(h); + assert_int_equal(((blogc_toctree_header_t*) h->next->next->data)->level, 3); + assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->slug, "baz"); + assert_string_equal(((blogc_toctree_header_t*) h->next->next->data)->text, "baz"); + assert_null(h->next->next->next); + blogc_toctree_free(h); + free(html); +} + + static void test_content_parse_description(void **state) { @@ -1316,7 +1610,7 @@ test_content_parse_description(void **state) char *html = blogc_content_parse( "# foo\n" "\n" - "bar", NULL, NULL, &d); + "bar", NULL, NULL, &d, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          foo

          \n" @@ -1329,7 +1623,7 @@ test_content_parse_description(void **state) html = blogc_content_parse( "# foo\n" "\n" - "bar\n", NULL, NULL, &d); + "bar\n", NULL, NULL, &d, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          foo

          \n" @@ -1343,7 +1637,7 @@ test_content_parse_description(void **state) "# foo\n" "\n" "qwe\n" - "bar\n", NULL, NULL, &d); + "bar\n", NULL, NULL, &d, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          foo

          \n" @@ -1359,7 +1653,7 @@ test_content_parse_description(void **state) "\n" "> qwe\n" "\n" - "bar\n", NULL, NULL, &d); + "bar\n", NULL, NULL, &d, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          foo

          \n" @@ -1377,7 +1671,7 @@ test_content_parse_description(void **state) "> qwe\n" "> zxc\n" "\n" - "bar\n", NULL, NULL, &d); + "bar\n", NULL, NULL, &d, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          foo

          \n" @@ -1399,7 +1693,7 @@ test_content_parse_description_crlf(void **state) char *html = blogc_content_parse( "# foo\r\n" "\r\n" - "bar", NULL, NULL, &d); + "bar", NULL, NULL, &d, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          foo

          \r\n" @@ -1412,7 +1706,7 @@ test_content_parse_description_crlf(void **state) html = blogc_content_parse( "# foo\r\n" "\r\n" - "bar\r\n", NULL, NULL, &d); + "bar\r\n", NULL, NULL, &d, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          foo

          \r\n" @@ -1426,7 +1720,7 @@ test_content_parse_description_crlf(void **state) "# foo\r\n" "\r\n" "qwe\r\n" - "bar\r\n", NULL, NULL, &d); + "bar\r\n", NULL, NULL, &d, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          foo

          \r\n" @@ -1442,7 +1736,7 @@ test_content_parse_description_crlf(void **state) "\r\n" "> qwe\r\n" "\r\n" - "bar\r\n", NULL, NULL, &d); + "bar\r\n", NULL, NULL, &d, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          foo

          \r\n" @@ -1460,7 +1754,7 @@ test_content_parse_description_crlf(void **state) "> qwe\r\n" "> zxc\r\n" "\r\n" - "bar\r\n", NULL, NULL, &d); + "bar\r\n", NULL, NULL, &d, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          foo

          \r\n" @@ -1475,6 +1769,107 @@ test_content_parse_description_crlf(void **state) } +static void +test_content_parse_endl(void **state) +{ + char *n = NULL; + char *html = blogc_content_parse("# test", NULL, NULL, NULL, &n, NULL); + assert_non_null(html); + assert_non_null(n); + assert_string_equal(n, "\n"); + free(html); + free(n); + n = "\n"; + html = blogc_content_parse("# test", NULL, NULL, NULL, &n, NULL); + assert_non_null(html); + assert_non_null(n); + assert_string_equal(n, "\n"); + free(html); + n = NULL; + html = blogc_content_parse( + "# test\n", NULL, NULL, NULL, &n, NULL); + assert_non_null(html); + assert_non_null(n); + assert_string_equal(n, "\n"); + free(html); + free(n); + n = NULL; + html = blogc_content_parse( + "# test\n" + "foo", NULL, NULL, NULL, &n, NULL); + assert_non_null(html); + assert_non_null(n); + assert_string_equal(n, "\n"); + free(html); + free(n); + n = NULL; + html = blogc_content_parse( + "# test\n" + "foo\n", NULL, NULL, NULL, &n, NULL); + assert_non_null(html); + assert_non_null(n); + assert_string_equal(n, "\n"); + free(html); + free(n); + n = NULL; + html = blogc_content_parse( + "# test\n" + "foo\r\n", NULL, NULL, NULL, &n, NULL); + assert_non_null(html); + assert_non_null(n); + assert_string_equal(n, "\n"); + free(html); + free(n); +} + + +static void +test_content_parse_endl_crlf(void **state) +{ + char *n = "\r\n"; + char *html = blogc_content_parse("# test", NULL, NULL, NULL, &n, NULL); + assert_non_null(html); + assert_non_null(n); + assert_string_equal(n, "\r\n"); + free(html); + n = NULL; + html = blogc_content_parse( + "# test\r\n", NULL, NULL, NULL, &n, NULL); + assert_non_null(html); + assert_non_null(n); + assert_string_equal(n, "\r\n"); + free(html); + free(n); + n = NULL; + html = blogc_content_parse( + "# test\r\n" + "foo", NULL, NULL, NULL, &n, NULL); + assert_non_null(html); + assert_non_null(n); + assert_string_equal(n, "\r\n"); + free(html); + free(n); + n = NULL; + html = blogc_content_parse( + "# test\r\n" + "foo\r\n", NULL, NULL, NULL, &n, NULL); + assert_non_null(html); + assert_non_null(n); + assert_string_equal(n, "\r\n"); + free(html); + free(n); + n = NULL; + html = blogc_content_parse( + "# test\r\n" + "foo\n", NULL, NULL, NULL, &n, NULL); + assert_non_null(html); + assert_non_null(n); + assert_string_equal(n, "\r\n"); + free(html); + free(n); +} + + static void test_content_parse_invalid_excerpt(void **state) { @@ -1487,7 +1882,7 @@ test_content_parse_invalid_excerpt(void **state) "..\n" "\n" "guda\n" - "lol", &l, NULL, &d); + "lol", &l, NULL, &d, NULL, NULL); assert_non_null(html); assert_int_equal(l, 0); assert_non_null(d); @@ -1509,7 +1904,7 @@ test_content_parse_invalid_excerpt(void **state) "\n" "...\n" "guda\n" - "lol", &l, NULL, &d); + "lol", &l, NULL, &d, NULL, NULL); assert_non_null(html); assert_int_equal(l, 0); assert_non_null(d); @@ -1530,7 +1925,7 @@ test_content_parse_invalid_excerpt(void **state) "chunda..\n" "\n" "guda\n" - "lol", &l, NULL, &d); + "lol", &l, NULL, &d, NULL, NULL); assert_non_null(html); assert_int_equal(l, 0); assert_non_null(d); @@ -1550,7 +1945,7 @@ test_content_parse_invalid_excerpt(void **state) "chunda\n" "\n" "...guda\n" - "lol", &l, NULL, &d); + "lol", &l, NULL, &d, NULL, NULL); assert_non_null(html); assert_int_equal(l, 0); assert_non_null(d); @@ -1571,7 +1966,7 @@ test_content_parse_invalid_header(void **state) char *html = blogc_content_parse( "asd\n" "\n" - "##bola\n", NULL, NULL, NULL); + "##bola\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          asd

          \n" @@ -1588,7 +1983,7 @@ test_content_parse_invalid_header_empty(void **state) "\n" "##\n" "\n" - "qwe\n", NULL, NULL, NULL); + "qwe\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          asd

          \n" @@ -1605,7 +2000,7 @@ test_content_parse_invalid_blockquote(void **state) char *html = blogc_content_parse( "> asd\n" "> bola\n" - "> foo\n", NULL, NULL, NULL); + "> foo\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          > asd\n" @@ -1614,7 +2009,7 @@ test_content_parse_invalid_blockquote(void **state) free(html); html = blogc_content_parse( "> asd\n" - "> bola", NULL, NULL, NULL); + "> bola", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          > asd\n" @@ -1629,7 +2024,7 @@ test_content_parse_invalid_code(void **state) char *html = blogc_content_parse( " asd\n" " bola\n" - " foo\n", NULL, NULL, NULL); + " foo\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          asd\n" @@ -1639,7 +2034,7 @@ test_content_parse_invalid_code(void **state) html = blogc_content_parse( " asd\n" " bola\n" - " foo", NULL, NULL, NULL); + " foo", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          asd\n" @@ -1652,11 +2047,11 @@ test_content_parse_invalid_code(void **state) static void test_content_parse_invalid_horizontal_rule(void **state) { - char *html = blogc_content_parse("** asd", NULL, NULL, NULL); + char *html = blogc_content_parse("** asd", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          ** asd

          \n"); free(html); - html = blogc_content_parse("** asd\n", NULL, NULL, NULL); + html = blogc_content_parse("** asd\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          ** asd

          \n"); free(html); @@ -1668,7 +2063,7 @@ test_content_parse_invalid_unordered_list(void **state) { char *html = blogc_content_parse( "* asd\n" - "1. qwe", NULL, NULL, NULL); + "1. qwe", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          * asd\n" @@ -1677,7 +2072,7 @@ test_content_parse_invalid_unordered_list(void **state) html = blogc_content_parse( "* asd\n" "1. qwe\n" - "\n", NULL, NULL, NULL); + "\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          * asd\n" @@ -1685,7 +2080,7 @@ test_content_parse_invalid_unordered_list(void **state) free(html); html = blogc_content_parse( "* asd\n" - "1. qwe\n", NULL, NULL, NULL); + "1. qwe\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          * asd\n" @@ -1694,7 +2089,7 @@ test_content_parse_invalid_unordered_list(void **state) free(html); html = blogc_content_parse( "* asd\n" - "1. qwe\n", NULL, NULL, NULL); + "1. qwe\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          * asd\n" @@ -1707,7 +2102,7 @@ test_content_parse_invalid_unordered_list(void **state) "* asd\n" "1. qwe\n" "\n" - "poi\n", NULL, NULL, NULL); + "poi\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          chunda

          \n" @@ -1723,7 +2118,7 @@ test_content_parse_invalid_ordered_list(void **state) { char *html = blogc_content_parse( "1. asd\n" - "* qwe", NULL, NULL, NULL); + "* qwe", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          1. asd\n" @@ -1732,7 +2127,7 @@ test_content_parse_invalid_ordered_list(void **state) html = blogc_content_parse( "1. asd\n" "* qwe\n" - "\n", NULL, NULL, NULL); + "\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          1. asd\n" @@ -1740,7 +2135,7 @@ test_content_parse_invalid_ordered_list(void **state) free(html); html = blogc_content_parse( "1. asd\n" - "* qwe\n", NULL, NULL, NULL); + "* qwe\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          1. asd\n" @@ -1749,7 +2144,7 @@ test_content_parse_invalid_ordered_list(void **state) free(html); html = blogc_content_parse( "1. asd\n" - "* qwe\n", NULL, NULL, NULL); + "* qwe\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          1. asd\n" @@ -1762,7 +2157,7 @@ test_content_parse_invalid_ordered_list(void **state) "1. asd\n" "* qwe\n" "\n" - "poi\n", NULL, NULL, NULL); + "poi\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          chunda

          \n" @@ -1772,7 +2167,7 @@ test_content_parse_invalid_ordered_list(void **state) free(html); html = blogc_content_parse( "1 asd\n" - "* qwe\n", NULL, NULL, NULL); + "* qwe\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          1 asd\n" @@ -1780,7 +2175,7 @@ test_content_parse_invalid_ordered_list(void **state) free(html); html = blogc_content_parse( "a. asd\n" - "2. qwe\n", NULL, NULL, NULL); + "2. qwe\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          a. asd\n" @@ -1788,18 +2183,18 @@ test_content_parse_invalid_ordered_list(void **state) free(html); html = blogc_content_parse( "1.\nasd\n" - "2. qwe\n", NULL, NULL, NULL); + "2. qwe\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          1.\n" "asd\n" "2. qwe

          \n"); free(html); - html = blogc_content_parse("1.\n", NULL, NULL, NULL); + html = blogc_content_parse("1.\n", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          1.

          \n"); free(html); - html = blogc_content_parse("1 ", NULL, NULL, NULL); + html = blogc_content_parse("1 ", NULL, NULL, NULL, NULL, NULL); assert_non_null(html); assert_string_equal(html, "

          1

          \n"); free(html); @@ -2365,8 +2760,12 @@ main(void) unit_test(test_content_parse_ordered_list_crlf), unit_test(test_content_parse_first_header), unit_test(test_content_parse_first_header_crlf), + unit_test(test_content_parse_headers), + unit_test(test_content_parse_headers_crlf), unit_test(test_content_parse_description), unit_test(test_content_parse_description_crlf), + unit_test(test_content_parse_endl), + unit_test(test_content_parse_endl_crlf), unit_test(test_content_parse_invalid_excerpt), unit_test(test_content_parse_invalid_header), unit_test(test_content_parse_invalid_header_empty), diff --git a/tests/blogc/check_loader.c b/tests/blogc/check_loader.c index d65f418..cded0ae 100644 --- a/tests/blogc/check_loader.c +++ b/tests/blogc/check_loader.c @@ -1,6 +1,6 @@ /* * blogc: A blog compiler. - * Copyright (C) 2014-2019 Rafael G. Martins + * Copyright (C) 2014-2020 Rafael G. Martins * * This program can be distributed under the terms of the BSD License. * See the file LICENSE. @@ -100,7 +100,8 @@ test_source_parse_from_file(void **state) "ASD: 123\n" "--------\n" "bola")); - bc_trie_t *t = blogc_source_parse_from_file("bola.txt", &err); + bc_trie_t *c = bc_trie_new(free); + bc_trie_t *t = blogc_source_parse_from_file(c, "bola.txt", &err); assert_null(err); assert_non_null(t); assert_int_equal(bc_trie_size(t), 6); @@ -110,6 +111,83 @@ test_source_parse_from_file(void **state) assert_string_equal(bc_trie_lookup(t, "CONTENT"), "

          bola

          \n"); assert_string_equal(bc_trie_lookup(t, "RAW_CONTENT"), "bola"); assert_string_equal(bc_trie_lookup(t, "DESCRIPTION"), "bola"); + bc_trie_free(c); + bc_trie_free(t); +} + + +static void +test_source_parse_from_file_maxdepth(void **state) +{ + bc_error_t *err = NULL; + will_return(__wrap_bc_file_get_contents, "bola.txt"); + will_return(__wrap_bc_file_get_contents, bc_strdup( + "ASD: 123\n" + "TOCTREE_MAXDEPTH: 1\n" + "--------\n" + "### bola\n" + "#### guda")); + bc_trie_t *c = bc_trie_new(free); + bc_trie_insert(c, "TOCTREE_MAXDEPTH", bc_strdup("-1")); + bc_trie_t *t = blogc_source_parse_from_file(c, "bola.txt", &err); + assert_null(err); + assert_non_null(t); + assert_int_equal(bc_trie_size(t), 8); + assert_string_equal(bc_trie_lookup(t, "ASD"), "123"); + assert_string_equal(bc_trie_lookup(t, "TOCTREE_MAXDEPTH"), "1"); + assert_string_equal(bc_trie_lookup(t, "FILENAME"), "bola"); + assert_string_equal(bc_trie_lookup(t, "EXCERPT"), + "

          bola

          \n" + "

          guda

          \n"); + assert_string_equal(bc_trie_lookup(t, "CONTENT"), + "

          bola

          \n" + "

          guda

          \n"); + assert_string_equal(bc_trie_lookup(t, "RAW_CONTENT"), + "### bola\n" + "#### guda"); + assert_string_equal(bc_trie_lookup(t, "FIRST_HEADER"), "bola"); + assert_string_equal(bc_trie_lookup(t, "TOCTREE"), + "\n"); + bc_trie_free(c); + bc_trie_free(t); +} + + +static void +test_source_parse_from_file_maxdepth2(void **state) +{ + bc_error_t *err = NULL; + will_return(__wrap_bc_file_get_contents, "bola.txt"); + will_return(__wrap_bc_file_get_contents, bc_strdup( + "ASD: 123\n" + "--------\n" + "### bola\n" + "#### guda")); + bc_trie_t *c = bc_trie_new(free); + bc_trie_insert(c, "TOCTREE_MAXDEPTH", bc_strdup("1")); + bc_trie_t *t = blogc_source_parse_from_file(c, "bola.txt", &err); + assert_null(err); + assert_non_null(t); + assert_int_equal(bc_trie_size(t), 7); + assert_string_equal(bc_trie_lookup(t, "ASD"), "123"); + assert_string_equal(bc_trie_lookup(t, "FILENAME"), "bola"); + assert_string_equal(bc_trie_lookup(t, "EXCERPT"), + "

          bola

          \n" + "

          guda

          \n"); + assert_string_equal(bc_trie_lookup(t, "CONTENT"), + "

          bola

          \n" + "

          guda

          \n"); + assert_string_equal(bc_trie_lookup(t, "RAW_CONTENT"), + "### bola\n" + "#### guda"); + assert_string_equal(bc_trie_lookup(t, "FIRST_HEADER"), "bola"); + assert_string_equal(bc_trie_lookup(t, "TOCTREE"), + "\n"); + bc_trie_free(c); bc_trie_free(t); } @@ -120,9 +198,11 @@ test_source_parse_from_file_null(void **state) bc_error_t *err = NULL; will_return(__wrap_bc_file_get_contents, "bola.txt"); will_return(__wrap_bc_file_get_contents, NULL); - bc_trie_t *t = blogc_source_parse_from_file("bola.txt", &err); + bc_trie_t *c = bc_trie_new(free); + bc_trie_t *t = blogc_source_parse_from_file(c, "bola.txt", &err); assert_null(err); assert_null(t); + bc_trie_free(c); } @@ -947,6 +1027,8 @@ main(void) unit_test(test_template_parse_from_file), unit_test(test_template_parse_from_file_null), unit_test(test_source_parse_from_file), + unit_test(test_source_parse_from_file_maxdepth), + unit_test(test_source_parse_from_file_maxdepth2), unit_test(test_source_parse_from_file_null), unit_test(test_source_parse_from_files), unit_test(test_source_parse_from_files_filter_sort), diff --git a/tests/blogc/check_renderer.c b/tests/blogc/check_renderer.c index 6486990..3c207a7 100644 --- a/tests/blogc/check_renderer.c +++ b/tests/blogc/check_renderer.c @@ -47,7 +47,7 @@ create_sources(size_t count) bc_error_t *err = NULL; bc_slist_t *l = NULL; for (size_t i = 0; i < count; i++) { - l = bc_slist_append(l, blogc_source_parse(s[i], strlen(s[i]), &err)); + l = bc_slist_append(l, blogc_source_parse(s[i], strlen(s[i]), -1, &err)); assert_null(err); } assert_int_equal(bc_slist_length(l), count); diff --git a/tests/blogc/check_source_parser.c b/tests/blogc/check_source_parser.c index f758522..c1bf2c7 100644 --- a/tests/blogc/check_source_parser.c +++ b/tests/blogc/check_source_parser.c @@ -1,6 +1,6 @@ /* * blogc: A blog compiler. - * Copyright (C) 2014-2019 Rafael G. Martins + * Copyright (C) 2014-2020 Rafael G. Martins * * This program can be distributed under the terms of the BSD License. * See the file LICENSE. @@ -27,7 +27,7 @@ test_source_parse(void **state) "\n" "bola\n"; bc_error_t *err = NULL; - bc_trie_t *source = blogc_source_parse(a, strlen(a), &err); + bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err); assert_null(err); assert_non_null(source); assert_int_equal(bc_trie_size(source), 7); @@ -45,6 +45,7 @@ test_source_parse(void **state) "bola\n"); assert_string_equal(bc_trie_lookup(source, "FIRST_HEADER"), "This is a test"); assert_string_equal(bc_trie_lookup(source, "DESCRIPTION"), "bola"); + assert_null(bc_trie_lookup(source, "TOCTREE")); bc_trie_free(source); } @@ -60,10 +61,10 @@ test_source_parse_crlf(void **state) "\r\n" "bola\r\n"; bc_error_t *err = NULL; - bc_trie_t *source = blogc_source_parse(a, strlen(a), &err); + bc_trie_t *source = blogc_source_parse(a, strlen(a), 1, &err); assert_null(err); assert_non_null(source); - assert_int_equal(bc_trie_size(source), 7); + assert_int_equal(bc_trie_size(source), 8); assert_string_equal(bc_trie_lookup(source, "VAR1"), "asd asd"); assert_string_equal(bc_trie_lookup(source, "VAR2"), "123chunda"); assert_string_equal(bc_trie_lookup(source, "EXCERPT"), @@ -78,6 +79,10 @@ test_source_parse_crlf(void **state) "bola\r\n"); assert_string_equal(bc_trie_lookup(source, "FIRST_HEADER"), "This is a test"); assert_string_equal(bc_trie_lookup(source, "DESCRIPTION"), "bola"); + assert_string_equal(bc_trie_lookup(source, "TOCTREE"), + "\r\n"); bc_trie_free(source); } @@ -95,10 +100,10 @@ test_source_parse_with_spaces(void **state) "\n" "bola\n"; bc_error_t *err = NULL; - bc_trie_t *source = blogc_source_parse(a, strlen(a), &err); + bc_trie_t *source = blogc_source_parse(a, strlen(a), -1, &err); assert_null(err); assert_non_null(source); - assert_int_equal(bc_trie_size(source), 7); + assert_int_equal(bc_trie_size(source), 8); assert_string_equal(bc_trie_lookup(source, "VAR1"), "chunda"); assert_string_equal(bc_trie_lookup(source, "BOLA"), "guda"); assert_string_equal(bc_trie_lookup(source, "EXCERPT"), @@ -113,6 +118,10 @@ test_source_parse_with_spaces(void **state) "bola\n"); assert_string_equal(bc_trie_lookup(source, "FIRST_HEADER"), "This is a test"); assert_string_equal(bc_trie_lookup(source, "DESCRIPTION"), "bola"); + assert_string_equal(bc_trie_lookup(source, "TOCTREE"), + "\n"); bc_trie_free(source); } @@ -133,7 +142,7 @@ test_source_parse_with_excerpt(void **state) "guda\n" "yay"; bc_error_t *err = NULL; - bc_trie_t *source = blogc_source_parse(a, strlen(a), &err); + bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err); assert_null(err); assert_non_null(source); assert_int_equal(bc_trie_size(source), 7); @@ -158,6 +167,7 @@ test_source_parse_with_excerpt(void **state) "yay"); assert_string_equal(bc_trie_lookup(source, "FIRST_HEADER"), "This is a test"); assert_string_equal(bc_trie_lookup(source, "DESCRIPTION"), "bola"); + assert_null(bc_trie_lookup(source, "TOCTREE")); bc_trie_free(source); } @@ -174,7 +184,7 @@ test_source_parse_with_first_header(void **state) "\n" "bola\n"; bc_error_t *err = NULL; - bc_trie_t *source = blogc_source_parse(a, strlen(a), &err); + bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err); assert_null(err); assert_non_null(source); assert_int_equal(bc_trie_size(source), 7); @@ -192,6 +202,7 @@ test_source_parse_with_first_header(void **state) "bola\n"); assert_string_equal(bc_trie_lookup(source, "FIRST_HEADER"), "THIS IS CHUNDA!"); assert_string_equal(bc_trie_lookup(source, "DESCRIPTION"), "bola"); + assert_null(bc_trie_lookup(source, "TOCTREE")); bc_trie_free(source); } @@ -208,7 +219,7 @@ test_source_parse_with_description(void **state) "\n" "bola\n"; bc_error_t *err = NULL; - bc_trie_t *source = blogc_source_parse(a, strlen(a), &err); + bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err); assert_null(err); assert_non_null(source); assert_int_equal(bc_trie_size(source), 7); @@ -226,6 +237,172 @@ test_source_parse_with_description(void **state) "bola\n"); assert_string_equal(bc_trie_lookup(source, "FIRST_HEADER"), "This is a test"); assert_string_equal(bc_trie_lookup(source, "DESCRIPTION"), "huehuehuebrbr"); + assert_null(bc_trie_lookup(source, "TOCTREE")); + bc_trie_free(source); +} + + +static void +test_source_parse_with_toctree(void **state) +{ + const char *a = + "VAR1: asd asd\n" + "VAR2: 123chunda\n" + "----------\n" + "### asd\n" + "### qwe\n" + "## zxc\n" + "### rty\n" + "#### bnm\n" + "### asd\n"; + bc_error_t *err = NULL; + bc_trie_t *source = blogc_source_parse(a, strlen(a), -1, &err); + assert_null(err); + assert_non_null(source); + assert_int_equal(bc_trie_size(source), 7); + assert_string_equal(bc_trie_lookup(source, "VAR1"), "asd asd"); + assert_string_equal(bc_trie_lookup(source, "VAR2"), "123chunda"); + assert_string_equal(bc_trie_lookup(source, "EXCERPT"), + "

          asd

          \n" + "

          qwe

          \n" + "

          zxc

          \n" + "

          rty

          \n" + "

          bnm

          \n" + "

          asd

          \n"); + assert_string_equal(bc_trie_lookup(source, "CONTENT"), + "

          asd

          \n" + "

          qwe

          \n" + "

          zxc

          \n" + "

          rty

          \n" + "

          bnm

          \n" + "

          asd

          \n"); + assert_string_equal(bc_trie_lookup(source, "RAW_CONTENT"), + "### asd\n" + "### qwe\n" + "## zxc\n" + "### rty\n" + "#### bnm\n" + "### asd\n"); + assert_string_equal(bc_trie_lookup(source, "FIRST_HEADER"), "asd"); + assert_string_equal(bc_trie_lookup(source, "TOCTREE"), + "
            \n" + "
              \n" + "
            • asd
            • \n" + "
            • qwe
            • \n" + "
            \n" + "
          • zxc
          • \n" + "
              \n" + "
            • rty
            • \n" + "
                \n" + "
              • bnm
              • \n" + "
              \n" + "
            • asd
            • \n" + "
            \n" + "
          \n"); + bc_trie_free(source); +} + + +static void +test_source_parse_with_toctree_noheader(void **state) +{ + const char *a = + "VAR1: asd asd\n" + "VAR2: 123chunda\n" + "----------\n" + "asd\n"; + bc_error_t *err = NULL; + bc_trie_t *source = blogc_source_parse(a, strlen(a), -1, &err); + assert_null(err); + assert_non_null(source); + assert_int_equal(bc_trie_size(source), 6); + assert_string_equal(bc_trie_lookup(source, "VAR1"), "asd asd"); + assert_string_equal(bc_trie_lookup(source, "VAR2"), "123chunda"); + assert_string_equal(bc_trie_lookup(source, "EXCERPT"), + "

          asd

          \n"); + assert_string_equal(bc_trie_lookup(source, "CONTENT"), + "

          asd

          \n"); + assert_string_equal(bc_trie_lookup(source, "RAW_CONTENT"), + "asd\n"); + assert_null(bc_trie_lookup(source, "FIRST_HEADER")); + assert_null(bc_trie_lookup(source, "TOCTREE")); + bc_trie_free(source); +} + + +static void +test_source_parse_with_toctree_maxdepth1(void **state) +{ + const char *a = + "VAR1: asd asd\n" + "VAR2: 123chunda\n" + "----------\n" + "### asd\n" + "### qwe\n" + "## zxc\n" + "### rty\n" + "#### bnm\n" + "### asd\n"; + bc_error_t *err = NULL; + bc_trie_t *source = blogc_source_parse(a, strlen(a), 1, &err); + assert_null(err); + assert_non_null(source); + assert_int_equal(bc_trie_size(source), 7); + assert_string_equal(bc_trie_lookup(source, "VAR1"), "asd asd"); + assert_string_equal(bc_trie_lookup(source, "VAR2"), "123chunda"); + assert_string_equal(bc_trie_lookup(source, "EXCERPT"), + "

          asd

          \n" + "

          qwe

          \n" + "

          zxc

          \n" + "

          rty

          \n" + "

          bnm

          \n" + "

          asd

          \n"); + assert_string_equal(bc_trie_lookup(source, "CONTENT"), + "

          asd

          \n" + "

          qwe

          \n" + "

          zxc

          \n" + "

          rty

          \n" + "

          bnm

          \n" + "

          asd

          \n"); + assert_string_equal(bc_trie_lookup(source, "RAW_CONTENT"), + "### asd\n" + "### qwe\n" + "## zxc\n" + "### rty\n" + "#### bnm\n" + "### asd\n"); + assert_string_equal(bc_trie_lookup(source, "FIRST_HEADER"), "asd"); + assert_string_equal(bc_trie_lookup(source, "TOCTREE"), + "
            \n" + "
          • zxc
          • \n" + "
          \n"); + bc_trie_free(source); +} + + +static void +test_source_parse_with_toctree_maxdepth_invalid(void **state) +{ + const char *a = + "VAR1: asd asd\n" + "VAR2: 123chunda\n" + "TOCTREE_MAXDEPTH: bola\n" + "----------\n" + "### asd\n" + "### qwe\n" + "## zxc\n" + "### rty\n" + "#### bnm\n" + "### asd\n"; + bc_error_t *err = NULL; + bc_trie_t *source = blogc_source_parse(a, strlen(a), 1, &err); + assert_non_null(err); + assert_null(source); + assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER); + assert_string_equal(err->msg, + "Invalid value for 'TOCTREE_MAXDEPTH' variable: bola.\n" + "Error occurred near line 10, position 8: ### asd"); + bc_error_free(err); bc_trie_free(source); } @@ -235,7 +412,7 @@ test_source_parse_config_empty(void **state) { const char *a = ""; bc_error_t *err = NULL; - bc_trie_t *source = blogc_source_parse(a, strlen(a), &err); + bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err); assert_null(source); assert_non_null(err); assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER); @@ -250,7 +427,7 @@ test_source_parse_config_invalid_key(void **state) { const char *a = "bola: guda"; bc_error_t *err = NULL; - bc_trie_t *source = blogc_source_parse(a, strlen(a), &err); + bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err); assert_non_null(err); assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER); assert_string_equal(err->msg, @@ -266,7 +443,7 @@ test_source_parse_config_no_key(void **state) { const char *a = "BOLa"; bc_error_t *err = NULL; - bc_trie_t *source = blogc_source_parse(a, strlen(a), &err); + bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err); assert_non_null(err); assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER); assert_string_equal(err->msg, @@ -282,7 +459,7 @@ test_source_parse_config_no_key2(void **state) { const char *a = "BOLA"; bc_error_t *err = NULL; - bc_trie_t *source = blogc_source_parse(a, strlen(a), &err); + bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err); assert_non_null(err); assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER); assert_string_equal(err->msg, @@ -299,10 +476,11 @@ test_source_parse_config_no_value(void **state) // this is a special case, not an error const char *a = "BOLA:\r\n"; bc_error_t *err = NULL; - bc_trie_t *source = blogc_source_parse(a, strlen(a), &err); + bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err); assert_non_null(source); assert_null(err); assert_string_equal(bc_trie_lookup(source, "BOLA"), ""); + assert_null(bc_trie_lookup(source, "TOCTREE")); bc_trie_free(source); } @@ -312,7 +490,7 @@ test_source_parse_config_no_value2(void **state) { const char *a = "BOLA:"; bc_error_t *err = NULL; - bc_trie_t *source = blogc_source_parse(a, strlen(a), &err); + bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err); assert_null(source); assert_non_null(err); assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER); @@ -329,7 +507,7 @@ test_source_parse_config_reserved_name(void **state) { const char *a = "FILENAME: asd\r\n"; bc_error_t *err = NULL; - bc_trie_t *source = blogc_source_parse(a, strlen(a), &err); + bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err); assert_null(source); assert_non_null(err); assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER); @@ -346,7 +524,7 @@ test_source_parse_config_reserved_name2(void **state) { const char *a = "CONTENT: asd\r\n"; bc_error_t *err = NULL; - bc_trie_t *source = blogc_source_parse(a, strlen(a), &err); + bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err); assert_null(source); assert_non_null(err); assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER); @@ -363,7 +541,7 @@ test_source_parse_config_reserved_name3(void **state) { const char *a = "DATE_FORMATTED: asd\r\n"; bc_error_t *err = NULL; - bc_trie_t *source = blogc_source_parse(a, strlen(a), &err); + bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err); assert_null(source); assert_non_null(err); assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER); @@ -380,7 +558,7 @@ test_source_parse_config_reserved_name4(void **state) { const char *a = "DATE_FIRST_FORMATTED: asd\r\n"; bc_error_t *err = NULL; - bc_trie_t *source = blogc_source_parse(a, strlen(a), &err); + bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err); assert_null(source); assert_non_null(err); assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER); @@ -397,7 +575,7 @@ test_source_parse_config_reserved_name5(void **state) { const char *a = "DATE_LAST_FORMATTED: asd\r\n"; bc_error_t *err = NULL; - bc_trie_t *source = blogc_source_parse(a, strlen(a), &err); + bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err); assert_null(source); assert_non_null(err); assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER); @@ -414,7 +592,7 @@ test_source_parse_config_reserved_name6(void **state) { const char *a = "PAGE_FIRST: asd\r\n"; bc_error_t *err = NULL; - bc_trie_t *source = blogc_source_parse(a, strlen(a), &err); + bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err); assert_null(source); assert_non_null(err); assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER); @@ -431,7 +609,7 @@ test_source_parse_config_reserved_name7(void **state) { const char *a = "PAGE_PREVIOUS: asd\r\n"; bc_error_t *err = NULL; - bc_trie_t *source = blogc_source_parse(a, strlen(a), &err); + bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err); assert_null(source); assert_non_null(err); assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER); @@ -448,7 +626,7 @@ test_source_parse_config_reserved_name8(void **state) { const char *a = "PAGE_CURRENT: asd\r\n"; bc_error_t *err = NULL; - bc_trie_t *source = blogc_source_parse(a, strlen(a), &err); + bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err); assert_null(source); assert_non_null(err); assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER); @@ -465,7 +643,7 @@ test_source_parse_config_reserved_name9(void **state) { const char *a = "PAGE_NEXT: asd\r\n"; bc_error_t *err = NULL; - bc_trie_t *source = blogc_source_parse(a, strlen(a), &err); + bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err); assert_null(source); assert_non_null(err); assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER); @@ -482,7 +660,7 @@ test_source_parse_config_reserved_name10(void **state) { const char *a = "PAGE_LAST: asd\r\n"; bc_error_t *err = NULL; - bc_trie_t *source = blogc_source_parse(a, strlen(a), &err); + bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err); assert_null(source); assert_non_null(err); assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER); @@ -499,7 +677,7 @@ test_source_parse_config_reserved_name11(void **state) { const char *a = "BLOGC_VERSION: 1.0\r\n"; bc_error_t *err = NULL; - bc_trie_t *source = blogc_source_parse(a, strlen(a), &err); + bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err); assert_null(source); assert_non_null(err); assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER); @@ -516,7 +694,7 @@ test_source_parse_config_value_no_line_ending(void **state) { const char *a = "BOLA: asd"; bc_error_t *err = NULL; - bc_trie_t *source = blogc_source_parse(a, strlen(a), &err); + bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err); assert_null(source); assert_non_null(err); assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER); @@ -533,7 +711,7 @@ test_source_parse_invalid_separator(void **state) { const char *a = "BOLA: asd\n---#"; bc_error_t *err = NULL; - bc_trie_t *source = blogc_source_parse(a, strlen(a), &err); + bc_trie_t *source = blogc_source_parse(a, strlen(a), 0, &err); assert_null(source); assert_non_null(err); assert_int_equal(err->type, BLOGC_ERROR_SOURCE_PARSER); @@ -555,6 +733,10 @@ main(void) unit_test(test_source_parse_with_excerpt), unit_test(test_source_parse_with_first_header), unit_test(test_source_parse_with_description), + unit_test(test_source_parse_with_toctree), + unit_test(test_source_parse_with_toctree_noheader), + unit_test(test_source_parse_with_toctree_maxdepth1), + unit_test(test_source_parse_with_toctree_maxdepth_invalid), unit_test(test_source_parse_config_empty), unit_test(test_source_parse_config_invalid_key), unit_test(test_source_parse_config_no_key), diff --git a/tests/blogc/check_toctree.c b/tests/blogc/check_toctree.c new file mode 100644 index 0000000..c5cb918 --- /dev/null +++ b/tests/blogc/check_toctree.c @@ -0,0 +1,234 @@ +/* + * blogc: A blog compiler. + * Copyright (C) 2014-2020 Rafael G. Martins + * + * This program can be distributed under the terms of the BSD License. + * See the file LICENSE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "../../src/common/utils.h" +#include "../../src/blogc/toctree.h" + + +static void +test_toctree_append(void **state) +{ + bc_slist_t *l = NULL; + + l = blogc_toctree_append(l, 0, "", ""); + assert_null(l); + + l = blogc_toctree_append(l, 1, "f1", "bola"); + assert_non_null(l); + assert_int_equal(((blogc_toctree_header_t*) l->data)->level, 1); + assert_string_equal(((blogc_toctree_header_t*) l->data)->slug, "f1"); + assert_string_equal(((blogc_toctree_header_t*) l->data)->text, "bola"); + assert_null(l->next); + + l = blogc_toctree_append(l, 2, "f2", "guda"); + assert_non_null(l); + assert_int_equal(((blogc_toctree_header_t*) l->data)->level, 1); + assert_string_equal(((blogc_toctree_header_t*) l->data)->slug, "f1"); + assert_string_equal(((blogc_toctree_header_t*) l->data)->text, "bola"); + assert_non_null(l->next); + assert_int_equal(((blogc_toctree_header_t*) l->next->data)->level, 2); + assert_string_equal(((blogc_toctree_header_t*) l->next->data)->slug, "f2"); + assert_string_equal(((blogc_toctree_header_t*) l->next->data)->text, "guda"); + assert_null(l->next->next); + + l = blogc_toctree_append(l, 0, "", ""); + assert_non_null(l); + assert_int_equal(((blogc_toctree_header_t*) l->data)->level, 1); + assert_string_equal(((blogc_toctree_header_t*) l->data)->slug, "f1"); + assert_string_equal(((blogc_toctree_header_t*) l->data)->text, "bola"); + assert_non_null(l->next); + assert_int_equal(((blogc_toctree_header_t*) l->next->data)->level, 2); + assert_string_equal(((blogc_toctree_header_t*) l->next->data)->slug, "f2"); + assert_string_equal(((blogc_toctree_header_t*) l->next->data)->text, "guda"); + assert_null(l->next->next); + + blogc_toctree_free(l); +} + + +static void +test_toctree_render(void **state) +{ + bc_slist_t *l = NULL; + assert_null(blogc_toctree_render(l, 6, NULL)); + + l = blogc_toctree_append(l, 1, "f1", "bola"); + l = blogc_toctree_append(l, 1, "f2", "guda"); + l = blogc_toctree_append(l, 2, "f3", "asd"); + l = blogc_toctree_append(l, 3, NULL, "foo"); + l = blogc_toctree_append(l, 1, "f5", NULL); + l = blogc_toctree_append(l, 5, NULL, NULL); + char *o = blogc_toctree_render(l, -2, NULL); + assert_string_equal(o, + "
            \n" + "
          • bola
          • \n" + "
          • guda
          • \n" + "
              \n" + "
            • asd
            • \n" + "
                \n" + "
              • foo
              • \n" + "
              \n" + "
            \n" + "
          • \n" + "
              \n" + "
                \n" + "
                  \n" + "
                    \n" + "
                  • \n" + "
                  \n" + "
                \n" + "
              \n" + "
            \n" + "
          \n"); + free(o); + + o = blogc_toctree_render(l, -1, "\n"); + assert_string_equal(o, + "
            \n" + "
          • bola
          • \n" + "
          • guda
          • \n" + "
              \n" + "
            • asd
            • \n" + "
                \n" + "
              • foo
              • \n" + "
              \n" + "
            \n" + "
          • \n" + "
              \n" + "
                \n" + "
                  \n" + "
                    \n" + "
                  • \n" + "
                  \n" + "
                \n" + "
              \n" + "
            \n" + "
          \n"); + free(o); + + o = blogc_toctree_render(l, 6, "\r\n"); + assert_string_equal(o, + "
            \r\n" + "
          • bola
          • \r\n" + "
          • guda
          • \r\n" + "
              \r\n" + "
            • asd
            • \r\n" + "
                \r\n" + "
              • foo
              • \r\n" + "
              \r\n" + "
            \r\n" + "
          • \r\n" + "
              \r\n" + "
                \r\n" + "
                  \r\n" + "
                    \r\n" + "
                  • \r\n" + "
                  \r\n" + "
                \r\n" + "
              \r\n" + "
            \r\n" + "
          \r\n"); + free(o); + + o = blogc_toctree_render(l, 5, NULL); + assert_string_equal(o, + "
            \n" + "
          • bola
          • \n" + "
          • guda
          • \n" + "
              \n" + "
            • asd
            • \n" + "
                \n" + "
              • foo
              • \n" + "
              \n" + "
            \n" + "
          • \n" + "
              \n" + "
                \n" + "
                  \n" + "
                    \n" + "
                  • \n" + "
                  \n" + "
                \n" + "
              \n" + "
            \n" + "
          \n"); + free(o); + + o = blogc_toctree_render(l, 4, "\n"); + assert_string_equal(o, + "
            \n" + "
          • bola
          • \n" + "
          • guda
          • \n" + "
              \n" + "
            • asd
            • \n" + "
                \n" + "
              • foo
              • \n" + "
              \n" + "
            \n" + "
          • \n" + "
          \n"); + free(o); + + o = blogc_toctree_render(l, 3, "\r\n"); + assert_string_equal(o, + "
            \r\n" + "
          • bola
          • \r\n" + "
          • guda
          • \r\n" + "
              \r\n" + "
            • asd
            • \r\n" + "
                \r\n" + "
              • foo
              • \r\n" + "
              \r\n" + "
            \r\n" + "
          • \r\n" + "
          \r\n"); + free(o); + + o = blogc_toctree_render(l, 2, NULL); + assert_string_equal(o, + "
            \n" + "
          • bola
          • \n" + "
          • guda
          • \n" + "
              \n" + "
            • asd
            • \n" + "
            \n" + "
          • \n" + "
          \n"); + free(o); + + o = blogc_toctree_render(l, 1, NULL); + assert_string_equal(o, + "\n"); + free(o); + + assert_null(blogc_toctree_render(l, 0, NULL)); + + blogc_toctree_free(l); +} + + +int +main(void) +{ + const UnitTest tests[] = { + unit_test(test_toctree_append), + unit_test(test_toctree_render), + }; + return run_tests(tests); +} -- cgit v1.2.3-18-g5258