1// +build windows
2
3package systray
4
5import (
6	"io/ioutil"
7	"runtime"
8	"sync/atomic"
9	"testing"
10	"time"
11	"unsafe"
12
13	"golang.org/x/sys/windows"
14)
15
16const iconFilePath = "example/icon/iconwin.ico"
17
18func TestBaseWindowsTray(t *testing.T) {
19	systrayReady = func() {}
20	systrayExit = func() {}
21
22	runtime.LockOSThread()
23
24	if err := wt.initInstance(); err != nil {
25		t.Fatalf("initInstance failed: %s", err)
26	}
27
28	if err := wt.createMenu(); err != nil {
29		t.Fatalf("createMenu failed: %s", err)
30	}
31
32	defer func() {
33		pDestroyWindow.Call(uintptr(wt.window))
34		wt.wcex.unregister()
35	}()
36
37	if err := wt.setIcon(iconFilePath); err != nil {
38		t.Errorf("SetIcon failed: %s", err)
39	}
40
41	if err := wt.setTooltip("Cyrillic tooltip тест:)"); err != nil {
42		t.Errorf("SetIcon failed: %s", err)
43	}
44
45	var id int32 = 0
46	err := wt.addOrUpdateMenuItem(atomic.AddInt32(&id, 1), "Simple enabled", false, false)
47	if err != nil {
48		t.Errorf("mergeMenuItem failed: %s", err)
49	}
50	err = wt.addOrUpdateMenuItem(atomic.AddInt32(&id, 1), "Simple disabled", true, false)
51	if err != nil {
52		t.Errorf("mergeMenuItem failed: %s", err)
53	}
54	err = wt.addSeparatorMenuItem(atomic.AddInt32(&id, 1))
55	if err != nil {
56		t.Errorf("addSeparatorMenuItem failed: %s", err)
57	}
58	err = wt.addOrUpdateMenuItem(atomic.AddInt32(&id, 1), "Simple checked enabled", false, true)
59	if err != nil {
60		t.Errorf("mergeMenuItem failed: %s", err)
61	}
62	err = wt.addOrUpdateMenuItem(atomic.AddInt32(&id, 1), "Simple checked disabled", true, true)
63	if err != nil {
64		t.Errorf("mergeMenuItem failed: %s", err)
65	}
66
67	err = wt.hideMenuItem(1)
68	if err != nil {
69		t.Errorf("hideMenuItem failed: %s", err)
70	}
71
72	err = wt.hideMenuItem(100)
73	if err == nil {
74		t.Error("hideMenuItem failed: must return error on invalid item id")
75	}
76
77	err = wt.addOrUpdateMenuItem(2, "Simple disabled update", true, false)
78	if err != nil {
79		t.Errorf("mergeMenuItem failed: %s", err)
80	}
81
82	time.AfterFunc(1*time.Second, quit)
83
84	m := struct {
85		WindowHandle windows.Handle
86		Message      uint32
87		Wparam       uintptr
88		Lparam       uintptr
89		Time         uint32
90		Pt           point
91	}{}
92	for {
93		ret, _, err := pGetMessage.Call(uintptr(unsafe.Pointer(&m)), 0, 0, 0)
94		res := int32(ret)
95		if res == -1 {
96			t.Errorf("win32 GetMessage failed: %v", err)
97			return
98		} else if res == 0 {
99			break
100		}
101		pTranslateMessage.Call(uintptr(unsafe.Pointer(&m)))
102		pDispatchMessage.Call(uintptr(unsafe.Pointer(&m)))
103	}
104}
105
106func TestWindowsRun(t *testing.T) {
107	onReady := func() {
108		b, err := ioutil.ReadFile(iconFilePath)
109		if err != nil {
110			t.Fatalf("Can't load icon file: %v", err)
111		}
112		SetIcon(b)
113		SetTitle("Test title с кириллицей")
114
115		bSomeBtn := AddMenuItem("Йа кнопко", "")
116		bSomeBtn.Check()
117		AddSeparator()
118		bQuit := AddMenuItem("Quit", "Quit the whole app")
119		go func() {
120			<-bQuit.ClickedCh
121			t.Log("Quit reqested")
122			Quit()
123		}()
124		time.AfterFunc(1*time.Second, Quit)
125	}
126
127	onExit := func() {
128		t.Log("Exit success")
129	}
130
131	Run(onReady, onExit)
132}
133