Add tests and refactor config
This commit is contained in:
106
tests/test_config.sh
Executable file
106
tests/test_config.sh
Executable file
@@ -0,0 +1,106 @@
|
||||
test_config_defaults() {
|
||||
. "$project_dir/lib/config.sh"
|
||||
|
||||
assert_eq "kewt" "$title" "default title"
|
||||
assert_eq "kewt" "$style" "default style"
|
||||
assert_eq "en" "$lang" "default lang"
|
||||
assert_eq "false" "$draft_by_default" "default draft_by_default"
|
||||
assert_eq "true" "$dir_indexes" "default dir_indexes"
|
||||
assert_eq "true" "$single_file_index" "default single_file_index"
|
||||
assert_eq "false" "$flatten" "default flatten"
|
||||
assert_eq "Home" "$home_name" "default home_name"
|
||||
assert_eq "true" "$show_home_in_nav" "default show_home_in_nav"
|
||||
assert_eq "false" "$generate_feed" "default generate_feed"
|
||||
assert_eq "rss.xml" "$feed_file" "default feed_file"
|
||||
assert_eq "12" "$posts_per_page" "default posts_per_page"
|
||||
assert_eq "false" "$generate_tags" "default generate_tags"
|
||||
assert_eq "tags" "$tags_dir" "default tags_dir"
|
||||
assert_eq "false" "$generate_search" "default generate_search"
|
||||
assert_eq "true" "$enable_header_links" "default enable_header_links"
|
||||
assert_eq "true" "$cw_hide_url" "default cw_hide_url"
|
||||
}
|
||||
|
||||
test_config_reset() {
|
||||
. "$project_dir/lib/config.sh"
|
||||
title="custom"
|
||||
style="nord"
|
||||
generate_feed="true"
|
||||
reset_config
|
||||
|
||||
assert_eq "kewt" "$title" "reset title"
|
||||
assert_eq "kewt" "$style" "reset style"
|
||||
assert_eq "false" "$generate_feed" "reset generate_feed"
|
||||
}
|
||||
|
||||
test_config_load() {
|
||||
. "$project_dir/lib/config.sh"
|
||||
|
||||
tmpdir="${TMPDIR:-/tmp}/kewt_test.$$"
|
||||
mkdir -p "$tmpdir"
|
||||
cat > "$tmpdir/test.conf" <<EOF
|
||||
title = "My Site"
|
||||
style = "nord"
|
||||
generate_feed = true
|
||||
base_url = "https://example.com"
|
||||
posts_per_page = 5
|
||||
EOF
|
||||
|
||||
reset_config
|
||||
load_config "$tmpdir/test.conf"
|
||||
|
||||
assert_eq "My Site" "$title" "load title"
|
||||
assert_eq "nord" "$style" "load style"
|
||||
assert_eq "true" "$generate_feed" "load generate_feed"
|
||||
assert_eq "https://example.com" "$base_url" "load base_url"
|
||||
assert_eq "5" "$posts_per_page" "load posts_per_page"
|
||||
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
|
||||
test_config_load_quoted() {
|
||||
. "$project_dir/lib/config.sh"
|
||||
|
||||
tmpdir="${TMPDIR:-/tmp}/kewt_test.$$"
|
||||
mkdir -p "$tmpdir"
|
||||
cat > "$tmpdir/test.conf" <<'EOF'
|
||||
footer = "made with <a href=\"https://kewt.krzak.org\">kewt</a>"
|
||||
nav_links = "[Docs](/docs), [About](/about)"
|
||||
EOF
|
||||
|
||||
reset_config
|
||||
load_config "$tmpdir/test.conf"
|
||||
|
||||
assert_eq 'made with <a href="https://kewt.krzak.org">kewt</a>' "$footer" "load quoted footer"
|
||||
assert_eq "[Docs](/docs), [About](/about)" "$nav_links" "load quoted nav_links"
|
||||
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
|
||||
test_config_load_skips_comments() {
|
||||
. "$project_dir/lib/config.sh"
|
||||
|
||||
tmpdir="${TMPDIR:-/tmp}/kewt_test.$$"
|
||||
mkdir -p "$tmpdir"
|
||||
cat > "$tmpdir/test.conf" <<EOF
|
||||
# This is a comment
|
||||
title = "Test Site"
|
||||
# Another comment
|
||||
style = "kewt"
|
||||
EOF
|
||||
|
||||
reset_config
|
||||
load_config "$tmpdir/test.conf"
|
||||
|
||||
assert_eq "Test Site" "$title" "load with comments title"
|
||||
assert_eq "kewt" "$style" "load with comments style"
|
||||
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
|
||||
test_config_load_missing_file() {
|
||||
. "$project_dir/lib/config.sh"
|
||||
reset_config
|
||||
load_config "/nonexistent/path/site.conf"
|
||||
|
||||
assert_eq "kewt" "$title" "missing file keeps defaults"
|
||||
}
|
||||
92
tests/test_metadata.sh
Executable file
92
tests/test_metadata.sh
Executable file
@@ -0,0 +1,92 @@
|
||||
test_strip_markdown_bold() {
|
||||
. "$project_dir/lib/metadata.sh"
|
||||
result=$(strip_markdown_text "**bold text**")
|
||||
assert_eq "bold text" "$result" "strip bold"
|
||||
}
|
||||
|
||||
test_strip_markdown_italic() {
|
||||
. "$project_dir/lib/metadata.sh"
|
||||
result=$(strip_markdown_text "*italic text*")
|
||||
assert_eq "italic text" "$result" "strip italic"
|
||||
}
|
||||
|
||||
test_strip_markdown_link() {
|
||||
. "$project_dir/lib/metadata.sh"
|
||||
result=$(strip_markdown_text "[link](http://example.com)")
|
||||
assert_eq "link" "$result" "strip link"
|
||||
}
|
||||
|
||||
test_strip_markdown_code() {
|
||||
. "$project_dir/lib/metadata.sh"
|
||||
result=$(strip_markdown_text "\`code\`")
|
||||
assert_eq "code" "$result" "strip code"
|
||||
}
|
||||
|
||||
test_first_heading() {
|
||||
tmpdir="${TMPDIR:-/tmp}/kewt_test.$$"
|
||||
mkdir -p "$tmpdir"
|
||||
printf '# Hello World\n\nSome content\n' > "$tmpdir/test.md"
|
||||
|
||||
. "$project_dir/lib/metadata.sh"
|
||||
result=$(first_heading_from_markdown "$tmpdir/test.md")
|
||||
assert_eq "Hello World" "$result" "first heading"
|
||||
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
|
||||
test_first_heading_no_heading() {
|
||||
tmpdir="${TMPDIR:-/tmp}/kewt_test.$$"
|
||||
mkdir -p "$tmpdir"
|
||||
printf 'Random content\n' > "$tmpdir/test.md"
|
||||
|
||||
. "$project_dir/lib/metadata.sh"
|
||||
result=$(first_heading_from_markdown "$tmpdir/test.md")
|
||||
assert_eq "" "$result" "no heading returns empty"
|
||||
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
|
||||
test_parse_frontmatter() {
|
||||
tmpdir="${TMPDIR:-/tmp}/kewt_test.$$"
|
||||
mkdir -p "$tmpdir"
|
||||
cat > "$tmpdir/test.md" <<'EOF'
|
||||
---
|
||||
title = "My Post"
|
||||
date = "2026-05-20 10:00"
|
||||
draft = false
|
||||
description = "A test post"
|
||||
tags = "test, example"
|
||||
---
|
||||
|
||||
# Content
|
||||
EOF
|
||||
|
||||
export KEWT_TMPDIR="$tmpdir"
|
||||
export awk_dir="$project_dir/awk"
|
||||
. "$project_dir/lib/metadata.sh"
|
||||
. "$project_dir/lib/config.sh"
|
||||
|
||||
parse_frontmatter "$tmpdir/test.md"
|
||||
|
||||
assert_eq "My Post" "$fm_title" "parse title"
|
||||
assert_eq "2026-05-20 10:00" "$fm_date" "parse date"
|
||||
assert_eq "false" "$fm_draft" "parse draft"
|
||||
assert_eq "A test post" "$fm_description" "parse description"
|
||||
assert_eq "test, example" "$fm_tags" "parse tags"
|
||||
|
||||
rm -rf "$tmpdir"
|
||||
}
|
||||
|
||||
test_set_post_datetime_from_date() {
|
||||
. "$project_dir/lib/metadata.sh"
|
||||
set_post_datetime "2026-05-20 14:30" "fallback"
|
||||
assert_eq "2026-05-20" "$post_date" "post date from date field"
|
||||
assert_eq "14:30" "$post_time" "post time from date field"
|
||||
}
|
||||
|
||||
test_set_post_datetime_from_filename() {
|
||||
. "$project_dir/lib/metadata.sh"
|
||||
set_post_datetime "" "2026-05-20-14-30-slug"
|
||||
assert_eq "2026-05-20" "$post_date" "post date from filename"
|
||||
assert_eq "14:30" "$post_time" "post time from filename"
|
||||
}
|
||||
93
tests/test_runner.sh
Executable file
93
tests/test_runner.sh
Executable file
@@ -0,0 +1,93 @@
|
||||
#!/bin/sh
|
||||
|
||||
script_dir=$(CDPATH="" cd -- "$(dirname -- "$0")" && pwd)
|
||||
project_dir=$(CDPATH="" cd -- "$script_dir/.." && pwd)
|
||||
|
||||
passed=0
|
||||
failed=0
|
||||
total=0
|
||||
|
||||
assert_eq() {
|
||||
total=$((total + 1))
|
||||
expected="$1"
|
||||
actual="$2"
|
||||
label="$3"
|
||||
|
||||
if [ "$expected" = "$actual" ]; then
|
||||
passed=$((passed + 1))
|
||||
printf " PASS: %s\n" "$label"
|
||||
else
|
||||
failed=$((failed + 1))
|
||||
printf " FAIL: %s\n" "$label"
|
||||
printf " expected: %s\n" "$expected"
|
||||
printf " actual: %s\n" "$actual"
|
||||
fi
|
||||
}
|
||||
|
||||
assert_contains() {
|
||||
total=$((total + 1))
|
||||
needle="$1"
|
||||
haystack="$2"
|
||||
label="$3"
|
||||
|
||||
case "$haystack" in
|
||||
*"$needle"*)
|
||||
passed=$((passed + 1))
|
||||
printf " PASS: %s\n" "$label"
|
||||
;;
|
||||
*)
|
||||
failed=$((failed + 1))
|
||||
printf " FAIL: %s\n" "$label"
|
||||
printf " expected to contain: %s\n" "$needle"
|
||||
printf " actual: %s\n" "$haystack"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
assert_file_exists() {
|
||||
total=$((total + 1))
|
||||
path="$1"
|
||||
label="$2"
|
||||
|
||||
if [ -f "$path" ]; then
|
||||
passed=$((passed + 1))
|
||||
printf " PASS: %s\n" "$label"
|
||||
else
|
||||
failed=$((failed + 1))
|
||||
printf " FAIL: %s\n" "$label"
|
||||
printf " file not found: %s\n" "$path"
|
||||
fi
|
||||
}
|
||||
|
||||
run_test_file() {
|
||||
test_file="$1"
|
||||
test_name=$(basename "$test_file" .sh)
|
||||
printf "\n== %s ==\n" "$test_name"
|
||||
|
||||
saved_total=$total
|
||||
saved_passed=$passed
|
||||
saved_failed=$failed
|
||||
|
||||
. "$test_file"
|
||||
|
||||
for func in $(grep '^test_' "$test_file" | sed 's/().*//' | sort -u); do
|
||||
$func
|
||||
done
|
||||
|
||||
file_total=$((total - saved_total))
|
||||
file_passed=$((passed - saved_passed))
|
||||
file_failed=$((failed - saved_failed))
|
||||
if [ "$file_total" -eq 0 ]; then
|
||||
printf " (no tests found)\n"
|
||||
fi
|
||||
}
|
||||
|
||||
for test_file in "$script_dir"/test_*.sh; do
|
||||
[ "$(basename "$test_file")" = "test_runner.sh" ] && continue
|
||||
run_test_file "$test_file"
|
||||
done
|
||||
|
||||
printf "\n== Results ==\n"
|
||||
printf " %d passed, %d failed, %d total\n" "$passed" "$failed" "$total"
|
||||
|
||||
[ "$failed" -eq 0 ] && exit 0 || exit 1
|
||||
71
tests/test_runtime.sh
Executable file
71
tests/test_runtime.sh
Executable file
@@ -0,0 +1,71 @@
|
||||
test_url_encode_spaces() {
|
||||
. "$project_dir/lib/runtime.sh"
|
||||
result=$(encode_url_path "hello world")
|
||||
assert_eq "hello%20world" "$result" "encode spaces"
|
||||
}
|
||||
|
||||
test_url_encode_hash() {
|
||||
. "$project_dir/lib/runtime.sh"
|
||||
result=$(encode_url_path "file#section")
|
||||
assert_eq "file%23section" "$result" "encode hash"
|
||||
}
|
||||
|
||||
test_url_encode_question() {
|
||||
. "$project_dir/lib/runtime.sh"
|
||||
result=$(encode_url_path "search?q=test")
|
||||
assert_eq "search%3Fq=test" "$result" "encode question mark"
|
||||
}
|
||||
|
||||
test_url_encode_percent() {
|
||||
. "$project_dir/lib/runtime.sh"
|
||||
result=$(encode_url_path "100%")
|
||||
assert_eq "100%25" "$result" "encode percent"
|
||||
}
|
||||
|
||||
test_markdown_file_url() {
|
||||
. "$project_dir/lib/runtime.sh"
|
||||
result=$(markdown_file_url "docs/readme.md")
|
||||
assert_eq "/docs/readme.html" "$result" "markdown file url"
|
||||
}
|
||||
|
||||
test_directory_index_url_root() {
|
||||
. "$project_dir/lib/runtime.sh"
|
||||
result=$(directory_index_url "")
|
||||
assert_eq "/index.html" "$result" "root index url"
|
||||
}
|
||||
|
||||
test_directory_index_url_subdir() {
|
||||
. "$project_dir/lib/runtime.sh"
|
||||
result=$(directory_index_url "docs")
|
||||
assert_eq "/docs/index.html" "$result" "subdir index url"
|
||||
}
|
||||
|
||||
test_directory_index_url_dot() {
|
||||
. "$project_dir/lib/runtime.sh"
|
||||
result=$(directory_index_url ".")
|
||||
assert_eq "/index.html" "$result" "dot index url"
|
||||
}
|
||||
|
||||
test_format_rfc2822_utc() {
|
||||
. "$project_dir/lib/runtime.sh"
|
||||
result=$(format_rfc2822_utc "2026-05-20" "14:30")
|
||||
assert_eq "Wed, 20 May 2026 14:30:00 +0000" "$result" "rfc2822 format"
|
||||
}
|
||||
|
||||
test_format_rfc2822_utc_default_time() {
|
||||
. "$project_dir/lib/runtime.sh"
|
||||
result=$(format_rfc2822_utc "2026-01-01")
|
||||
assert_eq "Thu, 01 Jan 2026 00:00:00 +0000" "$result" "rfc2822 default time"
|
||||
}
|
||||
|
||||
test_trim_whitespace() {
|
||||
. "$project_dir/lib/runtime.sh"
|
||||
result=$(trim_whitespace " hello ")
|
||||
assert_eq "hello" "$result" "trim whitespace"
|
||||
}
|
||||
|
||||
test_trim_whitespace_tabs() {
|
||||
. "$project_dir/lib/runtime.sh"
|
||||
result=$(trim_whitespace " world ")
|
||||
assert_eq "world" "$result" "trim tabs"
|
||||
}
|
||||
Reference in New Issue
Block a user