Files
Shuery 0df07ad0ae refactor: 迁移至 bashly CLI 与功能域模块结构
- CLI 定义迁移至 src/bashly.yml(bashly 1.4 生成参数解析),入口收敛为 src/root_command.sh
- 源码按功能域重组:config/storage/integrate/media/pipeline,消除扁平散落
- 新增零依赖测试框架 tests/(123 用例)与 CI 流水线(lint + test + build + 产物一致性)
- build.sh 支持版本单一来源注入与 --check 产物校验;新增 lint.sh(bash -n + shellcheck 零容忍)
- 删除旧单文件 media_organizer.sh 与旧扁平模块
2026-08-14 22:41:28 +08:00

91 lines
3.6 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ============================================================================
# 字符串工具模块测试(src/lib/strings.sh)
# ============================================================================
# 每个测试前重置依赖的全局状态
setup() {
COLOR_OUTPUT=false
TMDB_LANG="zh-CN"
SPECIAL_MAP=()
}
# sanitize:删除非法字符
test_sanitize_removes_illegal_chars() {
assert_eq "abcdefghij" "$(sanitize 'a/b\c:d*e?f"g<h>i|j')" "sanitize 应删除 \\ / : * ? \" < > |"
}
# sanitize:保留中文与空格
test_sanitize_keeps_cjk_and_spaces() {
assert_eq "某科学的超电磁炮T" "$(sanitize '某科学的超电磁炮T')"
assert_eq "刀剑神域 爱丽丝篇" "$(sanitize '刀剑神域 爱丽丝篇')"
}
# sanitize:空输入
test_sanitize_empty_input() {
assert_eq "" "$(sanitize "")"
assert_eq "" "$(sanitize "///")"
}
# clean_name:去方括号标记与首尾空白
test_clean_name_strips_brackets_and_spaces() {
assert_eq "Show Title" "$(clean_name '[VCB-Studio] Show Title [1080p]')"
assert_eq "Title" "$(clean_name ' [A] Title [B] ')"
}
# strip_season_suffix:多种季后缀
test_strip_season_suffix_variants() {
assert_eq "Show" "$(strip_season_suffix 'Show S01')"
assert_eq "Show" "$(strip_season_suffix 'Show 2nd Season')"
assert_eq "Show" "$(strip_season_suffix 'Show S12')"
# 行为契约:仅剥离 Season 前带数字的形式;"Show Season 2" 由 parse_media_filename 处理
assert_eq "Show Season 2" "$(strip_season_suffix 'Show Season 2')"
assert_eq "无需处理" "$(strip_season_suffix '无需处理')"
}
# norm_str:全角转半角 + 去空格/连字符 + 小写
test_norm_str_fullwidth_to_halfwidth() {
assert_eq "aliceization" "$(norm_str 'Aliceization')"
assert_eq "swordartonline" "$(norm_str 'Sword Art Online')"
assert_eq "iiiiiivv" "$(norm_str 'ⅡⅢⅣⅤ')"
assert_eq "menu01" "$(norm_str 'Menu 01')"
}
# safe_printf_int:补零与非数字默认值
test_safe_printf_int_padding() {
assert_eq "01" "$(safe_printf_int 1)"
assert_eq "23" "$(safe_printf_int 23)"
assert_eq "00" "$(safe_printf_int "")"
assert_eq "99" "$(safe_printf_int "abc" "99")"
assert_eq "07" "$(safe_printf_int "007")"
}
# normalize_abs:相对/绝对路径归一化
test_normalize_abs_paths() {
local d
d="$(mktemp -d)"
assert_eq "$d" "$(normalize_abs "$d")" "绝对路径原样返回"
assert_eq "$d/sub" "$(normalize_abs "$d/sub")" "不存在的子目录也应归一化"
assert_eq "" "$(normalize_abs "")" "空串原样返回"
rm -rf "$d"
}
# is_companion:伴随文件判断
test_is_companion_detection() {
assert_success is_companion "/path/Show.S01E01.mkv.ass" "/path/Show.S01E01.mkv"
assert_success is_companion "/path/Show.S01E01.zh-CN.ass" "/path/Show.S01E01"
assert_success is_companion "/path/Show.S01E01.flac" "/path/Show.S01E01"
assert_failure is_companion "/path/Other.mkv" "/path/Show.S01E01"
# 行为契约:视频自身去扩展名后等于 vbase → 也判为伴随(link_companions 调用前先跳过自身)
assert_success is_companion "/path/Show.S01E01.mkv" "/path/Show.S01E01"
}
# translate_fragment:查表、核心词回退、归一化
test_translate_fragment_lookup() {
SPECIAL_MAP["menu"]='["Menu", "菜单"]'
SPECIAL_MAP["cm01"]='["CM", "广告"]'
assert_eq "Menu" "$(translate_fragment "Menu01")" "去数字后查核心词"
assert_eq "CM" "$(translate_fragment "CM01")" "精确键优先"
assert_eq "Menu" "$(translate_fragment "Menu01")" "全角归一化"
assert_eq "PV-01" "$(translate_fragment "PV-01")" "无映射时原样返回"
}