wails/v3/pkg/application/dialogs_test.go
Lea Anthony 2604ecc0f8
test(v3): add comprehensive unit tests for pkg/application (#4827)
* test(v3): add comprehensive unit tests for pkg/application

Add 11 new test files to improve test coverage of the pkg/application
package from 13.6% to 17.7%.

New test files:
- context_test.go: Context struct operations
- services_test.go: Service management and lifecycle
- parameter_test.go: Parameter and CallError types
- dialogs_test.go: Dialog utilities and button methods
- webview_window_options_test.go: Window options and constants
- application_options_test.go: ChainMiddleware and app config
- keys_test.go: Keyboard accelerator parsing
- single_instance_test.go: Single instance management and encryption
- menuitem_internal_test.go: Menu item internal functions
- menu_internal_test.go: Menu internal functions
- screenmanager_internal_test.go: Screen geometry and transformations

The 40% target was not fully achievable because ~50% of the codebase
is platform-specific code that can only be tested on respective
platforms. Tests focus on pure Go logic, utility functions, and
data structures that can be tested cross-platform.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: address CodeRabbit review comments

- dialogs_test.go: improve ID recycling test to verify either recycled
  ID (id3 == id1) or new unique ID (id3 > id2)
- keys_test.go: make accelerator String() tests platform-agnostic by
  checking suffix patterns rather than exact platform-specific strings

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: normalize temp dir path for macOS compatibility in test

os.TempDir() returns a trailing slash on macOS, causing path comparison
to fail. Use filepath.Clean() to normalize both paths.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: remove REVIEW.md

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* chore: simplify changelog entry

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 09:53:24 +11:00

223 lines
5.1 KiB
Go

package application
import (
"testing"
)
func TestGetDialogID(t *testing.T) {
// Get first dialog ID
id1 := getDialogID()
// Get second dialog ID - should be different
id2 := getDialogID()
if id1 == id2 {
t.Error("getDialogID should return unique IDs")
}
// Free first ID
freeDialogID(id1)
// Get another ID - should recycle the freed id1 or be unique from id2
id3 := getDialogID()
if id3 == id2 {
t.Error("getDialogID should not return the same ID as an active dialog")
}
// Verify recycling behavior: id3 should either be id1 (recycled) or a new unique ID
if id3 != id1 && id3 <= id2 {
t.Errorf("getDialogID returned unexpected ID: got %d, expected recycled %d or new > %d", id3, id1, id2)
}
// Cleanup
freeDialogID(id2)
freeDialogID(id3)
}
func TestFreeDialogID(t *testing.T) {
id := getDialogID()
freeDialogID(id)
// Should be able to get the same ID again after freeing
newID := getDialogID()
freeDialogID(newID)
// Just verify it doesn't panic
}
func TestButton_OnClick(t *testing.T) {
button := &Button{Label: "Test"}
called := false
result := button.OnClick(func() {
called = true
})
// Should return the same button for chaining
if result != button {
t.Error("OnClick should return the same button")
}
// Callback should be set
if button.Callback == nil {
t.Error("Callback should be set")
}
// Call the callback
button.Callback()
if !called {
t.Error("Callback should have been called")
}
}
func TestButton_SetAsDefault(t *testing.T) {
button := &Button{Label: "Test"}
result := button.SetAsDefault()
// Should return the same button for chaining
if result != button {
t.Error("SetAsDefault should return the same button")
}
if !button.IsDefault {
t.Error("IsDefault should be true")
}
}
func TestButton_SetAsCancel(t *testing.T) {
button := &Button{Label: "Test"}
result := button.SetAsCancel()
// Should return the same button for chaining
if result != button {
t.Error("SetAsCancel should return the same button")
}
if !button.IsCancel {
t.Error("IsCancel should be true")
}
}
func TestButton_Chaining(t *testing.T) {
button := &Button{Label: "OK"}
button.SetAsDefault().SetAsCancel().OnClick(func() {})
if !button.IsDefault {
t.Error("IsDefault should be true after chaining")
}
if !button.IsCancel {
t.Error("IsCancel should be true after chaining")
}
if button.Callback == nil {
t.Error("Callback should be set after chaining")
}
}
func TestDialogType_Constants(t *testing.T) {
// Verify dialog type constants are distinct
types := []DialogType{InfoDialogType, QuestionDialogType, WarningDialogType, ErrorDialogType}
seen := make(map[DialogType]bool)
for _, dt := range types {
if seen[dt] {
t.Errorf("DialogType %d is duplicated", dt)
}
seen[dt] = true
}
}
func TestMessageDialogOptions_Fields(t *testing.T) {
opts := MessageDialogOptions{
DialogType: InfoDialogType,
Title: "Test Title",
Message: "Test Message",
Buttons: []*Button{{Label: "OK"}},
Icon: []byte{1, 2, 3},
}
if opts.DialogType != InfoDialogType {
t.Error("DialogType not set correctly")
}
if opts.Title != "Test Title" {
t.Error("Title not set correctly")
}
if opts.Message != "Test Message" {
t.Error("Message not set correctly")
}
if len(opts.Buttons) != 1 {
t.Error("Buttons not set correctly")
}
if len(opts.Icon) != 3 {
t.Error("Icon not set correctly")
}
}
func TestFileFilter_Fields(t *testing.T) {
filter := FileFilter{
DisplayName: "Image Files (*.jpg, *.png)",
Pattern: "*.jpg;*.png",
}
if filter.DisplayName != "Image Files (*.jpg, *.png)" {
t.Error("DisplayName not set correctly")
}
if filter.Pattern != "*.jpg;*.png" {
t.Error("Pattern not set correctly")
}
}
func TestOpenFileDialogOptions_Fields(t *testing.T) {
opts := OpenFileDialogOptions{
CanChooseDirectories: true,
CanChooseFiles: true,
CanCreateDirectories: true,
ShowHiddenFiles: true,
ResolvesAliases: true,
AllowsMultipleSelection: true,
Title: "Open",
Message: "Select a file",
ButtonText: "Choose",
Directory: "/home",
Filters: []FileFilter{
{DisplayName: "All Files", Pattern: "*"},
},
}
if !opts.CanChooseDirectories {
t.Error("CanChooseDirectories not set correctly")
}
if !opts.CanChooseFiles {
t.Error("CanChooseFiles not set correctly")
}
if opts.Title != "Open" {
t.Error("Title not set correctly")
}
if len(opts.Filters) != 1 {
t.Error("Filters not set correctly")
}
}
func TestSaveFileDialogOptions_Fields(t *testing.T) {
opts := SaveFileDialogOptions{
CanCreateDirectories: true,
ShowHiddenFiles: true,
Title: "Save",
Message: "Save as",
Directory: "/home",
Filename: "file.txt",
ButtonText: "Save",
Filters: []FileFilter{
{DisplayName: "Text Files", Pattern: "*.txt"},
},
}
if !opts.CanCreateDirectories {
t.Error("CanCreateDirectories not set correctly")
}
if opts.Title != "Save" {
t.Error("Title not set correctly")
}
if opts.Filename != "file.txt" {
t.Error("Filename not set correctly")
}
}