mirror of
https://github.com/samsonjs/samhuri.net.git
synced 2026-03-25 09:05:47 +00:00
Replace the Swift site generator with a Ruby and Phlex implementation. Loads site and projects from TOML, derive site metadata from posts. Migrate from make to bake and add standardrb and code coverage tasks. Update CI and docs to match the new workflow, and remove unused assets/dependencies plus obsolete tooling.
391 lines
13 KiB
Ruby
391 lines
13 KiB
Ruby
require "test_helper"
|
|
require "fileutils"
|
|
require "tmpdir"
|
|
|
|
class Pressa::Config::LoaderTest < Minitest::Test
|
|
def test_build_site_builds_a_site_from_site_toml_and_projects_toml
|
|
with_temp_config do |dir|
|
|
loader = Pressa::Config::Loader.new(source_path: dir)
|
|
site = loader.build_site
|
|
|
|
assert_equal("Sami Samhuri", site.author)
|
|
assert_equal("https://samhuri.net", site.url)
|
|
assert_equal("https://samhuri.net/images/me.jpg", site.image_url)
|
|
assert_equal(["/css/style.css"], site.styles.map(&:href))
|
|
|
|
projects_plugin = site.plugins.find { |plugin| plugin.is_a?(Pressa::Projects::Plugin) }
|
|
refute_nil(projects_plugin)
|
|
assert_equal(["/js/projects.js"], projects_plugin.scripts.map(&:src))
|
|
end
|
|
end
|
|
|
|
def test_build_site_applies_url_override_and_rewrites_relative_image_url_with_override_host
|
|
with_temp_config do |dir|
|
|
loader = Pressa::Config::Loader.new(source_path: dir)
|
|
site = loader.build_site(url_override: "https://beta.samhuri.net")
|
|
|
|
assert_equal("https://beta.samhuri.net", site.url)
|
|
assert_equal("https://beta.samhuri.net/images/me.jpg", site.image_url)
|
|
end
|
|
end
|
|
|
|
def test_build_site_raises_a_validation_error_for_missing_required_site_keys
|
|
Dir.mktmpdir do |dir|
|
|
File.write(File.join(dir, "site.toml"), "title = \"x\"\n")
|
|
File.write(File.join(dir, "projects.toml"), "")
|
|
|
|
loader = Pressa::Config::Loader.new(source_path: dir)
|
|
error = assert_raises(Pressa::Config::ValidationError) { loader.build_site }
|
|
assert_match(/Missing required site\.toml keys/, error.message)
|
|
end
|
|
end
|
|
|
|
def test_build_site_defaults_to_no_plugins_when_plugins_key_is_missing
|
|
Dir.mktmpdir do |dir|
|
|
File.write(File.join(dir, "site.toml"), <<~TOML)
|
|
author = "Sami Samhuri"
|
|
email = "sami@samhuri.net"
|
|
title = "samhuri.net"
|
|
description = "blog"
|
|
url = "https://samhuri.net"
|
|
TOML
|
|
|
|
loader = Pressa::Config::Loader.new(source_path: dir)
|
|
site = loader.build_site
|
|
assert_empty(site.plugins)
|
|
end
|
|
end
|
|
|
|
def test_build_site_raises_for_invalid_plugins_type
|
|
Dir.mktmpdir do |dir|
|
|
File.write(File.join(dir, "site.toml"), <<~TOML)
|
|
author = "Sami Samhuri"
|
|
email = "sami@samhuri.net"
|
|
title = "samhuri.net"
|
|
description = "blog"
|
|
url = "https://samhuri.net"
|
|
plugins = "posts"
|
|
TOML
|
|
|
|
loader = Pressa::Config::Loader.new(source_path: dir)
|
|
error = assert_raises(Pressa::Config::ValidationError) { loader.build_site }
|
|
assert_match(/Expected site\.toml plugins to be an array/, error.message)
|
|
end
|
|
end
|
|
|
|
def test_build_site_raises_for_unknown_plugin_name
|
|
Dir.mktmpdir do |dir|
|
|
File.write(File.join(dir, "site.toml"), <<~TOML)
|
|
author = "Sami Samhuri"
|
|
email = "sami@samhuri.net"
|
|
title = "samhuri.net"
|
|
description = "blog"
|
|
url = "https://samhuri.net"
|
|
plugins = ["wat"]
|
|
TOML
|
|
|
|
loader = Pressa::Config::Loader.new(source_path: dir)
|
|
error = assert_raises(Pressa::Config::ValidationError) { loader.build_site }
|
|
assert_match(/Unknown plugin 'wat'/, error.message)
|
|
end
|
|
end
|
|
|
|
def test_build_site_raises_for_empty_plugin_name
|
|
Dir.mktmpdir do |dir|
|
|
File.write(File.join(dir, "site.toml"), <<~TOML)
|
|
author = "Sami Samhuri"
|
|
email = "sami@samhuri.net"
|
|
title = "samhuri.net"
|
|
description = "blog"
|
|
url = "https://samhuri.net"
|
|
plugins = [""]
|
|
TOML
|
|
|
|
loader = Pressa::Config::Loader.new(source_path: dir)
|
|
error = assert_raises(Pressa::Config::ValidationError) { loader.build_site }
|
|
assert_match(/Expected site\.toml plugins\[0\] to be a non-empty String/, error.message)
|
|
end
|
|
end
|
|
|
|
def test_build_site_raises_for_duplicate_plugins
|
|
Dir.mktmpdir do |dir|
|
|
File.write(File.join(dir, "site.toml"), <<~TOML)
|
|
author = "Sami Samhuri"
|
|
email = "sami@samhuri.net"
|
|
title = "samhuri.net"
|
|
description = "blog"
|
|
url = "https://samhuri.net"
|
|
plugins = ["posts", "posts"]
|
|
TOML
|
|
|
|
loader = Pressa::Config::Loader.new(source_path: dir)
|
|
error = assert_raises(Pressa::Config::ValidationError) { loader.build_site }
|
|
assert_match(/Duplicate plugin 'posts' in site\.toml plugins/, error.message)
|
|
end
|
|
end
|
|
|
|
def test_build_site_raises_for_missing_projects_array
|
|
Dir.mktmpdir do |dir|
|
|
File.write(File.join(dir, "site.toml"), <<~TOML)
|
|
author = "Sami Samhuri"
|
|
email = "sami@samhuri.net"
|
|
title = "samhuri.net"
|
|
description = "blog"
|
|
url = "https://samhuri.net"
|
|
plugins = ["projects"]
|
|
TOML
|
|
File.write(File.join(dir, "projects.toml"), "title = \"no projects\"\n")
|
|
|
|
loader = Pressa::Config::Loader.new(source_path: dir)
|
|
error = assert_raises(Pressa::Config::ValidationError) { loader.build_site }
|
|
assert_match(/Missing required top-level array 'projects'/, error.message)
|
|
end
|
|
end
|
|
|
|
def test_build_site_raises_for_invalid_project_entries
|
|
Dir.mktmpdir do |dir|
|
|
File.write(File.join(dir, "site.toml"), <<~TOML)
|
|
author = "Sami Samhuri"
|
|
email = "sami@samhuri.net"
|
|
title = "samhuri.net"
|
|
description = "blog"
|
|
url = "https://samhuri.net"
|
|
plugins = ["projects"]
|
|
TOML
|
|
File.write(File.join(dir, "projects.toml"), <<~TOML)
|
|
projects = [1]
|
|
TOML
|
|
|
|
loader = Pressa::Config::Loader.new(source_path: dir)
|
|
error = assert_raises(Pressa::Config::ValidationError) { loader.build_site }
|
|
assert_match(/Project entry 1 must be a table/, error.message)
|
|
end
|
|
end
|
|
|
|
def test_build_site_raises_for_invalid_projects_plugin_type
|
|
Dir.mktmpdir do |dir|
|
|
File.write(File.join(dir, "site.toml"), <<~TOML)
|
|
author = "Sami Samhuri"
|
|
email = "sami@samhuri.net"
|
|
title = "samhuri.net"
|
|
description = "blog"
|
|
url = "https://samhuri.net"
|
|
plugins = ["projects"]
|
|
projects_plugin = []
|
|
TOML
|
|
File.write(File.join(dir, "projects.toml"), <<~TOML)
|
|
[[projects]]
|
|
name = "demo"
|
|
title = "demo"
|
|
description = "demo project"
|
|
url = "https://github.com/samsonjs/demo"
|
|
TOML
|
|
|
|
loader = Pressa::Config::Loader.new(source_path: dir)
|
|
error = assert_raises(Pressa::Config::ValidationError) { loader.build_site }
|
|
assert_match(/Expected site\.toml projects_plugin to be a table/, error.message)
|
|
end
|
|
end
|
|
|
|
def test_build_site_raises_for_invalid_script_and_style_entries
|
|
Dir.mktmpdir do |dir|
|
|
File.write(File.join(dir, "site.toml"), <<~TOML)
|
|
author = "Sami Samhuri"
|
|
email = "sami@samhuri.net"
|
|
title = "samhuri.net"
|
|
description = "blog"
|
|
url = "https://samhuri.net"
|
|
scripts = [{}]
|
|
styles = [123]
|
|
TOML
|
|
File.write(File.join(dir, "projects.toml"), <<~TOML)
|
|
[[projects]]
|
|
name = "demo"
|
|
title = "demo"
|
|
description = "demo project"
|
|
url = "https://github.com/samsonjs/demo"
|
|
TOML
|
|
|
|
loader = Pressa::Config::Loader.new(source_path: dir)
|
|
script_error = assert_raises(Pressa::Config::ValidationError) { loader.build_site }
|
|
assert_match(/Expected site\.toml scripts\[0\]\.src to be a String/, script_error.message)
|
|
|
|
File.write(File.join(dir, "site.toml"), <<~TOML)
|
|
author = "Sami Samhuri"
|
|
email = "sami@samhuri.net"
|
|
title = "samhuri.net"
|
|
description = "blog"
|
|
url = "https://samhuri.net"
|
|
scripts = []
|
|
styles = [123]
|
|
TOML
|
|
style_error = assert_raises(Pressa::Config::ValidationError) { loader.build_site }
|
|
assert_match(/Expected site\.toml styles\[0\] to be a String or table/, style_error.message)
|
|
end
|
|
end
|
|
|
|
def test_build_site_accepts_script_hashes_and_absolute_image_url
|
|
Dir.mktmpdir do |dir|
|
|
File.write(File.join(dir, "site.toml"), <<~TOML)
|
|
author = "Sami Samhuri"
|
|
email = "sami@samhuri.net"
|
|
title = "samhuri.net"
|
|
description = "blog"
|
|
url = "https://samhuri.net"
|
|
image_url = "https://images.example.net/me.jpg"
|
|
scripts = [{"src": "/js/site.js", "defer": false}]
|
|
styles = [{"href": "/css/site.css"}]
|
|
plugins = ["posts", "projects"]
|
|
|
|
[projects_plugin]
|
|
scripts = [{"src": "/js/projects.js", "defer": true}]
|
|
styles = [{"href": "/css/projects.css"}]
|
|
TOML
|
|
File.write(File.join(dir, "projects.toml"), <<~TOML)
|
|
[[projects]]
|
|
name = "demo"
|
|
title = "demo"
|
|
description = "demo project"
|
|
url = "https://github.com/samsonjs/demo"
|
|
TOML
|
|
|
|
loader = Pressa::Config::Loader.new(source_path: dir)
|
|
site = loader.build_site
|
|
|
|
assert_equal("https://images.example.net/me.jpg", site.image_url)
|
|
assert_equal(["/js/site.js"], site.scripts.map(&:src))
|
|
assert_equal([false], site.scripts.map(&:defer))
|
|
assert_equal(["/css/site.css"], site.styles.map(&:href))
|
|
end
|
|
end
|
|
|
|
def test_build_site_rewraps_toml_parse_errors_as_validation_errors
|
|
Dir.mktmpdir do |dir|
|
|
File.write(File.join(dir, "site.toml"), "author = \"unterminated\n")
|
|
File.write(File.join(dir, "projects.toml"), <<~TOML)
|
|
[[projects]]
|
|
name = "demo"
|
|
title = "demo"
|
|
description = "demo project"
|
|
url = "https://github.com/samsonjs/demo"
|
|
TOML
|
|
|
|
loader = Pressa::Config::Loader.new(source_path: dir)
|
|
error = assert_raises(Pressa::Config::ValidationError) { loader.build_site }
|
|
assert_match(/Unterminated value for key 'author'/, error.message)
|
|
end
|
|
end
|
|
|
|
def test_build_site_rejects_non_boolean_defer_values
|
|
Dir.mktmpdir do |dir|
|
|
File.write(File.join(dir, "site.toml"), <<~TOML)
|
|
author = "Sami Samhuri"
|
|
email = "sami@samhuri.net"
|
|
title = "samhuri.net"
|
|
description = "blog"
|
|
url = "https://samhuri.net"
|
|
scripts = [{"src": "/js/site.js", "defer": "yes"}]
|
|
TOML
|
|
File.write(File.join(dir, "projects.toml"), <<~TOML)
|
|
[[projects]]
|
|
name = "demo"
|
|
title = "demo"
|
|
description = "demo project"
|
|
url = "https://github.com/samsonjs/demo"
|
|
TOML
|
|
|
|
loader = Pressa::Config::Loader.new(source_path: dir)
|
|
error = assert_raises(Pressa::Config::ValidationError) { loader.build_site }
|
|
assert_match(/Expected site\.toml scripts\[0\]\.defer to be a Boolean/, error.message)
|
|
end
|
|
end
|
|
|
|
def test_build_site_rejects_non_string_or_table_scripts_and_non_array_script_lists
|
|
Dir.mktmpdir do |dir|
|
|
File.write(File.join(dir, "site.toml"), <<~TOML)
|
|
author = "Sami Samhuri"
|
|
email = "sami@samhuri.net"
|
|
title = "samhuri.net"
|
|
description = "blog"
|
|
url = "https://samhuri.net"
|
|
scripts = [123]
|
|
TOML
|
|
File.write(File.join(dir, "projects.toml"), <<~TOML)
|
|
[[projects]]
|
|
name = "demo"
|
|
title = "demo"
|
|
description = "demo project"
|
|
url = "https://github.com/samsonjs/demo"
|
|
TOML
|
|
|
|
loader = Pressa::Config::Loader.new(source_path: dir)
|
|
invalid_item = assert_raises(Pressa::Config::ValidationError) { loader.build_site }
|
|
assert_match(/Expected site\.toml scripts\[0\] to be a String or table/, invalid_item.message)
|
|
|
|
File.write(File.join(dir, "site.toml"), <<~TOML)
|
|
author = "Sami Samhuri"
|
|
email = "sami@samhuri.net"
|
|
title = "samhuri.net"
|
|
description = "blog"
|
|
url = "https://samhuri.net"
|
|
plugins = ["projects"]
|
|
|
|
[projects_plugin]
|
|
scripts = "js/projects.js"
|
|
TOML
|
|
non_array = assert_raises(Pressa::Config::ValidationError) { loader.build_site }
|
|
assert_match(/Expected site\.toml projects_plugin\.scripts to be an array/, non_array.message)
|
|
end
|
|
end
|
|
|
|
def test_build_site_rejects_non_absolute_local_asset_paths
|
|
Dir.mktmpdir do |dir|
|
|
File.write(File.join(dir, "site.toml"), <<~TOML)
|
|
author = "Sami Samhuri"
|
|
email = "sami@samhuri.net"
|
|
title = "samhuri.net"
|
|
description = "blog"
|
|
url = "https://samhuri.net"
|
|
scripts = ["js/site.js"]
|
|
styles = ["css/site.css"]
|
|
TOML
|
|
File.write(File.join(dir, "projects.toml"), "")
|
|
|
|
loader = Pressa::Config::Loader.new(source_path: dir)
|
|
error = assert_raises(Pressa::Config::ValidationError) { loader.build_site }
|
|
assert_match(%r{start with / or use http\(s\) scheme}, error.message)
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def with_temp_config
|
|
Dir.mktmpdir do |dir|
|
|
File.write(File.join(dir, "site.toml"), <<~TOML)
|
|
author = "Sami Samhuri"
|
|
email = "sami@samhuri.net"
|
|
title = "samhuri.net"
|
|
description = "blog"
|
|
url = "https://samhuri.net"
|
|
image_url = "/images/me.jpg"
|
|
scripts = []
|
|
styles = ["/css/style.css"]
|
|
plugins = ["posts", "projects"]
|
|
|
|
[projects_plugin]
|
|
scripts = ["/js/projects.js"]
|
|
styles = []
|
|
TOML
|
|
|
|
File.write(File.join(dir, "projects.toml"), <<~TOML)
|
|
[[projects]]
|
|
name = "demo"
|
|
title = "demo"
|
|
description = "demo project"
|
|
url = "https://github.com/samsonjs/demo"
|
|
TOML
|
|
|
|
yield dir
|
|
end
|
|
end
|
|
end
|