feat: Menu items get sorted by weight.

This commit is contained in:
Spencer Brower
2026-07-29 12:38:12 -04:00
parent fa8179c9b9
commit 040c462bba
3 changed files with 120 additions and 18 deletions
+78 -5
View File
@@ -16,7 +16,6 @@ parse_raw :: proc(s: string) -> json.Value {
}
@(test)
test_menus_string_form :: proc(t: ^testing.T) {
arena: mem.Dynamic_Arena
@@ -31,7 +30,7 @@ test_menus_string_form :: proc(t: ^testing.T) {
testing.expect(t, ok, "expected 'main' menu")
testing.expect_value(t, entry.name, "About")
testing.expect_value(t, entry.url, "/about/")
testing.expect_value(t, entry.weight, 0)
testing.expect_value(t, entry.weight, DEFAULT_WEIGHT)
}
@(test)
@@ -82,7 +81,7 @@ test_menus_object_no_weight :: proc(t: ^testing.T) {
testing.expect(t, len(menus) == 1)
entry, ok := menus["main"]
testing.expect(t, ok)
testing.expect_value(t, entry.weight, 0)
testing.expect_value(t, entry.weight, DEFAULT_WEIGHT)
}
@(test)
@@ -140,7 +139,7 @@ test_menus_object_non_object_value :: proc(t: ^testing.T) {
testing.expect(t, len(menus) == 1, "entry created with defaults")
entry, ok := menus["main"]
testing.expect(t, ok)
testing.expect_value(t, entry.weight, 0)
testing.expect_value(t, entry.weight, DEFAULT_WEIGHT)
}
@(test)
@@ -155,7 +154,7 @@ test_menus_non_numeric_weight :: proc(t: ^testing.T) {
menus := parse_page_menus(parse_raw(`{"main": {"weight": "30"}}`), page, context.allocator)
entry, ok := menus["main"]
testing.expect(t, ok)
testing.expect_value(t, entry.weight, 0)
testing.expect_value(t, entry.weight, DEFAULT_WEIGHT)
}
@(test)
@@ -199,3 +198,77 @@ test_menus_null_json :: proc(t: ^testing.T) {
menus := parse_page_menus(parse_raw(`null`), page, context.allocator)
testing.expect(t, menus == nil, "null JSON should return nil")
}
// --- sort_menu_entries tests ---
@(test)
test_sort_weight_orders_correctly :: proc(t: ^testing.T) {
entries := []Menu_Entry {
{name = "Zeta", url = "/z/", weight = DEFAULT_WEIGHT},
{name = "Alpha", url = "/a/", weight = 5},
{name = "Beta", url = "/b/", weight = 1},
}
sort_menu_entries(entries)
// weight 1 first, then weight 5, then default weight 10
testing.expect_value(t, entries[0].name, "Beta")
testing.expect_value(t, entries[1].name, "Alpha")
testing.expect_value(t, entries[2].name, "Zeta")
}
@(test)
test_sort_equal_weights_alphabetical :: proc(t: ^testing.T) {
entries := []Menu_Entry {
{name = "Zebra", url = "/z/", weight = DEFAULT_WEIGHT},
{name = "Apple", url = "/a/", weight = DEFAULT_WEIGHT},
{name = "Mango", url = "/m/", weight = DEFAULT_WEIGHT},
}
sort_menu_entries(entries)
testing.expect_value(t, entries[0].name, "Apple")
testing.expect_value(t, entries[1].name, "Mango")
testing.expect_value(t, entries[2].name, "Zebra")
}
@(test)
test_sort_mixed_weights :: proc(t: ^testing.T) {
entries := []Menu_Entry {
{name = "Charlie", url = "/c/", weight = DEFAULT_WEIGHT},
{name = "Alpha", url = "/a/", weight = DEFAULT_WEIGHT},
{name = "Bravo", url = "/b/", weight = 3},
{name = "Delta", url = "/d/", weight = 1},
}
sort_menu_entries(entries)
// weight 1 (Delta), weight 3 (Bravo), then default weight alphabetical (Alpha, Charlie)
testing.expect_value(t, entries[0].name, "Delta")
testing.expect_value(t, entries[1].name, "Bravo")
testing.expect_value(t, entries[2].name, "Alpha")
testing.expect_value(t, entries[3].name, "Charlie")
}
@(test)
test_config_weight_parsing_and_sort :: proc(t: ^testing.T) {
arena: mem.Dynamic_Arena
mem.dynamic_arena_init(&arena)
defer mem.dynamic_arena_destroy(&arena)
context.allocator = mem.dynamic_arena_allocator(&arena)
raw := parse_raw(
`{
"main": [
{"name": "Heavy", "url": "/h/", "weight": 20},
{"name": "Light", "url": "/l/", "weight": 1},
{"name": "Default", "url": "/d/"}
]
}`,
)
menus := parse_config_menus(raw, context.allocator)
main, ok := menus["main"]
testing.expect(t, ok)
testing.expect(t, len(main) == 3)
testing.expect_value(t, main[0].name, "Light")
testing.expect_value(t, main[0].weight, 1)
testing.expect_value(t, main[1].name, "Default")
testing.expect_value(t, main[1].weight, DEFAULT_WEIGHT)
testing.expect_value(t, main[2].name, "Heavy")
testing.expect_value(t, main[2].weight, 20)
}