...
This commit is contained in:
458
lib/web/doctree/meta/site_nav_test.v
Normal file
458
lib/web/doctree/meta/site_nav_test.v
Normal file
@@ -0,0 +1,458 @@
|
||||
module meta
|
||||
|
||||
import incubaid.herolib.core.playbook
|
||||
import incubaid.herolib.ui.console
|
||||
|
||||
// Comprehensive HeroScript for testing multi-level navigation depths
|
||||
const test_heroscript_nav_depth = '
|
||||
!!site.config
|
||||
name: "nav_depth_test"
|
||||
title: "Navigation Depth Test Site"
|
||||
description: "Testing multi-level nested navigation"
|
||||
tagline: "Deep navigation structures"
|
||||
|
||||
!!site.navbar
|
||||
title: "Nav Depth Test"
|
||||
|
||||
!!site.navbar_item
|
||||
label: "Home"
|
||||
to: "/"
|
||||
position: "left"
|
||||
|
||||
// ============================================================
|
||||
// LEVEL 1: Simple top-level category
|
||||
// ============================================================
|
||||
!!site.page_category
|
||||
path: "Why"
|
||||
collapsible: true
|
||||
collapsed: false
|
||||
|
||||
!!site.page src: "why:intro"
|
||||
label: "Why Choose Us"
|
||||
title: "Why Choose Us"
|
||||
description: "Reasons to use this platform"
|
||||
|
||||
!!site.page src: "benefits"
|
||||
label: "Key Benefits"
|
||||
title: "Key Benefits"
|
||||
description: "Main benefits overview"
|
||||
|
||||
// ============================================================
|
||||
// LEVEL 2: Two-level nested category
|
||||
// ============================================================
|
||||
!!site.page_category
|
||||
path: "Tutorials"
|
||||
collapsible: true
|
||||
collapsed: false
|
||||
|
||||
!!site.page src: "tutorials:getting_started"
|
||||
label: "Getting Started"
|
||||
title: "Getting Started"
|
||||
description: "Basic tutorial to get started"
|
||||
|
||||
!!site.page src: "first_steps"
|
||||
label: "First Steps"
|
||||
title: "First Steps"
|
||||
description: "Your first steps with the platform"
|
||||
|
||||
// ============================================================
|
||||
// LEVEL 3: Three-level nested category (Tutorials > Operations > Urgent)
|
||||
// ============================================================
|
||||
!!site.page_category
|
||||
path: "Tutorials/Operations/Urgent"
|
||||
collapsible: true
|
||||
collapsed: false
|
||||
|
||||
!!site.page src: "operations:emergency_restart"
|
||||
label: "Emergency Restart"
|
||||
title: "Emergency Restart"
|
||||
description: "How to emergency restart the system"
|
||||
|
||||
!!site.page src: "critical_fixes"
|
||||
label: "Critical Fixes"
|
||||
title: "Critical Fixes"
|
||||
description: "Apply critical fixes immediately"
|
||||
|
||||
!!site.page src: "incident_response"
|
||||
label: "Incident Response"
|
||||
title: "Incident Response"
|
||||
description: "Handle incidents in real-time"
|
||||
|
||||
// ============================================================
|
||||
// LEVEL 2.5: Two-level nested category (Tutorials > Operations)
|
||||
// ============================================================
|
||||
!!site.page_category
|
||||
path: "Tutorials/Operations"
|
||||
collapsible: true
|
||||
collapsed: false
|
||||
|
||||
!!site.page src: "ops:daily_checks"
|
||||
label: "Daily Checks"
|
||||
title: "Daily Checks"
|
||||
description: "Daily maintenance checklist"
|
||||
|
||||
!!site.page src: "monitoring"
|
||||
label: "Monitoring"
|
||||
title: "Monitoring"
|
||||
description: "System monitoring procedures"
|
||||
|
||||
!!site.page src: "backups"
|
||||
label: "Backups"
|
||||
title: "Backups"
|
||||
description: "Backup and restore procedures"
|
||||
|
||||
// ============================================================
|
||||
// LEVEL 1.5: One-to-two level (Tutorials)
|
||||
// ============================================================
|
||||
// Note: This creates a sibling at the Tutorials level (not nested deeper)
|
||||
!!site.page src: "advanced_concepts"
|
||||
label: "Advanced Concepts"
|
||||
title: "Advanced Concepts"
|
||||
description: "Deep dive into advanced concepts"
|
||||
|
||||
!!site.page src: "troubleshooting"
|
||||
label: "Troubleshooting"
|
||||
title: "Troubleshooting"
|
||||
description: "Troubleshooting guide"
|
||||
|
||||
// ============================================================
|
||||
// LEVEL 2: Two-level nested category (Why > FAQ)
|
||||
// ============================================================
|
||||
!!site.page_category
|
||||
path: "Why/FAQ"
|
||||
collapsible: true
|
||||
collapsed: false
|
||||
|
||||
!!site.page src: "faq:general"
|
||||
label: "General Questions"
|
||||
title: "General Questions"
|
||||
description: "Frequently asked questions"
|
||||
|
||||
!!site.page src: "pricing_questions"
|
||||
label: "Pricing"
|
||||
title: "Pricing Questions"
|
||||
description: "Questions about pricing"
|
||||
|
||||
!!site.page src: "technical_faq"
|
||||
label: "Technical FAQ"
|
||||
title: "Technical FAQ"
|
||||
description: "Technical frequently asked questions"
|
||||
|
||||
!!site.page src: "support_faq"
|
||||
label: "Support"
|
||||
title: "Support FAQ"
|
||||
description: "Support-related FAQ"
|
||||
|
||||
// ============================================================
|
||||
// LEVEL 3+: Even deeper nesting for comprehensive testing
|
||||
// ============================================================
|
||||
!!site.page_category
|
||||
path: "Tutorials/Operations/Database/Optimization"
|
||||
collapsible: true
|
||||
collapsed: false
|
||||
|
||||
!!site.page src: "database:query_optimization"
|
||||
label: "Query Optimization"
|
||||
title: "Query Optimization"
|
||||
description: "Optimize your database queries"
|
||||
|
||||
!!site.page src: "indexing_strategy"
|
||||
label: "Indexing Strategy"
|
||||
title: "Indexing Strategy"
|
||||
description: "Effective indexing strategies"
|
||||
|
||||
!!site.page_category
|
||||
path: "Tutorials/Operations/Database"
|
||||
collapsible: true
|
||||
collapsed: false
|
||||
|
||||
!!site.page src: "db:configuration"
|
||||
label: "Configuration"
|
||||
title: "Database Configuration"
|
||||
description: "Configure your database"
|
||||
|
||||
!!site.page src: "replication"
|
||||
label: "Replication"
|
||||
title: "Database Replication"
|
||||
description: "Set up database replication"
|
||||
|
||||
'
|
||||
|
||||
pub fn test_navigation_depth() ! {
|
||||
console.print_header('🧭 Navigation Depth Multi-Level Test')
|
||||
console.lf()
|
||||
|
||||
// ========================================================
|
||||
// SETUP: Create and process playbook
|
||||
// ========================================================
|
||||
console.print_item('Creating playbook from HeroScript')
|
||||
mut plbook := playbook.new(text: test_heroscript_nav_depth)!
|
||||
console.print_green('✓ Playbook created')
|
||||
console.lf()
|
||||
|
||||
console.print_item('Processing site configuration')
|
||||
play(mut plbook)!
|
||||
console.print_green('✓ Site processed')
|
||||
console.lf()
|
||||
|
||||
console.print_item('Retrieving configured site')
|
||||
mut nav_site := get(name: 'nav_depth_test')!
|
||||
console.print_green('✓ Site retrieved')
|
||||
console.lf()
|
||||
|
||||
// ========================================================
|
||||
// TEST 1: Validate Categories Structure
|
||||
// ========================================================
|
||||
console.print_header('TEST 1: Validate Categories Structure')
|
||||
console.print_item('Total categories: ${nav_site.categories.len}')
|
||||
|
||||
for i, category in nav_site.categories {
|
||||
depth := calculate_category_depth(category.path)
|
||||
console.print_debug(' [${i}] Path: "${category.path}" (Depth: ${depth})')
|
||||
}
|
||||
|
||||
// Assertions for category structure
|
||||
mut all_paths := nav_site.categories.map(it.path)
|
||||
|
||||
assert all_paths.contains('Why'), 'Missing "Why" category'
|
||||
console.print_green('✓ Level 1: "Why" found')
|
||||
|
||||
assert all_paths.contains('Tutorials'), 'Missing "Tutorials" category'
|
||||
console.print_green('✓ Level 1: "Tutorials" found')
|
||||
|
||||
assert all_paths.contains('Why/FAQ'), 'Missing "Why/FAQ" category'
|
||||
console.print_green('✓ Level 2: "Why/FAQ" found')
|
||||
|
||||
assert all_paths.contains('Tutorials/Operations'), 'Missing "Tutorials/Operations" category'
|
||||
console.print_green('✓ Level 2: "Tutorials/Operations" found')
|
||||
|
||||
assert all_paths.contains('Tutorials/Operations/Urgent'), 'Missing "Tutorials/Operations/Urgent" category'
|
||||
console.print_green('✓ Level 3: "Tutorials/Operations/Urgent" found')
|
||||
|
||||
assert all_paths.contains('Tutorials/Operations/Database'), 'Missing "Tutorials/Operations/Database" category'
|
||||
console.print_green('✓ Level 3: "Tutorials/Operations/Database" found')
|
||||
|
||||
assert all_paths.contains('Tutorials/Operations/Database/Optimization'), 'Missing "Tutorials/Operations/Database/Optimization" category'
|
||||
|
||||
console.print_green('✓ Level 4: "Tutorials/Operations/Database/Optimization" found')
|
||||
|
||||
console.lf()
|
||||
|
||||
// ========================================================
|
||||
// TEST 2: Validate Pages Distribution
|
||||
// ========================================================
|
||||
console.print_header('TEST 2: Validate Pages Distribution')
|
||||
console.print_item('Total pages: ${nav_site.pages.len}')
|
||||
|
||||
mut pages_by_category := map[int]int{}
|
||||
for page in nav_site.pages {
|
||||
cat_id := page.category_id
|
||||
if cat_id !in pages_by_category {
|
||||
pages_by_category[cat_id] = 0
|
||||
}
|
||||
pages_by_category[cat_id]++
|
||||
}
|
||||
|
||||
console.print_debug('Pages per category:')
|
||||
for cat_id, count in pages_by_category {
|
||||
mut cat_name := 'Root (Uncategorized)'
|
||||
// category_id is 1-based, index is 0-based
|
||||
if cat_id > 0 && cat_id <= nav_site.categories.len {
|
||||
cat_name = nav_site.categories[cat_id - 1].path
|
||||
}
|
||||
console.print_debug(' Category ${cat_id} [${cat_name}]: ${count} pages')
|
||||
}
|
||||
|
||||
// Validate we have pages in multiple categories
|
||||
assert pages_by_category.len >= 5, 'Should have pages in at least 5 categories'
|
||||
console.print_green('✓ Pages distributed across multiple category levels')
|
||||
|
||||
console.lf()
|
||||
|
||||
// ========================================================
|
||||
// TEST 3: Validate Navigation Structure (Sidebar)
|
||||
// ========================================================
|
||||
console.print_header('TEST 3: Navigation Structure Analysis')
|
||||
|
||||
mut sidebar := nav_site.sidebar()
|
||||
console.print_item('Sidebar root items: ${sidebar.my_sidebar.len}')
|
||||
console.lf()
|
||||
|
||||
// Analyze structure
|
||||
mut stats := analyze_sidebar_structure(sidebar.my_sidebar)
|
||||
console.print_debug('Structure Analysis:')
|
||||
console.print_debug(' Total root items: ${stats.root_items}')
|
||||
console.print_debug(' Categories: ${stats.categories}')
|
||||
console.print_debug(' Pages: ${stats.pages}')
|
||||
console.print_debug(' Links: ${stats.links}')
|
||||
console.print_debug(' Max nesting depth: ${stats.max_depth}')
|
||||
|
||||
assert stats.categories >= 6, 'Should have at least 6 categories'
|
||||
console.print_green('✓ Multiple category levels present')
|
||||
|
||||
assert stats.max_depth >= 4, 'Should have nesting depth of at least 4 levels (0-indexed root, so 3+1)'
|
||||
console.print_green('✓ Deep nesting verified (depth: ${stats.max_depth})')
|
||||
|
||||
console.lf()
|
||||
|
||||
// ========================================================
|
||||
// TEST 4: Validate Specific Path Hierarchies
|
||||
// ========================================================
|
||||
console.print_header('TEST 4: Path Hierarchy Validation')
|
||||
|
||||
// Find categories and check parent-child relationships
|
||||
let_test_hierarchy(nav_site.categories)
|
||||
|
||||
console.lf()
|
||||
|
||||
// ========================================================
|
||||
// TEST 5: Print Sidebar Structure
|
||||
// ========================================================
|
||||
console.print_header('📑 COMPLETE SIDEBAR STRUCTURE')
|
||||
console.lf()
|
||||
println(nav_site.sidebar_str())
|
||||
|
||||
console.print_header('✅ All Navigation Depth Tests Passed!')
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Helper Structures
|
||||
// ============================================================
|
||||
|
||||
struct SidebarStats {
|
||||
pub mut:
|
||||
root_items int
|
||||
categories int
|
||||
pages int
|
||||
links int
|
||||
max_depth int // Max nesting depth including root as depth 1
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Helper Functions
|
||||
// ============================================================
|
||||
|
||||
fn calculate_category_depth(path string) int {
|
||||
if path.len == 0 {
|
||||
return 0 // Or handle as an error/special case
|
||||
}
|
||||
// Count slashes + 1 for the depth
|
||||
// "Why" -> 1
|
||||
// "Why/FAQ" -> 2
|
||||
return path.split('/').len
|
||||
}
|
||||
|
||||
fn analyze_sidebar_structure(items []NavItem) SidebarStats {
|
||||
mut stats := SidebarStats{}
|
||||
|
||||
stats.root_items = items.len
|
||||
|
||||
for item in items {
|
||||
// Start depth at 1 for top-level items
|
||||
if item is NavCat {
|
||||
stats.categories++
|
||||
depth := calculate_nav_item_depth(item, 1)
|
||||
if depth > stats.max_depth {
|
||||
stats.max_depth = depth
|
||||
}
|
||||
// Recursively count pages and categories
|
||||
stats.pages += count_nested_pages_in_navcat(item)
|
||||
stats.categories += count_nested_categories_in_navcat(item)
|
||||
} else if item is NavDoc {
|
||||
stats.pages++
|
||||
if 1 > stats.max_depth {
|
||||
stats.max_depth = 1
|
||||
}
|
||||
} else if item is NavLink {
|
||||
stats.links++
|
||||
if 1 > stats.max_depth {
|
||||
stats.max_depth = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return stats
|
||||
}
|
||||
|
||||
fn calculate_nav_item_depth(item NavItem, current_depth int) int {
|
||||
mut max_depth_in_branch := current_depth
|
||||
|
||||
if item is NavCat {
|
||||
for sub_item in item.items {
|
||||
depth := calculate_nav_item_depth(sub_item, current_depth + 1)
|
||||
if depth > max_depth_in_branch {
|
||||
max_depth_in_branch = depth
|
||||
}
|
||||
}
|
||||
}
|
||||
// NavDoc and NavLink are leaf nodes, their depth is current_depth
|
||||
return max_depth_in_branch
|
||||
}
|
||||
|
||||
fn count_nested_pages_in_navcat(cat NavCat) int {
|
||||
mut count := 0
|
||||
for item in cat.items {
|
||||
if item is NavDoc {
|
||||
count++
|
||||
} else if item is NavCat {
|
||||
count += count_nested_pages_in_navcat(item)
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
fn count_nested_categories_in_navcat(cat NavCat) int {
|
||||
mut count := 0
|
||||
for item in cat.items {
|
||||
if item is NavCat {
|
||||
count++
|
||||
count += count_nested_categories_in_navcat(item)
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
fn let_test_hierarchy(categories []Category) {
|
||||
console.print_item('Validating path hierarchies:')
|
||||
|
||||
// Group by depth
|
||||
mut by_depth := map[int][]string{}
|
||||
for category in categories {
|
||||
depth := calculate_category_depth(category.path)
|
||||
if depth !in by_depth {
|
||||
by_depth[depth] = []string{}
|
||||
}
|
||||
by_depth[depth] << category.path
|
||||
}
|
||||
|
||||
// Print organized by depth
|
||||
// Assuming max depth is 4 based on the script
|
||||
for depth := 1; depth <= 4; depth++ {
|
||||
if depth in by_depth {
|
||||
console.print_debug(' Depth ${depth}:')
|
||||
for path in by_depth[depth] {
|
||||
console.print_debug(' └─ ${path}')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Validate specific hierarchies
|
||||
mut all_paths := categories.map(it.path)
|
||||
|
||||
// Hierarchy: Why -> Why/FAQ
|
||||
if all_paths.contains('Why') && all_paths.contains('Why/FAQ') {
|
||||
console.print_green('✓ Hierarchy verified: Why → Why/FAQ')
|
||||
}
|
||||
|
||||
// Hierarchy: Tutorials -> Tutorials/Operations -> Tutorials/Operations/Urgent
|
||||
if all_paths.contains('Tutorials') && all_paths.contains('Tutorials/Operations')
|
||||
&& all_paths.contains('Tutorials/Operations/Urgent') {
|
||||
console.print_green('✓ Hierarchy verified: Tutorials → Operations → Urgent')
|
||||
}
|
||||
|
||||
// Hierarchy: Tutorials/Operations -> Tutorials/Operations/Database -> Tutorials/Operations/Database/Optimization
|
||||
if all_paths.contains('Tutorials/Operations/Database')
|
||||
&& all_paths.contains('Tutorials/Operations/Database/Optimization') {
|
||||
console.print_green('✓ Hierarchy verified: Operations → Database → Optimization')
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user