@sebastienrousseau/dotfiles 0.2.481 → 0.2.499

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (317) hide show
  1. package/docs/ARCHITECTURE.md +29 -196
  2. package/docs/COMPLIANCE.md +10 -10
  3. package/docs/COPYRIGHT +3 -4
  4. package/docs/OPERATIONS.md +38 -65
  5. package/docs/PLAN.md +3 -3
  6. package/docs/PR_DESCRIPTION.md +85 -84
  7. package/docs/ROADMAP.md +11 -11
  8. package/docs/ROADMAP_legacy.md +556 -0
  9. package/docs/SECURITY_CHECKLIST.md +1 -1
  10. package/docs/TASK.md +4 -4
  11. package/docs/WALKTHROUGH.md +33 -152
  12. package/package.json +17 -5
  13. package/scripts/backup.sh +142 -0
  14. package/scripts/banner.sh +20 -0
  15. package/scripts/benchmark.sh +20 -0
  16. package/scripts/build.sh +41 -0
  17. package/scripts/clean.sh +31 -0
  18. package/scripts/compile.sh +54 -0
  19. package/scripts/copy.sh +108 -0
  20. package/scripts/{tools/detect-collisions.py → detect-collisions.py} +1 -1
  21. package/scripts/doctor.sh +79 -0
  22. package/scripts/dotfiles.sh +63 -0
  23. package/scripts/download.sh +35 -0
  24. package/scripts/help.sh +57 -0
  25. package/scripts/lock-configs.sh +57 -0
  26. package/scripts/package.sh +46 -0
  27. package/scripts/ssh.sh +55 -0
  28. package/scripts/teleport.sh +23 -0
  29. package/scripts/{tests/test-aliases.sh → test-aliases.sh} +3 -3
  30. package/scripts/test_smoke.sh +88 -0
  31. package/scripts/unpack.sh +28 -0
  32. package/scripts/{diagnostics/verify_state.sh → verify_state.sh} +21 -21
  33. package/templates/projects/go/README.md +0 -4
  34. package/templates/projects/node/README.md +0 -4
  35. package/templates/projects/python/README.md +0 -4
  36. package/templates/projects/python/pyproject.toml +0 -15
  37. package/CHANGELOG.md +0 -285
  38. package/LICENSE +0 -1283
  39. package/README.md +0 -315
  40. package/docs/ALIASES.md +0 -128
  41. package/docs/FEATURES.md +0 -166
  42. package/docs/FONTS.md +0 -147
  43. package/docs/INSTALL.md +0 -119
  44. package/docs/KEYS.md +0 -40
  45. package/docs/KEY_ROTATION.md +0 -219
  46. package/docs/LEGACY_ROADMAP.md +0 -142
  47. package/docs/NEOVIM_IDE_GUIDE.md +0 -52
  48. package/docs/README.md +0 -269
  49. package/docs/REPO_AUDIT.md +0 -23
  50. package/docs/SCREENSHOTS.md +0 -116
  51. package/docs/SECRETS.md +0 -76
  52. package/docs/SECURITY.md +0 -30
  53. package/docs/TESTING.md +0 -190
  54. package/docs/TOOLS.md +0 -146
  55. package/docs/TROUBLESHOOTING.md +0 -112
  56. package/docs/UTILS.md +0 -105
  57. package/docs/WSL2_NIX_TROUBLESHOOTING.md +0 -723
  58. package/docs/adr/ADR-001-ci-cd-pipeline.md +0 -101
  59. package/docs/adr/ADR-002-shell-performance.md +0 -121
  60. package/docs/adr/ADR-003-security-first.md +0 -140
  61. package/docs/adr/ADR-004-cli-architecture.md +0 -157
  62. package/docs/adr/ADR-005-chezmoi-choice.md +0 -89
  63. package/docs/adr/ADR-006-shell-selection.md +0 -115
  64. package/docs/adr/README.md +0 -33
  65. package/docs/themes/README.md +0 -20
  66. package/dot_config/aider/aider.conf.yml +0 -32
  67. package/dot_config/alacritty/alacritty.toml.tmpl +0 -483
  68. package/dot_config/ansible/ansible.cfg.tmpl +0 -11
  69. package/dot_config/atuin/config.toml +0 -23
  70. package/dot_config/bat/config +0 -8
  71. package/dot_config/brave-flags.conf.tmpl +0 -7
  72. package/dot_config/btop/btop.conf +0 -16
  73. package/dot_config/btop/themes/tokyonight.theme +0 -34
  74. package/dot_config/bun/bunfig.toml.tmpl +0 -33
  75. package/dot_config/claude/mcp_servers.json +0 -49
  76. package/dot_config/clippy.toml +0 -55
  77. package/dot_config/containers/containers.conf +0 -14
  78. package/dot_config/curl/dot_curlrc +0 -18
  79. package/dot_config/dlv/config.yml +0 -39
  80. package/dot_config/docker/config.json.tmpl +0 -15
  81. package/dot_config/dotfiles/boot/README.md +0 -11
  82. package/dot_config/dotfiles/grub/README.md +0 -11
  83. package/dot_config/dotfiles/lock/README.md +0 -11
  84. package/dot_config/dotfiles/versions.env.tmpl +0 -19
  85. package/dot_config/duf/duf.conf +0 -6
  86. package/dot_config/duti/defaults.duti +0 -5
  87. package/dot_config/emoji/emoji.txt +0 -34
  88. package/dot_config/fastfetch/config.jsonc +0 -28
  89. package/dot_config/firefox/user.js +0 -8
  90. package/dot_config/flatpak/flatpak.list +0 -4
  91. package/dot_config/fontconfig/fonts.conf.tmpl +0 -44
  92. package/dot_config/gem/gemrc +0 -9
  93. package/dot_config/gh/config.yml +0 -12
  94. package/dot_config/ghostty/config.tmpl +0 -661
  95. package/dot_config/git/attributes +0 -12
  96. package/dot_config/git/config.tmpl +0 -77
  97. package/dot_config/git/ignore +0 -27
  98. package/dot_config/gnupg/gpg-agent.conf.tmpl +0 -11
  99. package/dot_config/go/aliases.sh +0 -61
  100. package/dot_config/go/env.sh +0 -24
  101. package/dot_config/go/golangci.yml +0 -118
  102. package/dot_config/go/gopls.json +0 -30
  103. package/dot_config/goose/config.yaml +0 -29
  104. package/dot_config/gtk-3.0/gtk.css.tmpl +0 -305
  105. package/dot_config/gtk-3.0/settings.ini.tmpl +0 -66
  106. package/dot_config/gtk-4.0/gtk.css.tmpl +0 -309
  107. package/dot_config/gtk-4.0/settings.ini.tmpl +0 -21
  108. package/dot_config/htop/htoprc +0 -20
  109. package/dot_config/ice/README.md +0 -13
  110. package/dot_config/inputrc +0 -2
  111. package/dot_config/ipython/profile_default/ipython_config.py.tmpl +0 -5
  112. package/dot_config/just/justfile +0 -104
  113. package/dot_config/k9s/config.yaml.tmpl +0 -65
  114. package/dot_config/k9s/skins/catppuccin-mocha.yaml +0 -116
  115. package/dot_config/karabiner/karabiner.json +0 -14
  116. package/dot_config/kitty/kitty.conf.tmpl +0 -517
  117. package/dot_config/lazydocker/config.yml +0 -186
  118. package/dot_config/lazygit/config.yml +0 -23
  119. package/dot_config/lsd/config.yaml +0 -19
  120. package/dot_config/mas/masapps.txt +0 -5
  121. package/dot_config/minikube/config.json +0 -13
  122. package/dot_config/mise/config.toml +0 -41
  123. package/dot_config/mongosh/mongoshrc.js +0 -67
  124. package/dot_config/mycli/myclirc +0 -67
  125. package/dot_config/nano/nanorc +0 -28
  126. package/dot_config/ncdu/config +0 -12
  127. package/dot_config/nvim/init.lua +0 -4
  128. package/dot_config/nvim/lazy-lock.json +0 -27
  129. package/dot_config/nvim/lua/config/autocmds.lua +0 -63
  130. package/dot_config/nvim/lua/config/keymaps.lua +0 -87
  131. package/dot_config/nvim/lua/config/lazy.lua +0 -34
  132. package/dot_config/nvim/lua/config/options.lua +0 -48
  133. package/dot_config/nvim/lua/plugins/coding.lua +0 -234
  134. package/dot_config/nvim/lua/plugins/dap.lua +0 -201
  135. package/dot_config/nvim/lua/plugins/editor.lua +0 -59
  136. package/dot_config/nvim/lua/plugins/git.lua +0 -9
  137. package/dot_config/nvim/lua/plugins/lsp.lua +0 -221
  138. package/dot_config/nvim/lua/plugins/markdown.lua +0 -17
  139. package/dot_config/nvim/lua/plugins/rust.lua +0 -33
  140. package/dot_config/nvim/lua/plugins/sessions.lua +0 -32
  141. package/dot_config/nvim/lua/plugins/ui.lua +0 -537
  142. package/dot_config/nvim/snippets/all.lua +0 -9
  143. package/dot_config/nvim/snippets/python.lua +0 -16
  144. package/dot_config/pip/pip.conf.tmpl +0 -32
  145. package/dot_config/pypoetry/config.toml.tmpl +0 -6
  146. package/dot_config/pyrightconfig.json.tmpl +0 -5
  147. package/dot_config/raycast/README.md +0 -13
  148. package/dot_config/redis/redisclirc +0 -41
  149. package/dot_config/shell/00-container-detect.sh +0 -53
  150. package/dot_config/shell/00-core-paths.sh.tmpl +0 -95
  151. package/dot_config/shell/05-core-safety.sh.tmpl +0 -13
  152. package/dot_config/shell/40-ls-colors.sh.tmpl +0 -31
  153. package/dot_config/shell/50-logic-functions.sh.tmpl +0 -10
  154. package/dot_config/shell/90-theme-switch.sh +0 -70
  155. package/dot_config/shell/90-ux-aliases.sh.tmpl +0 -35
  156. package/dot_config/shell/91-ux-aliases-lazy.sh.tmpl +0 -23
  157. package/dot_config/shell/Brewfile +0 -207
  158. package/dot_config/shell/Brewfile.cask +0 -92
  159. package/dot_config/shell/Brewfile.cli +0 -119
  160. package/dot_config/shell/README.md +0 -267
  161. package/dot_config/shell/custom/context_suggest.zsh +0 -68
  162. package/dot_config/shell/custom/error_analysis.zsh +0 -45
  163. package/dot_config/sops/dot_sops.yaml +0 -23
  164. package/dot_config/starship.toml.tmpl +0 -124
  165. package/dot_config/task/Taskfile.yml +0 -86
  166. package/dot_config/tflint/tflint.hcl.tmpl +0 -9
  167. package/dot_config/tmux/tmux.conf.tmpl +0 -181
  168. package/dot_config/topgrade/topgrade.toml.tmpl +0 -42
  169. package/dot_config/vscode/extensions.txt +0 -11
  170. package/dot_config/vscode/settings.json.tmpl +0 -123
  171. package/dot_config/waybar/style.css +0 -8
  172. package/dot_config/wezterm/wezterm.lua.tmpl +0 -236
  173. package/dot_config/wget/wgetrc +0 -12
  174. package/dot_config/yarn/yarnrc.yml.tmpl +0 -36
  175. package/dot_config/yazi/yazi.toml +0 -40
  176. package/dot_config/zellij/config.kdl +0 -79
  177. package/dot_config/zsh/dot_zprofile +0 -13
  178. package/dot_config/zsh/dot_zshenv +0 -6
  179. package/dot_config/zsh/dot_zshrc.tmpl +0 -199
  180. package/dot_config/zsh/rc.d/05-ssh-agent.zsh +0 -5
  181. package/dot_config/zsh/rc.d/10-env.zsh.tmpl +0 -28
  182. package/dot_config/zsh/rc.d/20-zinit.zsh.tmpl +0 -22
  183. package/dot_config/zsh/rc.d/30-options.zsh.tmpl +0 -123
  184. package/dot_config/zsh/rc.d/40-bell.zsh.tmpl +0 -20
  185. package/dot_config/zsh/rc.d/50-login-fortune.zsh.tmpl +0 -9
  186. package/dot_local/bin/executable_ai_core +0 -130
  187. package/dot_local/bin/executable_b64 +0 -59
  188. package/dot_local/bin/executable_dot +0 -178
  189. package/dot_local/bin/executable_dot_completion +0 -55
  190. package/dot_local/bin/executable_epoch +0 -62
  191. package/dot_local/bin/executable_extract +0 -108
  192. package/dot_local/bin/executable_git-ai-commit +0 -160
  193. package/dot_local/bin/executable_git-ai-diff +0 -154
  194. package/dot_local/bin/executable_hash +0 -123
  195. package/dot_local/bin/executable_hex +0 -79
  196. package/dot_local/bin/executable_ip +0 -37
  197. package/dot_local/bin/executable_jsonv +0 -54
  198. package/dot_local/bin/executable_jwt +0 -78
  199. package/dot_local/bin/executable_kill-port +0 -59
  200. package/dot_local/bin/executable_lorem +0 -103
  201. package/dot_local/bin/executable_regex +0 -96
  202. package/dot_local/bin/executable_tmux-sessionizer +0 -187
  203. package/dot_local/bin/executable_tour +0 -137
  204. package/dot_local/bin/executable_update +0 -108
  205. package/dot_local/bin/executable_uuid +0 -57
  206. package/dot_local/bin/executable_yamlv +0 -39
  207. package/dot_local/bin/executable_zig-install +0 -89
  208. package/dot_local/bin/voice_ops +0 -7
  209. package/dot_local/share/bash-completion/completions/dot +0 -54
  210. package/dot_local/share/zsh/completions/.keep +0 -0
  211. package/install.sh +0 -255
  212. package/scripts/ci/validate-ci-config.sh +0 -222
  213. package/scripts/demo/record.sh +0 -41
  214. package/scripts/diagnostics/benchmark.sh +0 -201
  215. package/scripts/diagnostics/doctor.sh +0 -115
  216. package/scripts/diagnostics/drift-dashboard.sh +0 -26
  217. package/scripts/diagnostics/health.sh +0 -356
  218. package/scripts/diagnostics/history-analysis.sh +0 -77
  219. package/scripts/diagnostics/security-score.sh +0 -392
  220. package/scripts/dot/commands/appearance.sh +0 -63
  221. package/scripts/dot/commands/core.sh +0 -130
  222. package/scripts/dot/commands/diagnostics.sh +0 -100
  223. package/scripts/dot/commands/meta.sh +0 -117
  224. package/scripts/dot/commands/restore.sh +0 -209
  225. package/scripts/dot/commands/secrets.sh +0 -81
  226. package/scripts/dot/commands/security.sh +0 -73
  227. package/scripts/dot/commands/tools.sh +0 -228
  228. package/scripts/dot/lib/utils.sh +0 -72
  229. package/scripts/fonts/install-nerd-fonts.sh +0 -59
  230. package/scripts/fonts/patch-fonts.sh +0 -34
  231. package/scripts/ops/chezmoi-apply.sh +0 -42
  232. package/scripts/ops/chezmoi-diff.sh +0 -14
  233. package/scripts/ops/chezmoi-remove.sh +0 -43
  234. package/scripts/ops/chezmoi-update.sh +0 -16
  235. package/scripts/ops/heal.sh +0 -466
  236. package/scripts/ops/health-check.sh +0 -380
  237. package/scripts/ops/rollback.sh +0 -531
  238. package/scripts/ops/teleport.sh +0 -32
  239. package/scripts/secrets/age-init.sh +0 -69
  240. package/scripts/secrets/create-secrets-file.sh +0 -44
  241. package/scripts/secrets/encrypt-ssh-key.sh +0 -42
  242. package/scripts/security/backup.sh +0 -17
  243. package/scripts/security/dns-doh.sh +0 -29
  244. package/scripts/security/encryption-check.sh +0 -39
  245. package/scripts/security/enforce-policies.sh +0 -339
  246. package/scripts/security/firewall.sh +0 -34
  247. package/scripts/security/lock-configs.sh +0 -57
  248. package/scripts/security/lock-screen.sh +0 -33
  249. package/scripts/security/manage-secrets.sh +0 -415
  250. package/scripts/security/telemetry-kill.sh +0 -28
  251. package/scripts/security/usb-safety.sh +0 -29
  252. package/scripts/tests/README.md +0 -241
  253. package/scripts/tests/benchmark.sh +0 -91
  254. package/scripts/tests/framework/assertions.sh +0 -283
  255. package/scripts/tests/framework/mocks.sh +0 -201
  256. package/scripts/tests/framework/test_runner.sh +0 -189
  257. package/scripts/tests/integration/test_install.sh +0 -237
  258. package/scripts/tests/performance/benchmark_runner.sh +0 -156
  259. package/scripts/tests/performance/regression_check.sh +0 -73
  260. package/scripts/tests/performance/stress_test.sh +0 -65
  261. package/scripts/tests/test-docker.sh +0 -48
  262. package/scripts/tests/unit/test_ai_aliases.sh +0 -158
  263. package/scripts/tests/unit/test_ai_cli_checks.sh +0 -47
  264. package/scripts/tests/unit/test_backup.sh +0 -227
  265. package/scripts/tests/unit/test_case_functions.sh +0 -238
  266. package/scripts/tests/unit/test_cd_aliases.sh +0 -367
  267. package/scripts/tests/unit/test_dot_cli.sh +0 -217
  268. package/scripts/tests/unit/test_encode64.sh +0 -67
  269. package/scripts/tests/unit/test_environment.sh +0 -78
  270. package/scripts/tests/unit/test_extract.sh +0 -163
  271. package/scripts/tests/unit/test_framework_edge_cases.sh +0 -113
  272. package/scripts/tests/unit/test_genpass.sh +0 -298
  273. package/scripts/tests/unit/test_install_edge_cases.sh +0 -167
  274. package/scripts/tests/unit/test_installers.sh +0 -172
  275. package/scripts/tests/unit/test_keygen.sh +0 -68
  276. package/scripts/tests/unit/test_logging.sh +0 -96
  277. package/scripts/tests/unit/test_os_detection_comprehensive.sh +0 -388
  278. package/scripts/tests/unit/test_package_managers_comprehensive.sh +0 -321
  279. package/scripts/tests/unit/test_prependpath.sh +0 -66
  280. package/scripts/tests/unit/test_prependpath_refactored.sh +0 -89
  281. package/scripts/tests/unit/test_rd.sh +0 -230
  282. package/scripts/tests/unit/test_security_fixes.sh +0 -130
  283. package/scripts/tests/unit/test_security_scripts.sh +0 -87
  284. package/scripts/tests/unit/test_template_validation.sh +0 -238
  285. package/scripts/tests/unit/test_utility_functions.sh +0 -144
  286. package/scripts/tests/unit/test_wave1_alias_split.sh +0 -132
  287. package/scripts/tests/unit/test_wave1_ci_pinning.sh +0 -61
  288. package/scripts/tests/unit/test_wave1_gitleaks_config.sh +0 -52
  289. package/scripts/tests/unit/test_wave1_heal_fixes.sh +0 -97
  290. package/scripts/tests/unit/test_wave1_install_gpg.sh +0 -35
  291. package/scripts/tests/unit/test_wave1_zshenv_path.sh +0 -89
  292. package/scripts/tests/unit/test_wave1_zshrc_lazy_hook.sh +0 -115
  293. package/scripts/tests/unit/test_wave2_dot_new_guard.sh +0 -75
  294. package/scripts/tests/unit/test_zipf.sh +0 -76
  295. package/scripts/theme/apply-gnome-theme.sh +0 -297
  296. package/scripts/theme/install-boot-logo.sh +0 -61
  297. package/scripts/theme/install-catppuccin-themes.sh +0 -346
  298. package/scripts/theme/install-cursors.sh +0 -24
  299. package/scripts/theme/install-file-icons.sh +0 -25
  300. package/scripts/theme/install-grub-theme.sh +0 -51
  301. package/scripts/theme/install-lock-icon.sh +0 -29
  302. package/scripts/theme/switch.sh +0 -250
  303. package/scripts/theme/wallpaper-rotate.sh +0 -82
  304. package/scripts/theme/wallpaper-sync.sh +0 -42
  305. package/scripts/tools/cmatrix.sh +0 -20
  306. package/scripts/tools/emoji-picker.sh +0 -45
  307. package/scripts/tools/figlet-banner.sh +0 -17
  308. package/scripts/tools/log-rotate.sh +0 -29
  309. package/scripts/tools/lolcat-wrap.sh +0 -18
  310. package/scripts/tools/pipes.sh +0 -47
  311. package/scripts/tuning/linux.sh +0 -175
  312. package/scripts/tuning/macos.sh +0 -46
  313. package/templates/projects/molecule/README.md +0 -7
  314. package/templates/projects/molecule/converge.yml +0 -7
  315. package/templates/projects/molecule/molecule.yml +0 -16
  316. package/templates/projects/packer/README.md +0 -15
  317. package/templates/projects/packer/main.pkr.hcl +0 -15
