jekyll-theme-zer0 0.8.1 → 0.10.3

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 (63) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +308 -4
  3. data/README.md +58 -25
  4. data/_data/README.md +4 -5
  5. data/_includes/README.md +1 -1
  6. data/_includes/components/mermaid.html +98 -9
  7. data/_includes/content/intro.html +13 -1
  8. data/_includes/core/header.html +1 -1
  9. data/_includes/stats/README.md +14 -2
  10. data/_layouts/README.md +3 -3
  11. data/_layouts/category.html +16 -6
  12. data/_layouts/collection.html +8 -3
  13. data/_layouts/journals.html +8 -3
  14. data/_sass/core/_theme.scss +4 -1
  15. data/_sass/custom.scss +20 -12
  16. data/assets/images/previews/10-ai-tools-that-will-transform-your-productivity-.png +0 -0
  17. data/assets/images/previews/business.png +0 -0
  18. data/assets/images/previews/css-grid-mastery-build-any-layout-you-can-imagine.png +0 -0
  19. data/assets/images/previews/development.png +0 -0
  20. data/assets/images/previews/github-setup-deployment.png +0 -0
  21. data/assets/images/previews/jekyll-setup.png +0 -0
  22. data/assets/images/previews/machine-setup.png +0 -0
  23. data/assets/images/previews/published-documentation-library.png +0 -0
  24. data/assets/images/previews/quantum-computing-explained-from-qubits-to-quantum.png +0 -0
  25. data/assets/images/previews/science.png +0 -0
  26. data/assets/images/previews/technology.png +0 -0
  27. data/assets/images/previews/the-complete-guide-to-startup-funding-in-2025.png +0 -0
  28. data/assets/images/previews/the-remote-work-revolution-how-global-teams-are-re.png +0 -0
  29. data/assets/images/previews/tutorial.png +0 -0
  30. data/assets/images/previews/world-news.png +0 -0
  31. data/assets/images/previews/zer0-mistakes-news-network-building-dynamic-news-s.png +0 -0
  32. data/assets/images/previews/zer0-mistakes-quick-start-guide.png +0 -0
  33. data/assets/js/auto-hide-nav.js +79 -16
  34. data/scripts/bin/build +115 -0
  35. data/scripts/bin/release +240 -0
  36. data/scripts/bin/test +203 -0
  37. data/scripts/features/generate-preview-images +846 -0
  38. data/scripts/features/install-preview-generator +531 -0
  39. data/scripts/features/preview_generator.py +646 -0
  40. data/scripts/generate-preview-images.sh +38 -93
  41. data/scripts/lib/README.md +35 -7
  42. data/scripts/lib/preview_generator.py +37 -22
  43. data/scripts/test/integration/auto-version +243 -0
  44. data/scripts/test/integration/mermaid +252 -0
  45. data/scripts/test/lib/run_tests.sh +151 -0
  46. data/scripts/test/lib/test_changelog.sh +90 -0
  47. data/scripts/test/lib/test_gem.sh +71 -0
  48. data/scripts/test/lib/test_git.sh +85 -0
  49. data/scripts/test/lib/test_validation.sh +75 -0
  50. data/scripts/test/lib/test_version.sh +101 -0
  51. data/scripts/test/theme/validate +120 -0
  52. data/scripts/test-mermaid.sh +51 -11
  53. data/scripts/utils/analyze-commits +300 -0
  54. data/scripts/utils/fix-markdown +251 -0
  55. data/scripts/utils/setup +137 -0
  56. data/scripts/version.sh +26 -0
  57. metadata +37 -8
  58. data/scripts/build.sh +0 -33
  59. data/scripts/build.sh.legacy +0 -174
  60. data/scripts/gem-publish.sh +0 -42
  61. data/scripts/gem-publish.sh.legacy +0 -700
  62. data/scripts/release.sh +0 -33
  63. data/scripts/release.sh.legacy +0 -342
