mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-03 06:39:30 +08:00
298 lines
7.4 KiB
Go
298 lines
7.4 KiB
Go
//go:build windows
|
|
|
|
package menu_test
|
|
|
|
import (
|
|
"github.com/stretchr/testify/require"
|
|
platformMenu "github.com/wailsapp/wails/v2/internal/platform/menu"
|
|
"github.com/wailsapp/wails/v2/pkg/menu"
|
|
"testing"
|
|
)
|
|
|
|
func TestManager_ProcessClick_Checkbox(t *testing.T) {
|
|
|
|
checkbox := menu.Label("Checkbox").SetChecked(false)
|
|
menu1 := &menu.Menu{
|
|
Items: []*menu.MenuItem{
|
|
checkbox,
|
|
},
|
|
}
|
|
menu2 := &menu.Menu{
|
|
Items: []*menu.MenuItem{
|
|
checkbox,
|
|
},
|
|
}
|
|
menuWithNoCheckbox := &menu.Menu{
|
|
Items: []*menu.MenuItem{
|
|
menu.Label("No Checkbox"),
|
|
},
|
|
}
|
|
clicked := false
|
|
|
|
tests := []struct {
|
|
name string
|
|
inputs []*menu.Menu
|
|
startState bool
|
|
expectedState bool
|
|
expectedMenuUpdates map[*menu.Menu][]*menu.MenuItem
|
|
click func(*menu.CallbackData)
|
|
}{
|
|
{
|
|
name: "should callback menu checkbox state when clicked (false -> true)",
|
|
inputs: []*menu.Menu{menu1},
|
|
expectedMenuUpdates: map[*menu.Menu][]*menu.MenuItem{
|
|
menu1: {checkbox},
|
|
},
|
|
startState: false,
|
|
expectedState: true,
|
|
},
|
|
{
|
|
name: "should callback multiple menus when checkbox state when clicked (false -> true)",
|
|
inputs: []*menu.Menu{menu1, menu2},
|
|
startState: false,
|
|
expectedState: true,
|
|
expectedMenuUpdates: map[*menu.Menu][]*menu.MenuItem{
|
|
menu1: {checkbox},
|
|
menu2: {checkbox},
|
|
},
|
|
},
|
|
{
|
|
name: "should callback only for the menus that the checkbox is in (false -> true)",
|
|
inputs: []*menu.Menu{menu1, menuWithNoCheckbox},
|
|
startState: false,
|
|
expectedState: true,
|
|
expectedMenuUpdates: map[*menu.Menu][]*menu.MenuItem{
|
|
menu1: {checkbox},
|
|
},
|
|
},
|
|
{
|
|
name: "should callback menu checkbox state when clicked (true->false)",
|
|
inputs: []*menu.Menu{menu1},
|
|
expectedMenuUpdates: map[*menu.Menu][]*menu.MenuItem{
|
|
menu1: {checkbox},
|
|
},
|
|
startState: true,
|
|
expectedState: false,
|
|
},
|
|
{
|
|
name: "should callback multiple menus when checkbox state when clicked (true->false)",
|
|
inputs: []*menu.Menu{menu1, menu2},
|
|
startState: true,
|
|
expectedState: false,
|
|
expectedMenuUpdates: map[*menu.Menu][]*menu.MenuItem{
|
|
menu1: {checkbox},
|
|
menu2: {checkbox},
|
|
},
|
|
},
|
|
{
|
|
name: "should callback only for the menus that the checkbox is in (true->false)",
|
|
inputs: []*menu.Menu{menu1, menuWithNoCheckbox},
|
|
startState: true,
|
|
expectedState: false,
|
|
expectedMenuUpdates: map[*menu.Menu][]*menu.MenuItem{
|
|
menu1: {checkbox},
|
|
},
|
|
},
|
|
{
|
|
name: "should callback no menus if checkbox not in them",
|
|
inputs: []*menu.Menu{menuWithNoCheckbox},
|
|
startState: false,
|
|
expectedState: false,
|
|
expectedMenuUpdates: nil,
|
|
},
|
|
{
|
|
name: "should call Click on the checkbox",
|
|
inputs: []*menu.Menu{menu1, menu2},
|
|
startState: false,
|
|
expectedState: true,
|
|
expectedMenuUpdates: map[*menu.Menu][]*menu.MenuItem{
|
|
menu1: {checkbox},
|
|
menu2: {checkbox},
|
|
},
|
|
click: func(data *menu.CallbackData) {
|
|
clicked = true
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
|
|
menusUpdated := map[*menu.Menu][]*menu.MenuItem{}
|
|
clicked = false
|
|
|
|
var checkMenuItemStateInMenu func(menu *menu.Menu)
|
|
|
|
checkMenuItemStateInMenu = func(menu *menu.Menu) {
|
|
for _, item := range menusUpdated[menu] {
|
|
if item == checkbox {
|
|
require.Equal(t, tt.expectedState, item.Checked)
|
|
}
|
|
if item.SubMenu != nil {
|
|
checkMenuItemStateInMenu(item.SubMenu)
|
|
}
|
|
}
|
|
}
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
m := platformMenu.NewManager()
|
|
checkbox.SetChecked(tt.startState)
|
|
checkbox.Click = tt.click
|
|
for _, thisMenu := range tt.inputs {
|
|
thisMenu := thisMenu
|
|
m.AddMenu(thisMenu, func(menuItem *menu.MenuItem) {
|
|
menusUpdated[thisMenu] = append(menusUpdated[thisMenu], menuItem)
|
|
})
|
|
}
|
|
m.ProcessClick(checkbox)
|
|
|
|
// Check the item has the correct state in all the menus
|
|
for thisMenu := range menusUpdated {
|
|
require.EqualValues(t, tt.expectedMenuUpdates[thisMenu], menusUpdated[thisMenu])
|
|
}
|
|
|
|
if tt.click != nil {
|
|
require.Equal(t, true, clicked)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestManager_ProcessClick_RadioGroups(t *testing.T) {
|
|
|
|
radio1 := menu.Radio("Radio1", false, nil, nil)
|
|
radio2 := menu.Radio("Radio2", false, nil, nil)
|
|
radio3 := menu.Radio("Radio3", false, nil, nil)
|
|
radio4 := menu.Radio("Radio4", false, nil, nil)
|
|
radio5 := menu.Radio("Radio5", false, nil, nil)
|
|
radio6 := menu.Radio("Radio6", false, nil, nil)
|
|
|
|
radioGroupOne := &menu.Menu{
|
|
Items: []*menu.MenuItem{
|
|
radio1,
|
|
radio2,
|
|
radio3,
|
|
},
|
|
}
|
|
|
|
radioGroupTwo := &menu.Menu{
|
|
Items: []*menu.MenuItem{
|
|
radio4,
|
|
radio5,
|
|
radio6,
|
|
},
|
|
}
|
|
|
|
radioGroupThree := &menu.Menu{
|
|
Items: []*menu.MenuItem{
|
|
radio1,
|
|
radio2,
|
|
radio3,
|
|
},
|
|
}
|
|
|
|
clicked := false
|
|
|
|
tests := []struct {
|
|
name string
|
|
inputs []*menu.Menu
|
|
startState map[*menu.MenuItem]bool
|
|
selected *menu.MenuItem
|
|
expectedMenuUpdates map[*menu.Menu][]*menu.MenuItem
|
|
click func(*menu.CallbackData)
|
|
expectedState map[*menu.MenuItem]bool
|
|
}{
|
|
{
|
|
name: "should only set the clicked radio item",
|
|
inputs: []*menu.Menu{radioGroupOne},
|
|
expectedMenuUpdates: map[*menu.Menu][]*menu.MenuItem{
|
|
radioGroupOne: {radio1, radio2, radio3},
|
|
},
|
|
startState: map[*menu.MenuItem]bool{
|
|
radio1: true,
|
|
radio2: false,
|
|
radio3: false,
|
|
},
|
|
selected: radio2,
|
|
expectedState: map[*menu.MenuItem]bool{
|
|
radio1: false,
|
|
radio2: true,
|
|
radio3: false,
|
|
},
|
|
},
|
|
{
|
|
name: "should not affect other radio groups or menus",
|
|
inputs: []*menu.Menu{radioGroupOne, radioGroupTwo},
|
|
expectedMenuUpdates: map[*menu.Menu][]*menu.MenuItem{
|
|
radioGroupOne: {radio1, radio2, radio3},
|
|
},
|
|
startState: map[*menu.MenuItem]bool{
|
|
radio1: true,
|
|
radio2: false,
|
|
radio3: false,
|
|
radio4: true,
|
|
radio5: false,
|
|
radio6: false,
|
|
},
|
|
selected: radio2,
|
|
expectedState: map[*menu.MenuItem]bool{
|
|
radio1: false,
|
|
radio2: true,
|
|
radio3: false,
|
|
radio4: true,
|
|
radio5: false,
|
|
radio6: false,
|
|
},
|
|
},
|
|
{
|
|
name: "menus with the same radio group should be updated",
|
|
inputs: []*menu.Menu{radioGroupOne, radioGroupThree},
|
|
expectedMenuUpdates: map[*menu.Menu][]*menu.MenuItem{
|
|
radioGroupOne: {radio1, radio2, radio3},
|
|
radioGroupThree: {radio1, radio2, radio3},
|
|
},
|
|
startState: map[*menu.MenuItem]bool{
|
|
radio1: true,
|
|
radio2: false,
|
|
radio3: false,
|
|
},
|
|
selected: radio2,
|
|
expectedState: map[*menu.MenuItem]bool{
|
|
radio1: false,
|
|
radio2: true,
|
|
radio3: false,
|
|
},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
|
|
menusUpdated := map[*menu.Menu][]*menu.MenuItem{}
|
|
clicked = false
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
m := platformMenu.NewManager()
|
|
|
|
for item, value := range tt.startState {
|
|
item.SetChecked(value)
|
|
}
|
|
|
|
tt.selected.Click = tt.click
|
|
for _, thisMenu := range tt.inputs {
|
|
thisMenu := thisMenu
|
|
m.AddMenu(thisMenu, func(menuItem *menu.MenuItem) {
|
|
menusUpdated[thisMenu] = append(menusUpdated[thisMenu], menuItem)
|
|
})
|
|
}
|
|
m.ProcessClick(tt.selected)
|
|
require.Equal(t, tt.expectedMenuUpdates, menusUpdated)
|
|
|
|
// Check the items have the correct state in all the menus
|
|
for item, expectedValue := range tt.expectedState {
|
|
require.Equal(t, expectedValue, item.Checked)
|
|
}
|
|
|
|
if tt.click != nil {
|
|
require.Equal(t, true, clicked)
|
|
}
|
|
})
|
|
}
|
|
}
|