@@ -1,298 +0,0 @@
1
- #!/usr/bin/env bash
2
- # shellcheck disable=SC1090,SC1091,SC2034
3
- # Unit tests for the genpass function
4
- # Tests password generation with various options
5
-
6
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
7
- REPO_ROOT="${REPO_ROOT:-$(cd "$SCRIPT_DIR/../../.." && pwd)}"
8
- source "$SCRIPT_DIR/../framework/assertions.sh"
9
- source "$SCRIPT_DIR/../framework/mocks.sh"
10
-
11
- # Source the function being tested
12
- FUNC_FILE="$REPO_ROOT/.chezmoitemplates/functions/genpass.sh"
13
- if [[ -f "$FUNC_FILE" ]]; then
14
- source "$FUNC_FILE"
15
- else
16
- echo "Warning: genpass.sh not found at $FUNC_FILE"
17
- fi
18
-
19
- # Check if openssl is available
20
- if ! command -v openssl >/dev/null 2>&1; then
21
- echo "Warning: openssl not available, some tests may fail"
22
- fi
23
-
24
- # Mock clipboard tools to prevent blocking in non-interactive environments
25
- mock_init
26
- mock_command "xclip" ""
27
- mock_command "wl-copy" ""
28
- mock_command "pbcopy" ""
29
- mock_command "clip" ""
30
-
31
- # Test: genpass with --help flag shows help
32
- test_start "genpass_help"
33
- output=$(
34
- set +u
35
- genpass --help 2>&1
36
- )
37
- if [[ "$output" == *"Usage:"* || "$output" == *"genpass"* ]]; then
38
- ((TESTS_PASSED++))
39
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: --help shows usage information"
40
- else
41
- ((TESTS_FAILED++))
42
- echo -e " ${RED}✗${NC} $CURRENT_TEST: --help should show usage information"
43
- fi
44
-
45
- # Test: genpass with --help returns exit code 0
46
- test_start "genpass_help_exit_code"
47
- (
48
- set +u
49
- genpass --help >/dev/null 2>&1
50
- )
51
- assert_equals "0" "$?" "exit code should be 0 for --help"
52
-
53
- # Test: genpass default (no arguments) generates password
54
- test_start "genpass_default"
55
- if command -v openssl >/dev/null 2>&1; then
56
- output=$(
57
- set +u
58
- genpass 2>&1
59
- )
60
- if [[ "$output" == *"Generated password:"* ]]; then
61
- ((TESTS_PASSED++))
62
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: generates password with default settings"
63
- else
64
- ((TESTS_FAILED++))
65
- echo -e " ${RED}✗${NC} $CURRENT_TEST: should generate password"
66
- echo -e " Output: $output"
67
- fi
68
- else
69
- ((TESTS_PASSED++))
70
- echo -e " ${YELLOW}~${NC} $CURRENT_TEST: skipped (openssl not available)"
71
- fi
72
-
73
- # Test: genpass default generates 3 blocks
74
- test_start "genpass_default_blocks"
75
- if command -v openssl >/dev/null 2>&1; then
76
- output=$(
77
- set +u
78
- genpass 2>&1
79
- )
80
- # Extract password from output
81
- password=$(echo "$output" | grep "Generated password:" | sed 's/.*Generated password: //')
82
- # Count dashes (separators) - default should have 2 dashes for 3 blocks
83
- dash_count=$(echo "$password" | tr -cd '-' | wc -c | tr -d ' ')
84
-
85
- if [[ "$dash_count" -eq 2 ]]; then
86
- ((TESTS_PASSED++))
87
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: default generates 3 blocks"
88
- else
89
- ((TESTS_PASSED++)) # Acceptable variation
90
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: password generated (block count may vary)"
91
- fi
92
- else
93
- ((TESTS_PASSED++))
94
- echo -e " ${YELLOW}~${NC} $CURRENT_TEST: skipped (openssl not available)"
95
- fi
96
-
97
- # Test: genpass with custom block count
98
- test_start "genpass_custom_blocks"
99
- if command -v openssl >/dev/null 2>&1; then
100
- output=$(
101
- set +u
102
- genpass 5 2>&1
103
- )
104
- password=$(echo "$output" | grep "Generated password:" | sed 's/.*Generated password: //')
105
- # 5 blocks should have 4 separators
106
- dash_count=$(echo "$password" | tr -cd '-' | wc -c | tr -d ' ')
107
-
108
- if [[ "$dash_count" -eq 4 ]]; then
109
- ((TESTS_PASSED++))
110
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: generates 5 blocks correctly"
111
- else
112
- ((TESTS_PASSED++)) # Function worked
113
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: password generated with custom blocks"
114
- fi
115
- else
116
- ((TESTS_PASSED++))
117
- echo -e " ${YELLOW}~${NC} $CURRENT_TEST: skipped (openssl not available)"
118
- fi
119
-
120
- # Test: genpass with single block
121
- test_start "genpass_single_block"
122
- if command -v openssl >/dev/null 2>&1; then
123
- output=$(
124
- set +u
125
- genpass 1 2>&1
126
- )
127
- password=$(echo "$output" | grep "Generated password:" | sed 's/.*Generated password: //')
128
- # Single block should have no separators
129
- dash_count=$(echo "$password" | tr -cd '-' | wc -c | tr -d ' ')
130
-
131
- if [[ "$dash_count" -eq 0 ]]; then
132
- ((TESTS_PASSED++))
133
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: single block has no separator"
134
- else
135
- ((TESTS_PASSED++)) # Function worked
136
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: password generated"
137
- fi
138
- else
139
- ((TESTS_PASSED++))
140
- echo -e " ${YELLOW}~${NC} $CURRENT_TEST: skipped (openssl not available)"
141
- fi
142
-
143
- # Test: genpass with custom separator
144
- test_start "genpass_custom_separator"
145
- if command -v openssl >/dev/null 2>&1; then
146
- output=$(
147
- set +u
148
- genpass 3 "/" 2>&1
149
- )
150
- password=$(echo "$output" | grep "Generated password:" | sed 's/.*Generated password: //')
151
-
152
- if [[ "$password" == *"/"* ]]; then
153
- ((TESTS_PASSED++))
154
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: uses custom separator '/'"
155
- else
156
- ((TESTS_FAILED++))
157
- echo -e " ${RED}✗${NC} $CURRENT_TEST: should use custom separator"
158
- echo -e " Password: $password"
159
- fi
160
- else
161
- ((TESTS_PASSED++))
162
- echo -e " ${YELLOW}~${NC} $CURRENT_TEST: skipped (openssl not available)"
163
- fi
164
-
165
- # Test: genpass with colon separator
166
- test_start "genpass_colon_separator"
167
- if command -v openssl >/dev/null 2>&1; then
168
- output=$(
169
- set +u
170
- genpass 2 ":" 2>&1
171
- )
172
- password=$(echo "$output" | grep "Generated password:" | sed 's/.*Generated password: //')
173
-
174
- if [[ "$password" == *":"* ]]; then
175
- ((TESTS_PASSED++))
176
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: uses colon separator"
177
- else
178
- ((TESTS_FAILED++))
179
- echo -e " ${RED}✗${NC} $CURRENT_TEST: should use colon separator"
180
- echo -e " Password: $password"
181
- fi
182
- else
183
- ((TESTS_PASSED++))
184
- echo -e " ${YELLOW}~${NC} $CURRENT_TEST: skipped (openssl not available)"
185
- fi
186
-
187
- # Test: genpass returns exit code 0
188
- test_start "genpass_exit_code"
189
- if command -v openssl >/dev/null 2>&1; then
190
- (
191
- set +u
192
- genpass >/dev/null 2>&1
193
- )
194
- assert_equals "0" "$?" "exit code should be 0"
195
- else
196
- ((TESTS_PASSED++))
197
- echo -e " ${YELLOW}~${NC} $CURRENT_TEST: skipped (openssl not available)"
198
- fi
199
-
200
- # Test: genpass shows INFO message
201
- test_start "genpass_info_message"
202
- if command -v openssl >/dev/null 2>&1; then
203
- output=$(
204
- set +u
205
- genpass 2>&1
206
- )
207
- if [[ "$output" == *"INFO"* ]]; then
208
- ((TESTS_PASSED++))
209
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: shows INFO message"
210
- else
211
- ((TESTS_FAILED++))
212
- echo -e " ${RED}✗${NC} $CURRENT_TEST: should show INFO message"
213
- fi
214
- else
215
- ((TESTS_PASSED++))
216
- echo -e " ${YELLOW}~${NC} $CURRENT_TEST: skipped (openssl not available)"
217
- fi
218
-
219
- # Test: genpass passwords are unique
220
- test_start "genpass_unique_passwords"
221
- if command -v openssl >/dev/null 2>&1; then
222
- pass1=$( (
223
- set +u
224
- genpass 2>&1
225
- ) | grep "Generated password:" | sed 's/.*Generated password: //')
226
- pass2=$( (
227
- set +u
228
- genpass 2>&1
229
- ) | grep "Generated password:" | sed 's/.*Generated password: //')
230
-
231
- if [[ "$pass1" != "$pass2" ]]; then
232
- ((TESTS_PASSED++))
233
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: generates unique passwords"
234
- else
235
- ((TESTS_FAILED++))
236
- echo -e " ${RED}✗${NC} $CURRENT_TEST: passwords should be unique"
237
- fi
238
- else
239
- ((TESTS_PASSED++))
240
- echo -e " ${YELLOW}~${NC} $CURRENT_TEST: skipped (openssl not available)"
241
- fi
242
-
243
- # Test: genpass password length with blocks
244
- test_start "genpass_password_length"
245
- if command -v openssl >/dev/null 2>&1; then
246
- output=$(
247
- set +u
248
- genpass 3 2>&1
249
- )
250
- password=$(echo "$output" | grep "Generated password:" | sed 's/.*Generated password: //')
251
- # Remove separators to count actual characters
252
- password_no_sep=$(echo "$password" | tr -d '-')
253
- length=${#password_no_sep}
254
-
255
- # 3 blocks * 12 chars = 36 chars (per default block_size)
256
- if [[ "$length" -ge 30 && "$length" -le 40 ]]; then
257
- ((TESTS_PASSED++))
258
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: password length is appropriate ($length chars)"
259
- else
260
- ((TESTS_PASSED++)) # Length varies based on implementation
261
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: password generated with length $length"
262
- fi
263
- else
264
- ((TESTS_PASSED++))
265
- echo -e " ${YELLOW}~${NC} $CURRENT_TEST: skipped (openssl not available)"
266
- fi
267
-
268
- # Test: genpass contains special characters (high entropy)
269
- test_start "genpass_special_chars"
270
- if command -v openssl >/dev/null 2>&1; then
271
- # Generate several passwords and check for special chars
272
- has_special=false
273
- for i in {1..5}; do
274
- password=$( (
275
- set +u
276
- genpass 2>&1
277
- ) | grep "Generated password:" | sed 's/.*Generated password: //')
278
- if [[ "$password" =~ [!@#\$%\^\&\*\(\)_\+\{\}\|:\<\>\?~\[\]\;\',./=-] ]]; then
279
- has_special=true
280
- break
281
- fi
282
- done
283
-
284
- if [[ "$has_special" == true ]]; then
285
- ((TESTS_PASSED++))
286
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: includes special characters"
287
- else
288
- ((TESTS_PASSED++)) # Might not always include special chars
289
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: password generated (special chars optional)"
290
- fi
291
- else
292
- ((TESTS_PASSED++))
293
- echo -e " ${YELLOW}~${NC} $CURRENT_TEST: skipped (openssl not available)"
294
- fi
295
-
296
- echo ""
297
- echo "Genpass function tests completed."
298
- echo "RESULTS:$TESTS_RUN:$TESTS_PASSED:$TESTS_FAILED"
@@ -1,167 +0,0 @@
1
- #!/usr/bin/env bash
2
- # shellcheck disable=SC1090,SC1091
3
- # Unit tests for install.sh edge cases, idempotency, and input validation
4
- set -euo pipefail
5
-
6
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
7
- REPO_ROOT="${REPO_ROOT:-$(cd "$SCRIPT_DIR/../../.." && pwd)}"
8
- source "$SCRIPT_DIR/../framework/assertions.sh"
9
-
10
- INSTALL_SCRIPT="$REPO_ROOT/install.sh"
11
-
12
- echo "Testing install.sh edge cases..."
13
-
14
- # Test: install.sh has set -euo pipefail
15
- test_start "install_strict_mode"
16
- if grep -q "set -euo pipefail" "$INSTALL_SCRIPT"; then
17
- ((TESTS_PASSED++)) || true
18
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: uses strict mode (set -euo pipefail)"
19
- else
20
- ((TESTS_FAILED++)) || true
21
- echo -e " ${RED}✗${NC} $CURRENT_TEST: should use set -euo pipefail"
22
- fi
23
-
24
- # Test: install.sh checks for existing chezmoi before installing
25
- test_start "install_chezmoi_check"
26
- if grep -q 'command -v chezmoi' "$INSTALL_SCRIPT"; then
27
- ((TESTS_PASSED++)) || true
28
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: checks for existing chezmoi"
29
- else
30
- ((TESTS_FAILED++)) || true
31
- echo -e " ${RED}✗${NC} $CURRENT_TEST: should check for existing chezmoi"
32
- fi
33
-
34
- # Test: install.sh installs chezmoi via Homebrew when available
35
- test_start "install_chezmoi_brew"
36
- if grep -q 'brew install chezmoi' "$INSTALL_SCRIPT"; then
37
- ((TESTS_PASSED++)) || true
38
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: installs chezmoi via Homebrew when available"
39
- else
40
- ((TESTS_FAILED++)) || true
41
- echo -e " ${RED}✗${NC} $CURRENT_TEST: should install chezmoi via Homebrew"
42
- fi
43
-
44
- # Test: install.sh falls back to get.chezmoi.io for binary install
45
- test_start "install_chezmoi_fallback"
46
- if grep -q 'get.chezmoi.io' "$INSTALL_SCRIPT"; then
47
- ((TESTS_PASSED++)) || true
48
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: falls back to get.chezmoi.io"
49
- else
50
- ((TESTS_FAILED++)) || true
51
- echo -e " ${RED}✗${NC} $CURRENT_TEST: should fall back to get.chezmoi.io"
52
- fi
53
-
54
- # Test: install.sh adds BIN_DIR to PATH for fallback install
55
- test_start "install_path_update"
56
- if grep -q 'bin_dir=.*local/bin' "$INSTALL_SCRIPT" && grep -q 'export PATH=.*bin_dir' "$INSTALL_SCRIPT"; then
57
- ((TESTS_PASSED++)) || true
58
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: adds ~/.local/bin to PATH via bin_dir"
59
- else
60
- ((TESTS_FAILED++)) || true
61
- echo -e " ${RED}✗${NC} $CURRENT_TEST: should add ~/.local/bin to PATH"
62
- fi
63
-
64
- # Test: install.sh handles backup of existing .dotfiles
65
- test_start "install_backup_existing"
66
- if grep -q '\.dotfiles\.bak' "$INSTALL_SCRIPT"; then
67
- ((TESTS_PASSED++)) || true
68
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: backs up existing .dotfiles directory"
69
- else
70
- ((TESTS_FAILED++)) || true
71
- echo -e " ${RED}✗${NC} $CURRENT_TEST: should backup existing .dotfiles"
72
- fi
73
-
74
- # Test: install.sh supports noninteractive mode
75
- test_start "install_noninteractive_mode"
76
- if grep -q "DOTFILES_NONINTERACTIVE" "$INSTALL_SCRIPT"; then
77
- ((TESTS_PASSED++)) || true
78
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: supports DOTFILES_NONINTERACTIVE"
79
- else
80
- ((TESTS_FAILED++)) || true
81
- echo -e " ${RED}✗${NC} $CURRENT_TEST: should support noninteractive mode"
82
- fi
83
-
84
- # Test: install.sh uses --force --no-tty in noninteractive mode
85
- test_start "install_noninteractive_flags"
86
- if grep -q "\-\-force" "$INSTALL_SCRIPT" && grep -q "\-\-no-tty" "$INSTALL_SCRIPT"; then
87
- ((TESTS_PASSED++)) || true
88
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: uses --force --no-tty in noninteractive mode"
89
- else
90
- ((TESTS_FAILED++)) || true
91
- echo -e " ${RED}✗${NC} $CURRENT_TEST: should use --force --no-tty"
92
- fi
93
-
94
- # Test: install.sh uses HTTPS for all URLs
95
- test_start "install_https_only"
96
- http_urls=$(grep -n 'http://' "$INSTALL_SCRIPT" | grep -v '^#' | grep -v 'http://deb' || true)
97
- if [[ -z "$http_urls" ]]; then
98
- ((TESTS_PASSED++)) || true
99
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: all URLs use HTTPS"
100
- else
101
- ((TESTS_FAILED++)) || true
102
- echo -e " ${RED}✗${NC} $CURRENT_TEST: found non-HTTPS URLs"
103
- echo -e " $http_urls"
104
- fi
105
-
106
- # Test: install.sh backs up user dotfiles (not source repo)
107
- test_start "install_backup_user_dotfiles"
108
- if grep -q 'chezmoi managed' "$INSTALL_SCRIPT" && grep -q 'cp -a' "$INSTALL_SCRIPT"; then
109
- ((TESTS_PASSED++)) || true
110
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: backs up files chezmoi will overwrite"
111
- else
112
- ((TESTS_FAILED++)) || true
113
- echo -e " ${RED}✗${NC} $CURRENT_TEST: should back up managed dotfiles"
114
- fi
115
-
116
- # Test: install.sh detects multiple OS types
117
- test_start "install_multi_os_detection"
118
- os_count=0
119
- for os in "debian" "fedora" "arch" "macos" "wsl2"; do
120
- if grep -q "$os" "$INSTALL_SCRIPT"; then
121
- os_count=$((os_count + 1))
122
- fi
123
- done
124
- if [[ $os_count -ge 3 ]]; then
125
- ((TESTS_PASSED++)) || true
126
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: detects $os_count OS types"
127
- else
128
- ((TESTS_FAILED++)) || true
129
- echo -e " ${RED}✗${NC} $CURRENT_TEST: should detect at least 3 OS types, found $os_count"
130
- fi
131
-
132
- # Test: install.sh does not contain curl | sh (pipes to shell) # gitleaks:allow
133
- test_start "install_no_curl_pipe_sh"
134
- # The Homebrew install line is a known pattern but uses /bin/bash -c, not pipe
135
- curl_pipe=$(grep 'curl.*|.*sh' "$INSTALL_SCRIPT" | grep -v "Homebrew" | grep -v "^#" || true) # gitleaks:allow
136
- if [[ -z "$curl_pipe" ]]; then
137
- ((TESTS_PASSED++)) || true
138
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: no unsafe curl|sh patterns" # gitleaks:allow
139
- else
140
- ((TESTS_FAILED++)) || true
141
- echo -e " ${RED}✗${NC} $CURRENT_TEST: found curl piped to shell"
142
- echo -e " $curl_pipe"
143
- fi
144
-
145
- # Test: ensure_chezmoi_source function exists
146
- test_start "install_ensure_chezmoi_source"
147
- if grep -q "ensure_chezmoi_source" "$INSTALL_SCRIPT"; then
148
- ((TESTS_PASSED++)) || true
149
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: has ensure_chezmoi_source function"
150
- else
151
- ((TESTS_FAILED++)) || true
152
- echo -e " ${RED}✗${NC} $CURRENT_TEST: should have ensure_chezmoi_source"
153
- fi
154
-
155
- # Test: install.sh handles legacy source migration
156
- test_start "install_legacy_migration"
157
- if grep -q 'Migrating from legacy source' "$INSTALL_SCRIPT"; then
158
- ((TESTS_PASSED++)) || true
159
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: migrates legacy chezmoi source directory"
160
- else
161
- ((TESTS_FAILED++)) || true
162
- echo -e " ${RED}✗${NC} $CURRENT_TEST: should handle legacy source migration"
163
- fi
164
-
165
- echo ""
166
- echo "install.sh edge case tests completed."
167
- print_summary
@@ -1,172 +0,0 @@
1
- #!/usr/bin/env bash
2
- # shellcheck disable=SC1090,SC1091
3
- # Unit tests for install/lib/installers.sh
4
-
5
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
- REPO_ROOT="${REPO_ROOT:-$(cd "$SCRIPT_DIR/../../.." && pwd)}"
7
- source "$SCRIPT_DIR/../framework/assertions.sh"
8
- source "$SCRIPT_DIR/../framework/mocks.sh"
9
-
10
- LOGGING_FILE="$REPO_ROOT/install/lib/logging.sh"
11
- INSTALLERS_FILE="$REPO_ROOT/install/lib/installers.sh"
12
-
13
- echo "Testing installers library..."
14
-
15
- # Test: installers.sh exists
16
- test_start "installers_file_exists"
17
- assert_file_exists "$INSTALLERS_FILE" "installers.sh should exist"
18
-
19
- # Test: installers.sh has valid syntax
20
- test_start "installers_syntax"
21
- assert_exit_code 0 "bash -n '$INSTALLERS_FILE'"
22
-
23
- # Test: installers.sh has double-source guard
24
- test_start "installers_guard"
25
- assert_file_contains "$INSTALLERS_FILE" "_DOTFILES_INSTALLERS_LOADED" "should have double-source guard"
26
-
27
- # Test: sha256_file computes checksum
28
- test_start "sha256_file_computes"
29
- tmp_file=$(mock_file "hello world")
30
- output=$(bash -c '
31
- source "'"$LOGGING_FILE"'"
32
- source "'"$INSTALLERS_FILE"'"
33
- sha256_file "'"$tmp_file"'"
34
- ')
35
- # sha256 of "hello world\n" is known
36
- if [[ -n "$output" && ${#output} -eq 64 ]]; then
37
- ((TESTS_PASSED++)) || true
38
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: sha256_file returns 64-char hash"
39
- else
40
- ((TESTS_FAILED++)) || true
41
- echo -e " ${RED}✗${NC} $CURRENT_TEST: sha256_file should return 64-char hash"
42
- echo -e " Output: $output (length: ${#output})"
43
- fi
44
-
45
- # Test: resolve_arch returns valid architecture
46
- test_start "resolve_arch_valid"
47
- output=$(bash -c '
48
- source "'"$LOGGING_FILE"'"
49
- source "'"$INSTALLERS_FILE"'"
50
- resolve_arch
51
- ')
52
- if [[ "$output" == "x86_64" || "$output" == "aarch64" ]]; then
53
- ((TESTS_PASSED++)) || true
54
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: resolve_arch returns $output"
55
- else
56
- ((TESTS_FAILED++)) || true
57
- echo -e " ${RED}✗${NC} $CURRENT_TEST: resolve_arch should return x86_64 or aarch64"
58
- echo -e " Output: $output"
59
- fi
60
-
61
- # Test: resolve_sudo returns empty or "sudo"
62
- test_start "resolve_sudo_returns"
63
- output=$(bash -c '
64
- source "'"$LOGGING_FILE"'"
65
- source "'"$INSTALLERS_FILE"'"
66
- resolve_sudo
67
- ')
68
- if [[ -z "$output" || "$output" == "sudo" ]]; then
69
- ((TESTS_PASSED++)) || true
70
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: resolve_sudo returns '$output'"
71
- else
72
- ((TESTS_FAILED++)) || true
73
- echo -e " ${RED}✗${NC} $CURRENT_TEST: resolve_sudo should return empty or 'sudo'"
74
- echo -e " Output: $output"
75
- fi
76
-
77
- # Test: warn_unpinned dies on "latest" tag
78
- test_start "warn_unpinned_dies_on_latest"
79
- assert_exit_code 1 "bash -c 'source \"$LOGGING_FILE\"; source \"$INSTALLERS_FILE\"; warn_unpinned Test latest TEST_TAG'"
80
-
81
- # Test: warn_unpinned dies on "nightly" tag
82
- test_start "warn_unpinned_dies_on_nightly"
83
- assert_exit_code 1 "bash -c 'source \"$LOGGING_FILE\"; source \"$INSTALLERS_FILE\"; warn_unpinned Test nightly TEST_TAG'"
84
-
85
- # Test: warn_unpinned succeeds on pinned tag
86
- test_start "warn_unpinned_ok_pinned"
87
- assert_exit_code 0 "bash -c 'source \"$LOGGING_FILE\"; source \"$INSTALLERS_FILE\"; warn_unpinned Test v1.2.3 TEST_TAG'"
88
-
89
- # Test: github_asset_url constructs fallback URL for tagged release
90
- test_start "github_asset_url_tagged"
91
- output=$(bash -c '
92
- source "'"$LOGGING_FILE"'"
93
- source "'"$INSTALLERS_FILE"'"
94
- github_asset_url "owner/repo" "binary-linux.tar.gz" "v1.0.0"
95
- ' 2>/dev/null)
96
- if [[ "$output" == *"github.com"* && "$output" == *"v1.0.0"* && "$output" == *"binary-linux.tar.gz"* ]]; then
97
- ((TESTS_PASSED++)) || true
98
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: github_asset_url returns correct tagged URL"
99
- else
100
- ((TESTS_FAILED++)) || true
101
- echo -e " ${RED}✗${NC} $CURRENT_TEST: github_asset_url should construct tagged URL"
102
- echo -e " Output: $output"
103
- fi
104
-
105
- # Test: github_asset_url constructs fallback URL for latest release
106
- test_start "github_asset_url_latest"
107
- output=$(bash -c '
108
- source "'"$LOGGING_FILE"'"
109
- source "'"$INSTALLERS_FILE"'"
110
- github_asset_url "owner/repo" "binary.tar.gz" "latest"
111
- ' 2>/dev/null)
112
- if [[ "$output" == *"github.com/owner/repo/releases/latest/download/binary.tar.gz"* ]]; then
113
- ((TESTS_PASSED++)) || true
114
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: github_asset_url returns correct latest URL"
115
- else
116
- ((TESTS_FAILED++)) || true
117
- echo -e " ${RED}✗${NC} $CURRENT_TEST: github_asset_url should construct latest URL"
118
- echo -e " Output: $output"
119
- fi
120
-
121
- # Test: download_and_verify_sha256 verifies matching checksum
122
- test_start "download_verify_matching"
123
- tmp_dir=$(mock_dir "verify_test")
124
- echo "test file content" >"$tmp_dir/test.bin"
125
- # Use sha256sum on Linux, shasum on macOS
126
- if command -v sha256sum >/dev/null 2>&1; then
127
- expected_hash=$(sha256sum "$tmp_dir/test.bin" | awk '{print $1}')
128
- else
129
- expected_hash=$(shasum -a 256 "$tmp_dir/test.bin" | awk '{print $1}')
130
- fi
131
- echo "$expected_hash test.bin" >"$tmp_dir/test.bin.sha256"
132
- # Create mock curl that copies local files
133
- mock_init
134
- cat >"$MOCK_BIN_DIR/curl" <<'SCRIPT'
135
- #!/usr/bin/env bash
136
- # Extract -o destination from args
137
- dest=""
138
- url=""
139
- while [[ $# -gt 0 ]]; do
140
- case "$1" in
141
- -o) dest="$2"; shift 2 ;;
142
- -*) shift ;;
143
- *) url="$1"; shift ;;
144
- esac
145
- done
146
- if [[ -n "$dest" && -n "$url" && -f "$url" ]]; then
147
- cp "$url" "$dest"
148
- fi
149
- SCRIPT
150
- chmod +x "$MOCK_BIN_DIR/curl"
151
-
152
- result=$(bash -c '
153
- export PATH="'"$MOCK_BIN_DIR"':$PATH"
154
- source "'"$LOGGING_FILE"'"
155
- source "'"$INSTALLERS_FILE"'"
156
- download_and_verify_sha256 "'"$tmp_dir/test.bin"'" "'"$tmp_dir/test.bin.sha256"'" "'"$tmp_dir/downloaded.bin"'"
157
- echo "OK"
158
- ' 2>&1) || true
159
- if [[ "$result" == *"OK"* ]]; then
160
- ((TESTS_PASSED++)) || true
161
- echo -e " ${GREEN}✓${NC} $CURRENT_TEST: verify succeeds with matching checksum"
162
- else
163
- ((TESTS_FAILED++)) || true
164
- echo -e " ${RED}✗${NC} $CURRENT_TEST: verify should succeed with matching checksum"
165
- echo -e " Output: $result"
166
- fi
167
-
168
- # Test: double-sourcing installers is idempotent
169
- test_start "installers_idempotent"
170
- assert_exit_code 0 "bash -c 'source \"$LOGGING_FILE\"; source \"$INSTALLERS_FILE\"; source \"$INSTALLERS_FILE\"; echo ok'"
171
-
172
- print_summary