@@ -0,0 +1,243 @@
1
+ #!/bin/bash
2
+
3
+ # Test Script for Automated Version Bump System
4
+ # Tests the commit analysis and version bump automation
5
+ # Usage: ./scripts/test/integration/auto-version
6
+
7
+ set -euo pipefail
8
+
9
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
10
+ SCRIPTS_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
11
+ PROJECT_ROOT="$(cd "$SCRIPTS_ROOT/.." && pwd)"
12
+ LIB_DIR="$SCRIPTS_ROOT/lib"
13
+
14
+ # Source common library for logging and utilities
15
+ source "$LIB_DIR/common.sh"
16
+
17
+ # Aliases for backward compatibility
18
+ log_info() { info "$@"; }
19
+ log_success() { success "$@"; }
20
+ log_warning() { warn "$@"; }
21
+ log_error() { error "$@"; }
22
+ log_test() { step "$@"; }
23
+
24
+ # Test counter
25
+ TESTS_RUN=0
26
+ TESTS_PASSED=0
27
+
28
+ run_test() {
29
+ local test_name="$1"
30
+ local test_command="$2"
31
+ local expected_result="${3:-}"
32
+
33
+ ((TESTS_RUN++))
34
+ log_test "Running: $test_name"
35
+
36
+ local actual_result
37
+ if actual_result=$(eval "$test_command" 2>&1); then
38
+ if [[ -n "$expected_result" ]]; then
39
+ if [[ "$actual_result" == "$expected_result" ]]; then
40
+ log_success "✅ $test_name"
41
+ ((TESTS_PASSED++))
42
+ else
43
+ log_error "❌ $test_name - Expected: '$expected_result', Got: '$actual_result'"
44
+ fi
45
+ else
46
+ log_success "✅ $test_name"
47
+ ((TESTS_PASSED++))
48
+ fi
49
+ else
50
+ log_error "❌ $test_name - Command failed: $actual_result"
51
+ fi
52
+ }
53
+
54
+ # Test the commit analysis script
55
+ test_commit_analysis() {
56
+ log_info "Testing commit analysis functionality..."
57
+
58
+ # Test script exists and is executable
59
+ run_test "Commit analysis script exists" "test -x '$SCRIPT_DIR/analyze-commits.sh'"
60
+
61
+ # Test help output
62
+ run_test "Help output works" "$SCRIPT_DIR/analyze-commits.sh --help | grep -q 'Commit Analysis Script'"
63
+
64
+ # Test with sample commit ranges (if we have git history)
65
+ if git rev-list --count HEAD >/dev/null 2>&1; then
66
+ local commit_count=$(git rev-list --count HEAD)
67
+
68
+ if [[ $commit_count -gt 1 ]]; then
69
+ # Test analyzing last commit
70
+ run_test "Analyze last commit" "$SCRIPT_DIR/analyze-commits.sh HEAD~1..HEAD | grep -E '^(patch|minor|major|none)$'"
71
+
72
+ # Test analyzing multiple commits if available
73
+ if [[ $commit_count -gt 3 ]]; then
74
+ run_test "Analyze multiple commits" "$SCRIPT_DIR/analyze-commits.sh HEAD~3..HEAD | grep -E '^(patch|minor|major|none)$'"
75
+ fi
76
+ fi
77
+ else
78
+ log_warning "No git history available for commit analysis tests"
79
+ fi
80
+ }
81
+
82
+ # Test gem publication script compatibility
83
+ test_gem_publish_script() {
84
+ log_info "Testing gem publication script compatibility..."
85
+
86
+ # Test script exists and is executable
87
+ run_test "Gem publish script exists" "test -x '$SCRIPT_DIR/gem-publish.sh'"
88
+
89
+ # Test new automated options
90
+ run_test "Automated release option works" "$SCRIPT_DIR/gem-publish.sh --help | grep -q 'automated-release'"
91
+ run_test "Auto commit range option works" "$SCRIPT_DIR/gem-publish.sh --help | grep -q 'auto-commit-range'"
92
+
93
+ # Test dry run with automated options
94
+ if [[ -f "$PROJECT_ROOT/lib/jekyll-theme-zer0/version.rb" ]]; then
95
+ run_test "Dry run with automated options" "$SCRIPT_DIR/gem-publish.sh patch --dry-run --automated-release --skip-tests --skip-publish --no-github-release | grep -q 'Automated Release Mode'"
96
+ fi
97
+ }
98
+
99
+ # Test workflow files syntax
100
+ test_workflow_syntax() {
101
+ log_info "Testing GitHub Actions workflow syntax..."
102
+
103
+ # Check if yamllint is available
104
+ if command -v yamllint >/dev/null 2>&1; then
105
+ run_test "Auto-version-bump workflow syntax" "yamllint '$PROJECT_ROOT/.github/workflows/auto-version-bump.yml'"
106
+ else
107
+ # Basic YAML syntax check with Python
108
+ if command -v python3 >/dev/null 2>&1; then
109
+ run_test "Auto-version-bump workflow syntax" "python3 -c 'import yaml; yaml.safe_load(open(\"$PROJECT_ROOT/.github/workflows/auto-version-bump.yml\"))'"
110
+ else
111
+ log_warning "Neither yamllint nor python3 available for YAML validation"
112
+ fi
113
+ fi
114
+ }
115
+
116
+ # Test file permissions and executability
117
+ test_file_permissions() {
118
+ log_info "Testing file permissions..."
119
+
120
+ local scripts=(
121
+ "$SCRIPT_DIR/analyze-commits.sh"
122
+ "$SCRIPT_DIR/gem-publish.sh"
123
+ )
124
+
125
+ for script in "${scripts[@]}"; do
126
+ local script_name=$(basename "$script")
127
+ run_test "$script_name is executable" "test -x '$script'"
128
+ done
129
+ }
130
+
131
+ # Test integration between components
132
+ test_integration() {
133
+ log_info "Testing integration between components..."
134
+
135
+ # Test that analyze-commits.sh can be called by the workflow
136
+ if [[ -x "$SCRIPT_DIR/analyze-commits.sh" ]]; then
137
+ # Test with a simple commit range
138
+ if git rev-list --count HEAD >/dev/null 2>&1; then
139
+ local commit_count=$(git rev-list --count HEAD)
140
+ if [[ $commit_count -gt 0 ]]; then
141
+ run_test "Integration: commit analysis returns valid output" "$SCRIPT_DIR/analyze-commits.sh HEAD~1..HEAD | grep -E '^(patch|minor|major|none)$'"
142
+ fi
143
+ fi
144
+ fi
145
+
146
+ # Test that gem-publish.sh accepts the new parameters
147
+ if [[ -x "$SCRIPT_DIR/gem-publish.sh" ]]; then
148
+ run_test "Integration: gem-publish accepts automated params" "$SCRIPT_DIR/gem-publish.sh patch --dry-run --automated-release --auto-commit-range=HEAD~1..HEAD --skip-tests --skip-publish --no-github-release | grep -q 'DRY RUN MODE'"
149
+ fi
150
+ }
151
+
152
+ # Test conventional commit detection
153
+ test_conventional_commits() {
154
+ log_info "Testing conventional commit detection..."
155
+
156
+ # Create test commits in memory (don't actually commit)
157
+ local test_commits=(
158
+ "feat: add new feature"
159
+ "fix: resolve bug in component"
160
+ "BREAKING CHANGE: remove deprecated API"
161
+ "chore: update dependencies"
162
+ "docs: improve documentation"
163
+ )
164
+
165
+ local expected_results=(
166
+ "minor"
167
+ "patch"
168
+ "major"
169
+ "patch"
170
+ "patch"
171
+ )
172
+
173
+ # Note: This would require a more sophisticated test setup
174
+ # For now, just test that the patterns exist in the script
175
+ run_test "Conventional commit patterns exist" "grep -q 'feat.*minor' '$SCRIPT_DIR/analyze-commits.sh'"
176
+ run_test "Fix patterns exist" "grep -q 'fix.*patch' '$SCRIPT_DIR/analyze-commits.sh'"
177
+ run_test "Breaking change patterns exist" "grep -q 'BREAKING.*major' '$SCRIPT_DIR/analyze-commits.sh'"
178
+ }
179
+
180
+ # Main test execution
181
+ main() {
182
+ log_info "🧪 Starting Automated Version Bump System Tests"
183
+ echo "=================================================="
184
+ echo ""
185
+
186
+ # Change to project root
187
+ cd "$PROJECT_ROOT"
188
+
189
+ # Run all test suites
190
+ test_file_permissions
191
+ test_commit_analysis
192
+ test_gem_publish_script
193
+ test_workflow_syntax
194
+ test_integration
195
+ test_conventional_commits
196
+
197
+ # Test summary
198
+ echo ""
199
+ echo "=================================================="
200
+ log_info "🎯 Test Results Summary"
201
+ echo "Tests Run: $TESTS_RUN"
202
+ echo "Tests Passed: $TESTS_PASSED"
203
+ echo "Tests Failed: $((TESTS_RUN - TESTS_PASSED))"
204
+
205
+ if [[ $TESTS_PASSED -eq $TESTS_RUN ]]; then
206
+ log_success "🎉 All tests passed! Automated version bump system is ready."
207
+ exit 0
208
+ else
209
+ log_error "❌ Some tests failed. Please review the issues above."
210
+ exit 1
211
+ fi
212
+ }
213
+
214
+ # Show usage if requested
215
+ if [[ "${1:-}" == "--help" ]] || [[ "${1:-}" == "-h" ]]; then
216
+ cat << EOF
217
+ Test Script for Automated Version Bump System
218
+
219
+ USAGE:
220
+ $0
221
+
222
+ DESCRIPTION:
223
+ This script tests the automated version bump system including:
224
+ - Commit analysis functionality
225
+ - Gem publication script compatibility
226
+ - Workflow file syntax validation
227
+ - Integration between components
228
+ - Conventional commit detection
229
+
230
+ REQUIREMENTS:
231
+ - Git repository with commit history
232
+ - Executable scripts in scripts/ directory
233
+ - Valid GitHub Actions workflow files
234
+
235
+ OUTPUT:
236
+ Detailed test results and summary
237
+ Exit code 0 on success, 1 on failure
238
+ EOF
239
+ exit 0
240
+ fi
241
+
242
+ # Execute main function
243
+ main "$@"
@@ -0,0 +1,252 @@
1
+ #!/bin/bash
2
+
3
+ ###############################################################################
4
+ # Mermaid Integration Test Script
5
+ #
6
+ # Purpose: Comprehensive testing of Mermaid.js integration in Jekyll
7
+ # Usage: ./scripts/test/integration/mermaid [options]
8
+ # Options:
9
+ # --verbose Show detailed output
10
+ # --headless Run in headless mode (for CI/CD)
11
+ # --quick Run quick validation only
12
+ # --local Test local Jekyll server
13
+ # --docker Test Docker container
14
+ ###############################################################################
15
+
16
+ set -euo pipefail
17
+
18
+ # Get script directories
19
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
20
+ SCRIPTS_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
21
+ LIB_DIR="$SCRIPTS_ROOT/lib"
22
+
23
+ # Source common library for logging and utilities
24
+ source "$LIB_DIR/common.sh"
25
+
26
+ # Test counters
27
+ TESTS_PASSED=0
28
+ TESTS_FAILED=0
29
+ TOTAL_TESTS=0
30
+
31
+ # Configuration
32
+ export VERBOSE=${VERBOSE:-false}
33
+ HEADLESS=false
34
+ QUICK=false
35
+ TEST_MODE="both" # local, docker, both
36
+
37
+ # Parse arguments
38
+ for arg in "$@"; do
39
+ case $arg in
40
+ --verbose)
41
+ export VERBOSE=true
42
+ shift
43
+ ;;
44
+ --headless)
45
+ HEADLESS=true
46
+ shift
47
+ ;;
48
+ --quick)
49
+ QUICK=true
50
+ shift
51
+ ;;
52
+ --local)
53
+ TEST_MODE="local"
54
+ shift
55
+ ;;
56
+ --docker)
57
+ TEST_MODE="docker"
58
+ shift
59
+ ;;
60
+ --help)
61
+ echo "Usage: $0 [options]"
62
+ echo "Options:"
63
+ echo " --verbose Show detailed output"
64
+ echo " --headless Run in headless mode (for CI/CD)"
65
+ echo " --quick Run quick validation only"
66
+ echo " --local Test local Jekyll server only"
67
+ echo " --docker Test Docker container only"
68
+ echo " --help Show this help message"
69
+ exit 0
70
+ ;;
71
+ *)
72
+ echo "Unknown option: $arg"
73
+ echo "Use --help for usage information"
74
+ exit 1
75
+ ;;
76
+ esac
77
+ done
78
+
79
+ # Logging functions
80
+ log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
81
+ log_success() { echo -e "${GREEN}[✓]${NC} $1"; }
82
+ log_warning() { echo -e "${YELLOW}[!]${NC} $1"; }
83
+ log_error() { echo -e "${RED}[✗]${NC} $1"; }
84
+
85
+ # Test function
86
+ run_test() {
87
+ local test_name="$1"
88
+ local test_command="$2"
89
+
90
+ TOTAL_TESTS=$((TOTAL_TESTS + 1))
91
+
92
+ if [ "$VERBOSE" = true ]; then
93
+ log_info "Running: $test_name"
94
+ fi
95
+
96
+ if eval "$test_command" >/dev/null 2>&1; then
97
+ TESTS_PASSED=$((TESTS_PASSED + 1))
98
+ log_success "$test_name"
99
+ return 0
100
+ else
101
+ TESTS_FAILED=$((TESTS_FAILED + 1))
102
+ log_error "$test_name"
103
+ return 1
104
+ fi
105
+ }
106
+
107
+ # Test file existence
108
+ test_file_exists() {
109
+ local file_path="$1"
110
+ local description="$2"
111
+
112
+ run_test "$description" "[ -f '$file_path' ]"
113
+ }
114
+
115
+ # Test file content
116
+ test_file_content() {
117
+ local file_path="$1"
118
+ local pattern="$2"
119
+ local description="$3"
120
+
121
+ run_test "$description" "grep -q '$pattern' '$file_path'"
122
+ }
123
+
124
+ # Test URL accessibility
125
+ test_url() {
126
+ local url="$1"
127
+ local description="$2"
128
+
129
+ run_test "$description" "curl -s -f '$url' >/dev/null"
130
+ }
131
+
132
+ # Test Mermaid script loading
133
+ test_mermaid_script() {
134
+ local url="$1"
135
+ local description="$2"
136
+
137
+ run_test "$description" "curl -s '$url' | grep -q 'mermaid.min.js'"
138
+ }
139
+
140
+ # Test Mermaid initialization
141
+ test_mermaid_init() {
142
+ local url="$1"
143
+ local description="$2"
144
+
145
+ run_test "$description" "curl -s '$url' | grep -q 'mermaid.initialize'"
146
+ }
147
+
148
+ # Test diagram rendering
149
+ test_diagram_rendering() {
150
+ local url="$1"
151
+ local description="$2"
152
+
153
+ run_test "$description" "curl -s '$url' | grep -q 'class=\"mermaid\"'"
154
+ }
155
+
156
+ # Main test execution
157
+ main() {
158
+ echo "🧪 Mermaid Integration Test Suite"
159
+ echo "=================================="
160
+ echo "Mode: $TEST_MODE"
161
+ echo "Verbose: $VERBOSE"
162
+ echo "Quick: $QUICK"
163
+ echo ""
164
+
165
+ # Core file tests
166
+ log_info "Testing core files..."
167
+
168
+ test_file_exists "_includes/components/mermaid.html" "Mermaid include file exists"
169
+ test_file_exists "pages/_docs/jekyll/mermaid.md" "Main documentation exists"
170
+ test_file_exists "pages/_docs/jekyll/mermaid-test-suite.md" "Test suite exists"
171
+ test_file_exists "pages/_docs/jekyll/jekyll-diagram-with-mermaid.md" "Tutorial exists"
172
+
173
+ # Configuration tests
174
+ log_info "Testing configuration..."
175
+
176
+ test_file_content "_config.yml" "jekyll-mermaid" "Jekyll-mermaid plugin configured"
177
+ test_file_content "_config.yml" "mermaid:" "Mermaid configuration present"
178
+ test_file_content "_includes/core/head.html" "page.mermaid" "Conditional loading configured"
179
+ test_file_content "_includes/core/head.html" "mermaid.html" "Mermaid include referenced"
180
+
181
+ # Mermaid include file tests
182
+ log_info "Testing Mermaid include file..."
183
+
184
+ test_file_content "_includes/components/mermaid.html" "mermaid@10" "Mermaid v10 CDN link"
185
+ test_file_content "_includes/components/mermaid.html" "mermaid.initialize" "Mermaid initialization script"
186
+ test_file_content "_includes/components/mermaid.html" "forest" "Forest theme configured"
187
+ test_file_content "_includes/components/mermaid.html" "FontAwesome" "FontAwesome support included"
188
+
189
+ # Documentation tests
190
+ log_info "Testing documentation..."
191
+
192
+ test_file_content "pages/_docs/jekyll/mermaid.md" "mermaid: true" "Main docs have front matter"
193
+ test_file_content "pages/_docs/jekyll/mermaid-test-suite.md" "mermaid: true" "Test suite has front matter"
194
+ test_file_content "pages/_docs/jekyll/mermaid.md" "graph TD" "Main docs have examples"
195
+ test_file_content "pages/_docs/jekyll/mermaid-test-suite.md" "graph TD" "Test suite has examples"
196
+
197
+ # Server tests (if not quick mode)
198
+ if [ "$QUICK" = false ]; then
199
+ log_info "Testing server functionality..."
200
+
201
+ # Test local server if enabled
202
+ if [ "$TEST_MODE" = "local" ] || [ "$TEST_MODE" = "both" ]; then
203
+ log_info "Testing local Jekyll server..."
204
+
205
+ # Check if local server is running
206
+ if curl -s -f "http://localhost:4000" >/dev/null 2>&1; then
207
+ test_url "http://localhost:4000/docs/jekyll/mermaid/" "Main documentation accessible"
208
+ test_url "http://localhost:4000/docs/jekyll/mermaid-test-suite/" "Test suite accessible"
209
+ test_mermaid_script "http://localhost:4000/docs/jekyll/mermaid-test-suite/" "Mermaid script loads on test page"
210
+ test_mermaid_init "http://localhost:4000/docs/jekyll/mermaid-test-suite/" "Mermaid initializes on test page"
211
+ test_diagram_rendering "http://localhost:4000/docs/jekyll/mermaid-test-suite/" "Diagrams render on test page"
212
+ else
213
+ log_warning "Local Jekyll server not running. Start with: bundle exec jekyll serve"
214
+ fi
215
+ fi
216
+
217
+ # Test Docker server if enabled
218
+ if [ "$TEST_MODE" = "docker" ] || [ "$TEST_MODE" = "both" ]; then
219
+ log_info "Testing Docker container..."
220
+
221
+ # Check if Docker container is running
222
+ if docker ps | grep -q "zer0-mistakes-jekyll"; then
223
+ test_url "http://localhost:4000/docs/jekyll/mermaid/" "Docker: Main documentation accessible"
224
+ test_url "http://localhost:4000/docs/jekyll/mermaid-test-suite/" "Docker: Test suite accessible"
225
+ test_mermaid_script "http://localhost:4000/docs/jekyll/mermaid-test-suite/" "Docker: Mermaid script loads"
226
+ test_mermaid_init "http://localhost:4000/docs/jekyll/mermaid-test-suite/" "Docker: Mermaid initializes"
227
+ test_diagram_rendering "http://localhost:4000/docs/jekyll/mermaid-test-suite/" "Docker: Diagrams render"
228
+ else
229
+ log_warning "Docker container not running. Start with: docker-compose up -d"
230
+ fi
231
+ fi
232
+ fi
233
+
234
+ # Summary
235
+ echo ""
236
+ echo "📊 Test Results Summary"
237
+ echo "======================"
238
+ echo "Total Tests: $TOTAL_TESTS"
239
+ echo "Passed: $TESTS_PASSED"
240
+ echo "Failed: $TESTS_FAILED"
241
+
242
+ if [ $TESTS_FAILED -eq 0 ]; then
243
+ log_success "All tests passed! ✅"
244
+ exit 0
245
+ else
246
+ log_error "Some tests failed! ❌"
247
+ exit 1
248
+ fi
249
+ }
250
+
251
+ # Run main function
252
+ main "$@"
@@ -0,0 +1,151 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Test runner for library unit tests
4
+ # Usage: ./scripts/test/lib/run_tests.sh
5
+ #
6
+ # Note: Requires Bash 4.0+ (for associative arrays in changelog.sh)
7
+ # On macOS: brew install bash
8
+
9
+ # Note: We intentionally don't use set -e here because test assertions
10
+ # may return non-zero and we want to continue running tests
11
+ set -uo pipefail
12
+
13
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
14
+ # Navigate from scripts/test/lib to scripts/lib
15
+ LIB_DIR="$(cd "$SCRIPT_DIR/../../lib" && pwd)"
16
+
17
+ # Colors
18
+ RED='\033[0;31m'
19
+ GREEN='\033[0;32m'
20
+ YELLOW='\033[1;33m'
21
+ BLUE='\033[0;34m'
22
+ NC='\033[0m'
23
+
24
+ # Test counters
25
+ TESTS_RUN=0
26
+ TESTS_PASSED=0
27
+ TESTS_FAILED=0
28
+
29
+ # Test result tracking
30
+ declare -a FAILED_TESTS=()
31
+
32
+ # Test assertions
33
+ assert_equals() {
34
+ local expected="$1"
35
+ local actual="$2"
36
+ local message="${3:-}"
37
+
38
+ ((TESTS_RUN++))
39
+
40
+ if [[ "$expected" == "$actual" ]]; then
41
+ ((TESTS_PASSED++))
42
+ echo -e "${GREEN}✓${NC} $message"
43
+ return 0
44
+ else
45
+ ((TESTS_FAILED++))
46
+ echo -e "${RED}✗${NC} $message"
47
+ echo -e " Expected: ${YELLOW}$expected${NC}"
48
+ echo -e " Actual: ${YELLOW}$actual${NC}"
49
+ FAILED_TESTS+=("$message")
50
+ return 1
51
+ fi
52
+ }
53
+
54
+ assert_true() {
55
+ local condition="$1"
56
+ local message="${2:-}"
57
+
58
+ ((TESTS_RUN++))
59
+
60
+ if eval "$condition"; then
61
+ ((TESTS_PASSED++))
62
+ echo -e "${GREEN}✓${NC} $message"
63
+ return 0
64
+ else
65
+ ((TESTS_FAILED++))
66
+ echo -e "${RED}✗${NC} $message"
67
+ echo -e " Condition failed: ${YELLOW}$condition${NC}"
68
+ FAILED_TESTS+=("$message")
69
+ return 1
70
+ fi
71
+ }
72
+
73
+ assert_false() {
74
+ local condition="$1"
75
+ local message="${2:-}"
76
+
77
+ ((TESTS_RUN++))
78
+
79
+ if ! eval "$condition"; then
80
+ ((TESTS_PASSED++))
81
+ echo -e "${GREEN}✓${NC} $message"
82
+ return 0
83
+ else
84
+ ((TESTS_FAILED++))
85
+ echo -e "${RED}✗${NC} $message"
86
+ echo -e " Condition should have failed: ${YELLOW}$condition${NC}"
87
+ FAILED_TESTS+=("$message")
88
+ return 1
89
+ fi
90
+ }
91
+
92
+ # Test suite header
93
+ print_suite_header() {
94
+ echo -e "\n${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
95
+ echo -e "${BLUE}Testing: $1${NC}"
96
+ echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}\n"
97
+ }
98
+
99
+ # Run test files
100
+ run_test_file() {
101
+ local test_file="$1"
102
+
103
+ if [[ -f "$test_file" && -x "$test_file" ]]; then
104
+ bash "$test_file"
105
+ else
106
+ echo -e "${YELLOW}Skipping $test_file (not found or not executable)${NC}"
107
+ fi
108
+ }
109
+
110
+ # Main test execution
111
+ main() {
112
+ echo -e "${BLUE}╔═══════════════════════════════════════╗${NC}"
113
+ echo -e "${BLUE}║ Library Unit Test Suite ║${NC}"
114
+ echo -e "${BLUE}╚═══════════════════════════════════════╝${NC}"
115
+
116
+ # Save the test directory (test files may overwrite SCRIPT_DIR)
117
+ local TEST_DIR="$SCRIPT_DIR"
118
+
119
+ # Export test functions for use in test files
120
+ export -f assert_equals assert_true assert_false print_suite_header
121
+ export RED GREEN YELLOW BLUE NC
122
+ export LIB_DIR
123
+
124
+ # Run individual test files (sourced, not executed)
125
+ source "$TEST_DIR/test_version.sh"
126
+ source "$TEST_DIR/test_validation.sh"
127
+ source "$TEST_DIR/test_git.sh"
128
+ source "$TEST_DIR/test_changelog.sh"
129
+ source "$TEST_DIR/test_gem.sh"
130
+
131
+ # Summary
132
+ echo -e "\n${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
133
+ echo -e "${BLUE}Test Summary${NC}"
134
+ echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
135
+ echo -e "Total: $TESTS_RUN"
136
+ echo -e "${GREEN}Passed: $TESTS_PASSED${NC}"
137
+ echo -e "${RED}Failed: $TESTS_FAILED${NC}"
138
+
139
+ if [[ $TESTS_FAILED -gt 0 ]]; then
140
+ echo -e "\n${RED}Failed tests:${NC}"
141
+ for test in "${FAILED_TESTS[@]}"; do
142
+ echo -e " ${RED}✗${NC} $test"
143
+ done
144
+ exit 1
145
+ else
146
+ echo -e "\n${GREEN}All tests passed! 🎉${NC}"
147
+ exit 0
148
+ fi
149
+ }
150
+
151
+ main "$@"