aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael G. Martins <rafael@rafaelmartins.eng.br>2017-01-01 18:14:22 +0100
committerRafael G. Martins <rafael@rafaelmartins.eng.br>2017-01-01 18:14:22 +0100
commitb832feb3894d95a82e88da05bb9fa29c6da26211 (patch)
tree7a7845fd5256b1454743817fd587fa7621164c05
parent463f6bd5a7f74827427b431452b0720f7be3bd62 (diff)
downloadblogc-b832feb3894d95a82e88da05bb9fa29c6da26211.tar.gz
blogc-b832feb3894d95a82e88da05bb9fa29c6da26211.tar.bz2
blogc-b832feb3894d95a82e88da05bb9fa29c6da26211.zip
make: added a bunch of tests
-rw-r--r--.gitignore3
-rw-r--r--Makefile.am44
-rw-r--r--configure.ac3
-rw-r--r--src/blogc-make/exec.h2
-rw-r--r--tests/blogc-make/check_atom.c154
-rwxr-xr-xtests/blogc-make/check_blogc_make.sh.in796
-rw-r--r--tests/blogc-make/check_exec.c138
7 files changed, 1139 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index 844d416..b6ded60 100644
--- a/.gitignore
+++ b/.gitignore
@@ -67,6 +67,9 @@ blogc*.html
/tests/blogc-git-receiver/check_post_receive.sh
/tests/blogc-git-receiver/check_shell_command_parser
/tests/blogc-git-receiver/check_shell.sh
+/tests/blogc-make/check_atom
+/tests/blogc-make/check_blogc_make.sh
+/tests/blogc-make/check_exec
/tests/blogc-make/check_settings
/tests/blogc-runserver/check_httpd_utils
/tests/blogc-runserver/check_mime
diff --git a/Makefile.am b/Makefile.am
index bd69302..7650ccc 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -406,6 +406,12 @@ check_SCRIPTS += \
endif
endif
+if BUILD_MAKE
+check_SCRIPTS += \
+ tests/blogc-make/check_blogc_make.sh \
+ $(NULL)
+endif
+
check_SCRIPTS += \
tests/blogc/check_blogc.sh \
$(NULL)
@@ -731,9 +737,47 @@ endif
if BUILD_MAKE_LIB
check_PROGRAMS += \
+ tests/blogc-make/check_atom \
+ tests/blogc-make/check_exec \
tests/blogc-make/check_settings \
$(NULL)
+tests_blogc_make_check_atom_SOURCES = \
+ tests/blogc-make/check_atom.c \
+ $(NULL)
+
+tests_blogc_make_check_atom_CFLAGS = \
+ $(CMOCKA_CFLAGS) \
+ $(NULL)
+
+tests_blogc_make_check_atom_LDFLAGS = \
+ -no-install \
+ $(NULL)
+
+tests_blogc_make_check_atom_LDADD = \
+ $(CMOCKA_LIBS) \
+ libblogc_make.la \
+ libblogc_common.la \
+ $(NULL)
+
+tests_blogc_make_check_exec_SOURCES = \
+ tests/blogc-make/check_exec.c \
+ $(NULL)
+
+tests_blogc_make_check_exec_CFLAGS = \
+ $(CMOCKA_CFLAGS) \
+ $(NULL)
+
+tests_blogc_make_check_exec_LDFLAGS = \
+ -no-install \
+ $(NULL)
+
+tests_blogc_make_check_exec_LDADD = \
+ $(CMOCKA_LIBS) \
+ libblogc_make.la \
+ libblogc_common.la \
+ $(NULL)
+
tests_blogc_make_check_settings_SOURCES = \
tests/blogc-make/check_settings.c \
$(NULL)
diff --git a/configure.ac b/configure.ac
index cc08106..0fdbf6a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -227,7 +227,8 @@ AC_CONFIG_FILES([tests/blogc-git-receiver/check_post_receive.sh],
[chmod +x tests/blogc-git-receiver/check_post_receive.sh])
AC_CONFIG_FILES([tests/blogc-git-receiver/check_shell.sh],
[chmod +x tests/blogc-git-receiver/check_shell.sh])
-
+AC_CONFIG_FILES([tests/blogc-make/check_blogc_make.sh],
+ [chmod +x tests/blogc-make/check_blogc_make.sh])
AC_OUTPUT
AS_ECHO("
diff --git a/src/blogc-make/exec.h b/src/blogc-make/exec.h
index ecc7f2c..04bd44e 100644
--- a/src/blogc-make/exec.h
+++ b/src/blogc-make/exec.h
@@ -9,8 +9,10 @@
#ifndef _MAKE_EXEC_H
#define _MAKE_EXEC_H
+#include <stdbool.h>
#include "../common/error.h"
#include "../common/utils.h"
+#include "ctx.h"
#include "settings.h"
int bm_exec_command(const char *cmd, const char *input, char **output,
diff --git a/tests/blogc-make/check_atom.c b/tests/blogc-make/check_atom.c
new file mode 100644
index 0000000..cceec23
--- /dev/null
+++ b/tests/blogc-make/check_atom.c
@@ -0,0 +1,154 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "../../src/blogc-make/atom.h"
+#include "../../src/blogc-make/settings.h"
+#include "../../src/common/file.h"
+#include "../../src/common/error.h"
+#include "../../src/common/utils.h"
+
+
+static void
+test_atom_file(void **state)
+{
+ bm_settings_t *settings = bc_malloc(sizeof(bm_settings_t));
+ settings->settings = bc_trie_new(free);
+ bc_trie_insert(settings->settings, "atom_prefix", bc_strdup("atom"));
+ bc_trie_insert(settings->settings, "atom_ext", bc_strdup(".xml"));
+ bc_trie_insert(settings->settings, "post_prefix", bc_strdup("post"));
+
+ bc_error_t *err = NULL;
+ char *rv = bm_atom_deploy(settings, &err);
+
+ assert_non_null(rv);
+ assert_null(err);
+
+ size_t cmp_len;
+ char *cmp = bc_file_get_contents(rv, true, &cmp_len, &err);
+
+ assert_non_null(cmp);
+ assert_null(err);
+
+ assert_string_equal(cmp,
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<feed xmlns=\"http://www.w3.org/2005/Atom\">\n"
+ " <title type=\"text\">{{ SITE_TITLE }}{% ifdef FILTER_TAG %} - "
+ "{{ FILTER_TAG }}{% endif %}</title>\n"
+ " <id>{{ BASE_URL }}/atom{% ifdef FILTER_TAG %}/{{ FILTER_TAG }}"
+ "{% endif %}.xml</id>\n"
+ " <updated>{{ DATE_FIRST_FORMATTED }}</updated>\n"
+ " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/\" />\n"
+ " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/atom{% ifdef FILTER_TAG %}"
+ "/{{ FILTER_TAG }}{% endif %}.xml\" rel=\"self\" />\n"
+ " <author>\n"
+ " <name>{{ AUTHOR_NAME }}</name>\n"
+ " <email>{{ AUTHOR_EMAIL }}</email>\n"
+ " </author>\n"
+ " <subtitle type=\"text\">{{ SITE_TAGLINE }}</subtitle>\n"
+ " {% block listing %}\n"
+ " <entry>\n"
+ " <title type=\"text\">{{ TITLE }}</title>\n"
+ " <id>{{ BASE_URL }}/post/{{ FILENAME }}/</id>\n"
+ " <updated>{{ DATE_FORMATTED }}</updated>\n"
+ " <published>{{ DATE_FORMATTED }}</published>\n"
+ " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/post/{{ FILENAME }}/\" />\n"
+ " <author>\n"
+ " <name>{{ AUTHOR_NAME }}</name>\n"
+ " <email>{{ AUTHOR_EMAIL }}</email>\n"
+ " </author>\n"
+ " <content type=\"html\"><![CDATA[{{ CONTENT }}]]></content>\n"
+ " </entry>\n"
+ " {% endblock %}\n"
+ "</feed>\n");
+
+ free(cmp);
+ bm_atom_destroy(rv);
+ free(rv);
+ bc_trie_free(settings->settings);
+ free(settings);
+}
+
+
+static void
+test_atom_dir(void **state)
+{
+ bm_settings_t *settings = bc_malloc(sizeof(bm_settings_t));
+ settings->settings = bc_trie_new(free);
+ bc_trie_insert(settings->settings, "atom_prefix", bc_strdup("atom"));
+ bc_trie_insert(settings->settings, "atom_ext", bc_strdup("/index.xml"));
+ bc_trie_insert(settings->settings, "post_prefix", bc_strdup("post"));
+
+ bc_error_t *err = NULL;
+ char *rv = bm_atom_deploy(settings, &err);
+
+ assert_non_null(rv);
+ assert_null(err);
+
+ size_t cmp_len;
+ char *cmp = bc_file_get_contents(rv, true, &cmp_len, &err);
+
+ assert_non_null(cmp);
+ assert_null(err);
+
+ assert_string_equal(cmp,
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<feed xmlns=\"http://www.w3.org/2005/Atom\">\n"
+ " <title type=\"text\">{{ SITE_TITLE }}{% ifdef FILTER_TAG %} - "
+ "{{ FILTER_TAG }}{% endif %}</title>\n"
+ " <id>{{ BASE_URL }}/atom{% ifdef FILTER_TAG %}/{{ FILTER_TAG }}"
+ "{% endif %}/index.xml</id>\n"
+ " <updated>{{ DATE_FIRST_FORMATTED }}</updated>\n"
+ " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/\" />\n"
+ " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/atom{% ifdef FILTER_TAG %}"
+ "/{{ FILTER_TAG }}{% endif %}/index.xml\" rel=\"self\" />\n"
+ " <author>\n"
+ " <name>{{ AUTHOR_NAME }}</name>\n"
+ " <email>{{ AUTHOR_EMAIL }}</email>\n"
+ " </author>\n"
+ " <subtitle type=\"text\">{{ SITE_TAGLINE }}</subtitle>\n"
+ " {% block listing %}\n"
+ " <entry>\n"
+ " <title type=\"text\">{{ TITLE }}</title>\n"
+ " <id>{{ BASE_URL }}/post/{{ FILENAME }}/</id>\n"
+ " <updated>{{ DATE_FORMATTED }}</updated>\n"
+ " <published>{{ DATE_FORMATTED }}</published>\n"
+ " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/post/{{ FILENAME }}/\" />\n"
+ " <author>\n"
+ " <name>{{ AUTHOR_NAME }}</name>\n"
+ " <email>{{ AUTHOR_EMAIL }}</email>\n"
+ " </author>\n"
+ " <content type=\"html\"><![CDATA[{{ CONTENT }}]]></content>\n"
+ " </entry>\n"
+ " {% endblock %}\n"
+ "</feed>\n");
+
+ free(cmp);
+ bm_atom_destroy(rv);
+ free(rv);
+ bc_trie_free(settings->settings);
+ free(settings);
+}
+
+
+int
+main(void)
+{
+ const UnitTest tests[] = {
+ unit_test(test_atom_file),
+ unit_test(test_atom_dir),
+ };
+ return run_tests(tests);
+}
diff --git a/tests/blogc-make/check_blogc_make.sh.in b/tests/blogc-make/check_blogc_make.sh.in
new file mode 100755
index 0000000..2139664
--- /dev/null
+++ b/tests/blogc-make/check_blogc_make.sh.in
@@ -0,0 +1,796 @@
+#!@BASH@
+
+set -xe -o pipefail
+
+export LC_ALL=C
+
+TEMP="$(mktemp -d)"
+[[ -n "${TEMP}" ]]
+
+trap_func() {
+ [[ -e "${TEMP}/output.txt" ]] && cat "${TEMP}/output.txt"
+ [[ -n "${TEMP}" ]] && rm -rf "${TEMP}"
+}
+
+trap trap_func EXIT
+
+mkdir -p "${TEMP}"/proj{,/templates,/content/post}
+
+
+### minimal settings, will produce no file
+
+cat > "${TEMP}/proj/settings.ini" <<EOF
+[environment]
+AUTHOR_NAME = Lol
+AUTHOR_EMAIL = author@example.com
+SITE_TITLE = Lol's Website
+SITE_TAGLINE = WAT?!
+BASE_DOMAIN = http://example.org
+EOF
+
+${TESTS_ENVIRONMENT} ./blogc-make -f "${TEMP}/proj/settings.ini" 2>&1
+
+
+### default settings with some posts
+
+cat > "${TEMP}/proj/content/post/foo.txt" <<EOF
+TITLE: Foo
+DATE: 2016-10-01
+----------------
+This is foo.
+EOF
+
+cat > "${TEMP}/proj/content/post/bar.txt" <<EOF
+TITLE: Bar
+DATE: 2016-09-01
+----------------
+This is bar.
+EOF
+
+cat > "${TEMP}/proj/templates/main.tmpl" <<EOF
+{% block listing %}
+Listing: {% ifdef FILTER_TAG %}{{ FILTER_TAG }} - {% endif %}{{ TITLE }} - {{ DATE_FORMATTED }}
+{% endblock %}
+{% block entry %}
+{{ TITLE }}{% if BM_TYPE == "post" %} - {{ DATE_FORMATTED }}{% endif %}
+
+{{ CONTENT }}
+{% endblock %}
+EOF
+
+cat >> "${TEMP}/proj/settings.ini" <<EOF
+[posts]
+foo
+bar
+EOF
+
+${TESTS_ENVIRONMENT} ./blogc-make -f "${TEMP}/proj/settings.ini" 2>&1 | tee "${TEMP}/output.txt"
+grep "_build/index\\.html" "${TEMP}/output.txt"
+grep "_build/atom\\.xml" "${TEMP}/output.txt"
+grep "_build/page/1/index\\.html" "${TEMP}/output.txt"
+grep "_build/post/foo/index\\.html" "${TEMP}/output.txt"
+grep "_build/post/bar/index\\.html" "${TEMP}/output.txt"
+
+rm "${TEMP}/output.txt"
+
+cat > "${TEMP}/expected-index.html" <<EOF
+
+Listing: Foo - Oct 01, 2016, 12:00 AM GMT
+
+Listing: Bar - Sep 01, 2016, 12:00 AM GMT
+
+
+EOF
+diff -uN "${TEMP}/proj/_build/index.html" "${TEMP}/expected-index.html"
+diff -uN "${TEMP}/proj/_build/page/1/index.html" "${TEMP}/expected-index.html"
+
+cat > "${TEMP}/expected-atom.xml" <<EOF
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">Lol's Website</title>
+ <id>/atom.xml</id>
+ <updated>2016-10-01T00:00:00Z</updated>
+ <link href="http://example.org/" />
+ <link href="http://example.org/atom.xml" rel="self" />
+ <author>
+ <name>Lol</name>
+ <email>author@example.com</email>
+ </author>
+ <subtitle type="text">WAT?!</subtitle>
+
+ <entry>
+ <title type="text">Foo</title>
+ <id>/post/foo/</id>
+ <updated>2016-10-01T00:00:00Z</updated>
+ <published>2016-10-01T00:00:00Z</published>
+ <link href="http://example.org/post/foo/" />
+ <author>
+ <name>Lol</name>
+ <email>author@example.com</email>
+ </author>
+ <content type="html"><![CDATA[<p>This is foo.</p>
+]]></content>
+ </entry>
+
+ <entry>
+ <title type="text">Bar</title>
+ <id>/post/bar/</id>
+ <updated>2016-09-01T00:00:00Z</updated>
+ <published>2016-09-01T00:00:00Z</published>
+ <link href="http://example.org/post/bar/" />
+ <author>
+ <name>Lol</name>
+ <email>author@example.com</email>
+ </author>
+ <content type="html"><![CDATA[<p>This is bar.</p>
+]]></content>
+ </entry>
+
+</feed>
+EOF
+diff -uN "${TEMP}/proj/_build/atom.xml" "${TEMP}/expected-atom.xml"
+
+cat > "${TEMP}/expected-post-foo.html" <<EOF
+
+
+Foo - Oct 01, 2016, 12:00 AM GMT
+
+<p>This is foo.</p>
+
+
+EOF
+diff -uN "${TEMP}/proj/_build/post/foo/index.html" "${TEMP}/expected-post-foo.html"
+
+cat > "${TEMP}/expected-post-bar.html" <<EOF
+
+
+Bar - Sep 01, 2016, 12:00 AM GMT
+
+<p>This is bar.</p>
+
+
+EOF
+diff -uN "${TEMP}/proj/_build/post/bar/index.html" "${TEMP}/expected-post-bar.html"
+
+rm -rf "${TEMP}/proj/_build"
+
+
+### default settings with some posts and tags
+
+cat > "${TEMP}/proj/content/post/baz.txt" <<EOF
+TITLE: Baz
+DATE: 2016-08-01
+TAGS: tag1 tag2
+----------------
+This is baz.
+EOF
+
+cat >> "${TEMP}/proj/settings.ini" <<EOF
+baz
+[tags]
+tag1
+tag2
+EOF
+
+${TESTS_ENVIRONMENT} ./blogc-make -f "${TEMP}/proj/settings.ini" 2>&1 | tee "${TEMP}/output.txt"
+grep "_build/index\\.html" "${TEMP}/output.txt"
+grep "_build/atom\\.xml" "${TEMP}/output.txt"
+grep "_build/atom/tag1\\.xml" "${TEMP}/output.txt"
+grep "_build/atom/tag2\\.xml" "${TEMP}/output.txt"
+grep "_build/page/1/index\\.html" "${TEMP}/output.txt"
+grep "_build/post/foo/index\\.html" "${TEMP}/output.txt"
+grep "_build/post/bar/index\\.html" "${TEMP}/output.txt"
+grep "_build/post/baz/index\\.html" "${TEMP}/output.txt"
+grep "_build/tag/tag1/index\\.html" "${TEMP}/output.txt"
+grep "_build/tag/tag2/index\\.html" "${TEMP}/output.txt"
+
+rm "${TEMP}/output.txt"
+
+cat > "${TEMP}/expected-index.html" <<EOF
+
+Listing: Foo - Oct 01, 2016, 12:00 AM GMT
+
+Listing: Bar - Sep 01, 2016, 12:00 AM GMT
+
+Listing: Baz - Aug 01, 2016, 12:00 AM GMT
+
+
+EOF
+diff -uN "${TEMP}/proj/_build/index.html" "${TEMP}/expected-index.html"
+diff -uN "${TEMP}/proj/_build/page/1/index.html" "${TEMP}/expected-index.html"
+
+cat > "${TEMP}/expected-atom.xml" <<EOF
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">Lol's Website</title>
+ <id>/atom.xml</id>
+ <updated>2016-10-01T00:00:00Z</updated>
+ <link href="http://example.org/" />
+ <link href="http://example.org/atom.xml" rel="self" />
+ <author>
+ <name>Lol</name>
+ <email>author@example.com</email>
+ </author>
+ <subtitle type="text">WAT?!</subtitle>
+
+ <entry>
+ <title type="text">Foo</title>
+ <id>/post/foo/</id>
+ <updated>2016-10-01T00:00:00Z</updated>
+ <published>2016-10-01T00:00:00Z</published>
+ <link href="http://example.org/post/foo/" />
+ <author>
+ <name>Lol</name>
+ <email>author@example.com</email>
+ </author>
+ <content type="html"><![CDATA[<p>This is foo.</p>
+]]></content>
+ </entry>
+
+ <entry>
+ <title type="text">Bar</title>
+ <id>/post/bar/</id>
+ <updated>2016-09-01T00:00:00Z</updated>
+ <published>2016-09-01T00:00:00Z</published>
+ <link href="http://example.org/post/bar/" />
+ <author>
+ <name>Lol</name>
+ <email>author@example.com</email>
+ </author>
+ <content type="html"><![CDATA[<p>This is bar.</p>
+]]></content>
+ </entry>
+
+ <entry>
+ <title type="text">Baz</title>
+ <id>/post/baz/</id>
+ <updated>2016-08-01T00:00:00Z</updated>
+ <published>2016-08-01T00:00:00Z</published>
+ <link href="http://example.org/post/baz/" />
+ <author>
+ <name>Lol</name>
+ <email>author@example.com</email>
+ </author>
+ <content type="html"><![CDATA[<p>This is baz.</p>
+]]></content>
+ </entry>
+
+</feed>
+EOF
+diff -uN "${TEMP}/proj/_build/atom.xml" "${TEMP}/expected-atom.xml"
+
+cat > "${TEMP}/expected-atom-tag1.xml" <<EOF
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">Lol's Website - tag1</title>
+ <id>/atom/tag1.xml</id>
+ <updated>2016-08-01T00:00:00Z</updated>
+ <link href="http://example.org/" />
+ <link href="http://example.org/atom/tag1.xml" rel="self" />
+ <author>
+ <name>Lol</name>
+ <email>author@example.com</email>
+ </author>
+ <subtitle type="text">WAT?!</subtitle>
+
+ <entry>
+ <title type="text">Baz</title>
+ <id>/post/baz/</id>
+ <updated>2016-08-01T00:00:00Z</updated>
+ <published>2016-08-01T00:00:00Z</published>
+ <link href="http://example.org/post/baz/" />
+ <author>
+ <name>Lol</name>
+ <email>author@example.com</email>
+ </author>
+ <content type="html"><![CDATA[<p>This is baz.</p>
+]]></content>
+ </entry>
+
+</feed>
+EOF
+diff -uN "${TEMP}/proj/_build/atom/tag1.xml" "${TEMP}/expected-atom-tag1.xml"
+
+cat > "${TEMP}/expected-atom-tag2.xml" <<EOF
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">Lol's Website - tag2</title>
+ <id>/atom/tag2.xml</id>
+ <updated>2016-08-01T00:00:00Z</updated>
+ <link href="http://example.org/" />
+ <link href="http://example.org/atom/tag2.xml" rel="self" />
+ <author>
+ <name>Lol</name>
+ <email>author@example.com</email>
+ </author>
+ <subtitle type="text">WAT?!</subtitle>
+
+ <entry>
+ <title type="text">Baz</title>
+ <id>/post/baz/</id>
+ <updated>2016-08-01T00:00:00Z</updated>
+ <published>2016-08-01T00:00:00Z</published>
+ <link href="http://example.org/post/baz/" />
+ <author>
+ <name>Lol</name>
+ <email>author@example.com</email>
+ </author>
+ <content type="html"><![CDATA[<p>This is baz.</p>
+]]></content>
+ </entry>
+
+</feed>
+EOF
+diff -uN "${TEMP}/proj/_build/atom/tag2.xml" "${TEMP}/expected-atom-tag2.xml"
+
+cat > "${TEMP}/expected-post-baz.html" <<EOF
+
+
+Baz - Aug 01, 2016, 12:00 AM GMT
+
+<p>This is baz.</p>
+
+
+EOF
+diff -uN "${TEMP}/proj/_build/post/foo/index.html" "${TEMP}/expected-post-foo.html"
+diff -uN "${TEMP}/proj/_build/post/bar/index.html" "${TEMP}/expected-post-bar.html"
+diff -uN "${TEMP}/proj/_build/post/baz/index.html" "${TEMP}/expected-post-baz.html"
+
+cat > "${TEMP}/expected-tag1.html" <<EOF
+
+Listing: tag1 - Baz - Aug 01, 2016, 12:00 AM GMT
+
+
+EOF
+diff -uN "${TEMP}/proj/_build/tag/tag1/index.html" "${TEMP}/expected-tag1.html"
+
+cat > "${TEMP}/expected-tag2.html" <<EOF
+
+Listing: tag2 - Baz - Aug 01, 2016, 12:00 AM GMT
+
+
+EOF
+diff -uN "${TEMP}/proj/_build/tag/tag2/index.html" "${TEMP}/expected-tag2.html"
+
+rm -rf "${TEMP}/proj/_build"
+
+
+### default settings with some posts, pages and tags
+
+cat > "${TEMP}/proj/content/page1.txt" <<EOF
+TITLE: Page 1
+-------------
+This is page 1.
+EOF
+
+cat > "${TEMP}/proj/content/page2.txt" <<EOF
+TITLE: Page 2
+-------------
+This is page 2.
+EOF
+
+cat >> "${TEMP}/proj/settings.ini" <<EOF
+[pages]
+page1
+page2
+EOF
+
+${TESTS_ENVIRONMENT} ./blogc-make -f "${TEMP}/proj/settings.ini" 2>&1 | tee "${TEMP}/output.txt"
+grep "_build/index\\.html" "${TEMP}/output.txt"
+grep "_build/atom\\.xml" "${TEMP}/output.txt"
+grep "_build/atom/tag1\\.xml" "${TEMP}/output.txt"
+grep "_build/atom/tag2\\.xml" "${TEMP}/output.txt"
+grep "_build/page/1/index\\.html" "${TEMP}/output.txt"
+grep "_build/post/foo/index\\.html" "${TEMP}/output.txt"
+grep "_build/post/bar/index\\.html" "${TEMP}/output.txt"
+grep "_build/post/baz/index\\.html" "${TEMP}/output.txt"
+grep "_build/tag/tag1/index\\.html" "${TEMP}/output.txt"
+grep "_build/tag/tag2/index\\.html" "${TEMP}/output.txt"
+grep "_build/page1/index\\.html" "${TEMP}/output.txt"
+grep "_build/page2/index\\.html" "${TEMP}/output.txt"
+
+rm "${TEMP}/output.txt"
+
+diff -uN "${TEMP}/proj/_build/index.html" "${TEMP}/expected-index.html"
+diff -uN "${TEMP}/proj/_build/page/1/index.html" "${TEMP}/expected-index.html"
+
+diff -uN "${TEMP}/proj/_build/atom.xml" "${TEMP}/expected-atom.xml"
+
+diff -uN "${TEMP}/proj/_build/atom/tag1.xml" "${TEMP}/expected-atom-tag1.xml"
+diff -uN "${TEMP}/proj/_build/atom/tag2.xml" "${TEMP}/expected-atom-tag2.xml"
+
+diff -uN "${TEMP}/proj/_build/post/foo/index.html" "${TEMP}/expected-post-foo.html"
+diff -uN "${TEMP}/proj/_build/post/bar/index.html" "${TEMP}/expected-post-bar.html"
+diff -uN "${TEMP}/proj/_build/post/baz/index.html" "${TEMP}/expected-post-baz.html"
+
+diff -uN "${TEMP}/proj/_build/tag/tag1/index.html" "${TEMP}/expected-tag1.html"
+diff -uN "${TEMP}/proj/_build/tag/tag2/index.html" "${TEMP}/expected-tag2.html"
+
+cat > "${TEMP}/expected-page1.html" <<EOF
+
+
+Page 1
+
+<p>This is page 1.</p>
+
+
+EOF
+diff -uN "${TEMP}/proj/_build/page1/index.html" "${TEMP}/expected-page1.html"
+
+cat > "${TEMP}/expected-page2.html" <<EOF
+
+
+Page 2
+
+<p>This is page 2.</p>
+
+
+EOF
+diff -uN "${TEMP}/proj/_build/page2/index.html" "${TEMP}/expected-page2.html"
+
+rm -rf "${TEMP}/proj"
+mkdir -p "${TEMP}"/proj{,/temp,/contents/poost}
+
+
+### custom settings with some posts
+
+cat > "${TEMP}/proj/contents/poost/foo.blogc" <<EOF
+TITLE: Foo
+DATE: 2016-10-01
+----------------
+This is foo.
+EOF
+
+cat > "${TEMP}/proj/contents/poost/bar.blogc" <<EOF
+TITLE: Bar
+DATE: 2016-09-01
+----------------
+This is bar.
+EOF
+
+cat > "${TEMP}/proj/temp/main.html" <<EOF
+{% block listing %}
+Listing: {% ifdef FILTER_TAG %}{{ FILTER_TAG }} - {% endif %}{{ TITLE }} - {{ DATE_FORMATTED }}
+{% endblock %}
+{% block entry %}
+{{ TITLE }}{% if BM_TYPE == "post" %} - {{ DATE_FORMATTED }}{% endif %}
+
+{{ CONTENT }}
+{% endblock %}
+EOF
+
+cat > "${TEMP}/proj/settings.ini" <<EOF
+[settings]
+content_dir = contents
+template_dir = temp
+main_template = main.html
+source_ext = .blogc
+output_dir = _blogc_build
+pagination_prefix = pagination
+posts_per_page = 1
+atom_posts_per_page = 1
+html_ext = .html
+index_prefix = posts
+post_prefix = poost
+tag_prefix = taag
+atom_prefix = atoom
+atom_ext = /index.xml
+date_format = %b %d, %Y
+locale = en_US.utf8
+
+[environment]
+AUTHOR_NAME = Lol
+AUTHOR_EMAIL = author@example.com
+SITE_TITLE = Lol's Website
+SITE_TAGLINE = WAT?!
+BASE_DOMAIN = http://example.org
+
+[posts]
+foo
+bar
+EOF
+
+${TESTS_ENVIRONMENT} ./blogc-make -f "${TEMP}/proj/settings.ini" 2>&1 | tee "${TEMP}/output.txt"
+grep "_blogc_build/posts\\.html" "${TEMP}/output.txt"
+grep "_blogc_build/atoom/index\\.xml" "${TEMP}/output.txt"
+grep "_blogc_build/pagination/1\\.html" "${TEMP}/output.txt"
+grep "_blogc_build/pagination/2\\.html" "${TEMP}/output.txt"
+grep "_blogc_build/poost/foo\\.html" "${TEMP}/output.txt"
+grep "_blogc_build/poost/bar\\.html" "${TEMP}/output.txt"
+
+rm "${TEMP}/output.txt"
+
+cat > "${TEMP}/expected-index.html" <<EOF
+
+Listing: Foo - Oct 01, 2016
+
+
+EOF
+diff -uN "${TEMP}/proj/_blogc_build/posts.html" "${TEMP}/expected-index.html"
+diff -uN "${TEMP}/proj/_blogc_build/pagination/1.html" "${TEMP}/expected-index.html"
+
+cat > "${TEMP}/expected-page-2.html" <<EOF
+
+Listing: Bar - Sep 01, 2016
+
+
+EOF
+diff -uN "${TEMP}/proj/_blogc_build/pagination/2.html" "${TEMP}/expected-page-2.html"
+
+cat > "${TEMP}/expected-atom.xml" <<EOF
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">Lol's Website</title>
+ <id>/atoom/index.xml</id>
+ <updated>2016-10-01T00:00:00Z</updated>
+ <link href="http://example.org/" />
+ <link href="http://example.org/atoom/index.xml" rel="self" />
+ <author>
+ <name>Lol</name>
+ <email>author@example.com</email>
+ </author>
+ <subtitle type="text">WAT?!</subtitle>
+
+ <entry>
+ <title type="text">Foo</title>
+ <id>/poost/foo/</id>
+ <updated>2016-10-01T00:00:00Z</updated>
+ <published>2016-10-01T00:00:00Z</published>
+ <link href="http://example.org/poost/foo/" />
+ <author>
+ <name>Lol</name>
+ <email>author@example.com</email>
+ </author>
+ <content type="html"><![CDATA[<p>This is foo.</p>
+]]></content>
+ </entry>
+
+</feed>
+EOF
+diff -uN "${TEMP}/proj/_blogc_build/atoom/index.xml" "${TEMP}/expected-atom.xml"
+
+cat > "${TEMP}/expected-post-foo.html" <<EOF
+
+
+Foo - Oct 01, 2016
+
+<p>This is foo.</p>
+
+
+EOF
+diff -uN "${TEMP}/proj/_blogc_build/poost/foo.html" "${TEMP}/expected-post-foo.html"
+
+cat > "${TEMP}/expected-post-bar.html" <<EOF
+
+
+Bar - Sep 01, 2016
+
+<p>This is bar.</p>
+
+
+EOF
+diff -uN "${TEMP}/proj/_blogc_build/poost/bar.html" "${TEMP}/expected-post-bar.html"
+
+rm -rf "${TEMP}/proj/_build"
+
+
+### default settings with some posts and tags
+
+cat > "${TEMP}/proj/contents/poost/baz.blogc" <<EOF
+TITLE: Baz
+DATE: 2016-08-01
+TAGS: tag1 tag2
+----------------
+This is baz.
+EOF
+
+cat >> "${TEMP}/proj/settings.ini" <<EOF
+baz
+[tags]
+tag1
+tag2
+EOF
+
+${TESTS_ENVIRONMENT} ./blogc-make -f "${TEMP}/proj/settings.ini" 2>&1 | tee "${TEMP}/output.txt"
+grep "_blogc_build/posts\\.html" "${TEMP}/output.txt"
+grep "_blogc_build/atoom/index\\.xml" "${TEMP}/output.txt"
+grep "_blogc_build/atoom/tag1/index\\.xml" "${TEMP}/output.txt"
+grep "_blogc_build/atoom/tag2/index\\.xml" "${TEMP}/output.txt"
+grep "_blogc_build/pagination/1\\.html" "${TEMP}/output.txt"
+grep "_blogc_build/pagination/2\\.html" "${TEMP}/output.txt"
+grep "_blogc_build/pagination/3\\.html" "${TEMP}/output.txt"
+grep "_blogc_build/poost/foo\\.html" "${TEMP}/output.txt"
+grep "_blogc_build/poost/bar\\.html" "${TEMP}/output.txt"
+grep "_blogc_build/poost/baz\\.html" "${TEMP}/output.txt"
+grep "_blogc_build/taag/tag1\\.html" "${TEMP}/output.txt"
+grep "_blogc_build/taag/tag2\\.html" "${TEMP}/output.txt"
+
+rm "${TEMP}/output.txt"
+
+diff -uN "${TEMP}/proj/_blogc_build/posts.html" "${TEMP}/expected-index.html"
+diff -uN "${TEMP}/proj/_blogc_build/pagination/1.html" "${TEMP}/expected-index.html"
+diff -uN "${TEMP}/proj/_blogc_build/pagination/2.html" "${TEMP}/expected-page-2.html"
+
+cat > "${TEMP}/expected-page-3.html" <<EOF
+
+Listing: Baz - Aug 01, 2016
+
+
+EOF
+diff -uN "${TEMP}/proj/_blogc_build/pagination/3.html" "${TEMP}/expected-page-3.html"
+
+diff -uN "${TEMP}/proj/_blogc_build/atoom/index.xml" "${TEMP}/expected-atom.xml"
+
+cat > "${TEMP}/expected-atom-tag1.xml" <<EOF
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">Lol's Website - tag1</title>
+ <id>/atoom/tag1/index.xml</id>
+ <updated>2016-08-01T00:00:00Z</updated>
+ <link href="http://example.org/" />
+ <link href="http://example.org/atoom/tag1/index.xml" rel="self" />
+ <author>
+ <name>Lol</name>
+ <email>author@example.com</email>
+ </author>
+ <subtitle type="text">WAT?!</subtitle>
+
+ <entry>
+ <title type="text">Baz</title>
+ <id>/poost/baz/</id>
+ <updated>2016-08-01T00:00:00Z</updated>
+ <published>2016-08-01T00:00:00Z</published>
+ <link href="http://example.org/poost/baz/" />
+ <author>
+ <name>Lol</name>
+ <email>author@example.com</email>
+ </author>
+ <content type="html"><![CDATA[<p>This is baz.</p>
+]]></content>
+ </entry>
+
+</feed>
+EOF
+diff -uN "${TEMP}/proj/_blogc_build/atoom/tag1/index.xml" "${TEMP}/expected-atom-tag1.xml"
+
+cat > "${TEMP}/expected-atom-tag2.xml" <<EOF
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">Lol's Website - tag2</title>
+ <id>/atoom/tag2/index.xml</id>
+ <updated>2016-08-01T00:00:00Z</updated>
+ <link href="http://example.org/" />
+ <link href="http://example.org/atoom/tag2/index.xml" rel="self" />
+ <author>
+ <name>Lol</name>
+ <email>author@example.com</email>
+ </author>
+ <subtitle type="text">WAT?!</subtitle>
+
+ <entry>
+ <title type="text">Baz</title>
+ <id>/poost/baz/</id>
+ <updated>2016-08-01T00:00:00Z</updated>
+ <published>2016-08-01T00:00:00Z</published>
+ <link href="http://example.org/poost/baz/" />
+ <author>
+ <name>Lol</name>
+ <email>author@example.com</email>
+ </author>
+ <content type="html"><![CDATA[<p>This is baz.</p>
+]]></content>
+ </entry>
+
+</feed>
+EOF
+diff -uN "${TEMP}/proj/_blogc_build/atoom/tag2/index.xml" "${TEMP}/expected-atom-tag2.xml"
+
+cat > "${TEMP}/expected-post-baz.html" <<EOF
+
+
+Baz - Aug 01, 2016
+
+<p>This is baz.</p>
+
+
+EOF
+diff -uN "${TEMP}/proj/_blogc_build/poost/foo.html" "${TEMP}/expected-post-foo.html"
+diff -uN "${TEMP}/proj/_blogc_build/poost/bar.html" "${TEMP}/expected-post-bar.html"
+diff -uN "${TEMP}/proj/_blogc_build/poost/baz.html" "${TEMP}/expected-post-baz.html"
+
+cat > "${TEMP}/expected-tag1.html" <<EOF
+
+Listing: tag1 - Baz - Aug 01, 2016
+
+
+EOF
+diff -uN "${TEMP}/proj/_blogc_build/taag/tag1.html" "${TEMP}/expected-tag1.html"
+
+cat > "${TEMP}/expected-tag2.html" <<EOF
+
+Listing: tag2 - Baz - Aug 01, 2016
+
+
+EOF
+diff -uN "${TEMP}/proj/_blogc_build/taag/tag2.html" "${TEMP}/expected-tag2.html"
+
+rm -rf "${TEMP}/proj/_blogc_build"
+
+
+### default settings with some posts, pages and tags
+
+cat > "${TEMP}/proj/contents/page1.blogc" <<EOF
+TITLE: Page 1
+-------------
+This is page 1.
+EOF
+
+cat > "${TEMP}/proj/contents/page2.blogc" <<EOF
+TITLE: Page 2
+-------------
+This is page 2.
+EOF
+
+cat >> "${TEMP}/proj/settings.ini" <<EOF
+[pages]
+page1
+page2
+EOF
+
+${TESTS_ENVIRONMENT} ./blogc-make -f "${TEMP}/proj/settings.ini" 2>&1 | tee "${TEMP}/output.txt"
+grep "_blogc_build/posts\\.html" "${TEMP}/output.txt"
+grep "_blogc_build/atoom/index\\.xml" "${TEMP}/output.txt"
+grep "_blogc_build/atoom/tag1/index\\.xml" "${TEMP}/output.txt"
+grep "_blogc_build/atoom/tag2/index\\.xml" "${TEMP}/output.txt"
+grep "_blogc_build/pagination/1\\.html" "${TEMP}/output.txt"
+grep "_blogc_build/pagination/2\\.html" "${TEMP}/output.txt"
+grep "_blogc_build/pagination/3\\.html" "${TEMP}/output.txt"
+grep "_blogc_build/poost/foo\\.html" "${TEMP}/output.txt"
+grep "_blogc_build/poost/bar\\.html" "${TEMP}/output.txt"
+grep "_blogc_build/poost/baz\\.html" "${TEMP}/output.txt"
+grep "_blogc_build/taag/tag1\\.html" "${TEMP}/output.txt"
+grep "_blogc_build/taag/tag2\\.html" "${TEMP}/output.txt"
+grep "_blogc_build/page1\\.html" "${TEMP}/output.txt"
+grep "_blogc_build/page2\\.html" "${TEMP}/output.txt"
+
+rm "${TEMP}/output.txt"
+
+diff -uN "${TEMP}/proj/_blogc_build/posts.html" "${TEMP}/expected-index.html"
+diff -uN "${TEMP}/proj/_blogc_build/pagination/1.html" "${TEMP}/expected-index.html"
+diff -uN "${TEMP}/proj/_blogc_build/pagination/2.html" "${TEMP}/expected-page-2.html"
+diff -uN "${TEMP}/proj/_blogc_build/pagination/3.html" "${TEMP}/expected-page-3.html"
+
+diff -uN "${TEMP}/proj/_blogc_build/atoom/index.xml" "${TEMP}/expected-atom.xml"
+diff -uN "${TEMP}/proj/_blogc_build/atoom/tag1/index.xml" "${TEMP}/expected-atom-tag1.xml"
+diff -uN "${TEMP}/proj/_blogc_build/atoom/tag2/index.xml" "${TEMP}/expected-atom-tag2.xml"
+
+diff -uN "${TEMP}/proj/_blogc_build/poost/foo.html" "${TEMP}/expected-post-foo.html"
+diff -uN "${TEMP}/proj/_blogc_build/poost/bar.html" "${TEMP}/expected-post-bar.html"
+diff -uN "${TEMP}/proj/_blogc_build/poost/baz.html" "${TEMP}/expected-post-baz.html"
+
+diff -uN "${TEMP}/proj/_blogc_build/taag/tag1.html" "${TEMP}/expected-tag1.html"
+diff -uN "${TEMP}/proj/_blogc_build/taag/tag2.html" "${TEMP}/expected-tag2.html"
+
+cat > "${TEMP}/expected-page1.html" <<EOF
+
+
+Page 1
+
+<p>This is page 1.</p>
+
+
+EOF
+diff -uN "${TEMP}/proj/_blogc_build/page1.html" "${TEMP}/expected-page1.html"
+
+cat > "${TEMP}/expected-page2.html" <<EOF
+
+
+Page 2
+
+<p>This is page 2.</p>
+
+
+EOF
+diff -uN "${TEMP}/proj/_blogc_build/page2.html" "${TEMP}/expected-page2.html"
+
+rm -rf "${TEMP}/proj/_blogc_build"
diff --git a/tests/blogc-make/check_exec.c b/tests/blogc-make/check_exec.c
new file mode 100644
index 0000000..ce87f09
--- /dev/null
+++ b/tests/blogc-make/check_exec.c
@@ -0,0 +1,138 @@
+/*
+ * blogc: A blog compiler.
+ * Copyright (C) 2015-2016 Rafael G. Martins <rafael@rafaelmartins.eng.br>
+ *
+ * This program can be distributed under the terms of the BSD License.
+ * See the file LICENSE.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "../../src/blogc-make/exec.h"
+#include "../../src/blogc-make/settings.h"
+#include "../../src/common/utils.h"
+
+
+static void
+test_build_blogc_cmd_with_settings(void **state)
+{
+ unsetenv("BLOGC");
+
+ bm_settings_t *settings = bc_malloc(sizeof(bm_settings_t));
+ settings->settings = bc_trie_new(free);
+ bc_trie_insert(settings->settings, "locale", bc_strdup("en_US.utf8"));
+ settings->env = bc_trie_new(free);
+ bc_trie_insert(settings->env, "FOO", bc_strdup("BAR"));
+ bc_trie_insert(settings->env, "BAR", bc_strdup("BAZ"));
+ bc_trie_t *variables = bc_trie_new(free);
+ bc_trie_insert(variables, "LOL", bc_strdup("HEHE"));
+
+ char *rv = bm_exec_build_blogc_cmd(settings, variables, true, "main.tmpl",
+ "foo.html", true);
+ assert_string_equal(rv,
+ "LC_ALL='en_US.utf8' blogc -D FOO='BAR' -D BAR='BAZ' -D LOL='HEHE' -l "
+ "-t 'main.tmpl' -o 'foo.html' -i");
+ free(rv);
+
+ rv = bm_exec_build_blogc_cmd(settings, variables, false, NULL, NULL, false);
+ assert_string_equal(rv,
+ "LC_ALL='en_US.utf8' blogc -D FOO='BAR' -D BAR='BAZ' -D LOL='HEHE'");
+ free(rv);
+
+ rv = bm_exec_build_blogc_cmd(settings, NULL, false, NULL, NULL, false);
+ assert_string_equal(rv,
+ "LC_ALL='en_US.utf8' blogc -D FOO='BAR' -D BAR='BAZ'");
+ free(rv);
+
+ setenv("BLOGC", "/path/to/blogc", 1);
+
+ rv = bm_exec_build_blogc_cmd(settings, variables, true, "main.tmpl",
+ "foo.html", true);
+ assert_string_equal(rv,
+ "LC_ALL='en_US.utf8' /path/to/blogc -D FOO='BAR' -D BAR='BAZ' "
+ "-D LOL='HEHE' -l -t 'main.tmpl' -o 'foo.html' -i");
+ free(rv);
+
+ rv = bm_exec_build_blogc_cmd(settings, variables, false, NULL, NULL, false);
+ assert_string_equal(rv,
+ "LC_ALL='en_US.utf8' /path/to/blogc -D FOO='BAR' -D BAR='BAZ' "
+ "-D LOL='HEHE'");
+ free(rv);
+
+ rv = bm_exec_build_blogc_cmd(settings, NULL, false, NULL, NULL, false);
+ assert_string_equal(rv,
+ "LC_ALL='en_US.utf8' /path/to/blogc -D FOO='BAR' -D BAR='BAZ'");
+ free(rv);
+
+ unsetenv("BLOGC");
+
+ bc_trie_free(variables);
+ bc_trie_free(settings->settings);
+ bc_trie_free(settings->env);
+ free(settings);
+}
+
+
+static void
+test_build_blogc_cmd_without_settings(void **state)
+{
+ unsetenv("BLOGC");
+
+ bc_trie_t *variables = bc_trie_new(free);
+ bc_trie_insert(variables, "LOL", bc_strdup("HEHE"));
+
+ char *rv = bm_exec_build_blogc_cmd(NULL, variables, true, "main.tmpl",
+ "foo.html", true);
+ assert_string_equal(rv,
+ "blogc -D LOL='HEHE' -l -t 'main.tmpl' -o 'foo.html' -i");
+ free(rv);
+
+ rv = bm_exec_build_blogc_cmd(NULL, variables, false, NULL, NULL, false);
+ assert_string_equal(rv,
+ "blogc -D LOL='HEHE'");
+ free(rv);
+
+ rv = bm_exec_build_blogc_cmd(NULL, NULL, false, NULL, NULL, false);
+ assert_string_equal(rv,
+ "blogc");
+ free(rv);
+
+ setenv("BLOGC", "/path/to/blogc", 1);
+
+ rv = bm_exec_build_blogc_cmd(NULL, variables, true, "main.tmpl", "foo.html",
+ true);
+ assert_string_equal(rv,
+ "/path/to/blogc -D LOL='HEHE' -l -t 'main.tmpl' -o 'foo.html' -i");
+ free(rv);
+
+ rv = bm_exec_build_blogc_cmd(NULL, variables, false, NULL, NULL, false);
+ assert_string_equal(rv,
+ "/path/to/blogc -D LOL='HEHE'");
+ free(rv);
+
+ rv = bm_exec_build_blogc_cmd(NULL, NULL, false, NULL, NULL, false);
+ assert_string_equal(rv,
+ "/path/to/blogc");
+ free(rv);
+
+ unsetenv("BLOGC");
+
+ bc_trie_free(variables);
+}
+
+
+int
+main(void)
+{
+ const UnitTest tests[] = {
+ unit_test(test_build_blogc_cmd_with_settings),
+ unit_test(test_build_blogc_cmd_without_settings),
+ };
+ return run_tests(tests);
+}