Add window icons, tests.

This commit is contained in:
Nuno Cruces 2022-05-18 14:48:09 +01:00
parent 15547b2097
commit 61a5cfeeb5
20 changed files with 160 additions and 38 deletions

View File

@ -50,6 +50,7 @@ var (
extraButton string
text string
icon string
windowIcon string
multiple bool
defaultCancel bool
@ -207,7 +208,7 @@ func setupFlags() {
flag.StringVar(&cancelLabel, "cancel-label", "", "Set the `label` of the Cancel button")
flag.Func("extra-button", "Add an extra `button`", setExtraButton)
flag.StringVar(&text, "text", "", "Set the dialog `text`")
flag.StringVar(&icon, "window-icon", "", "Set the window `icon` (error, info, question, warning)")
flag.StringVar(&windowIcon, "window-icon", "", "Set the window `icon` (error, info, question, warning)")
flag.BoolVar(&multiple, "multiple", false, "Allow multiple items to be selected")
flag.BoolVar(&defaultCancel, "default-cancel", false, "Give Cancel button focus by default")
@ -277,6 +278,7 @@ func setupFlags() {
extraButton = unspecified
text = unspecified
icon = unspecified
windowIcon = unspecified
}
func validateFlags() {

View File

@ -26,6 +26,10 @@ func ExampleSelectColor_palette() {
}
func TestSelectColor_timeout(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}
defer goleak.VerifyNone(t)
ctx, cancel := context.WithTimeout(context.Background(), time.Second/5)
defer cancel()
@ -54,6 +58,10 @@ func TestSelectColor_cancel(t *testing.T) {
}
func TestSelectColor_script(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}
tests := []struct {
name string
call string

View File

@ -15,10 +15,13 @@ import (
func ExampleCalendar() {
zenity.Calendar("Select a date from below:",
zenity.DefaultDate(2006, time.January, 1))
// Output:
}
func TestCalendar_timeout(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}
defer goleak.VerifyNone(t)
ctx, cancel := context.WithTimeout(context.Background(), time.Second/5)
defer cancel()
@ -47,6 +50,10 @@ func TestCalendar_cancel(t *testing.T) {
}
func TestCalendar_script(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}
tests := []struct {
name string
call string

View File

@ -14,7 +14,7 @@ func calendar(text string, opts options) (time.Time, error) {
args = appendTitle(args, opts)
args = appendButtons(args, opts)
args = appendWidthHeight(args, opts)
args = appendIcon(args, opts)
args = appendWindowIcon(args, opts)
if opts.time != nil {
year, month, day := opts.time.Date()
args = append(args, "--month", strconv.Itoa(int(month)))

View File

@ -18,6 +18,10 @@ func ExampleEntry() {
}
func TestEntry_timeout(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}
defer goleak.VerifyNone(t)
ctx, cancel := context.WithTimeout(context.Background(), time.Second/5)
defer cancel()
@ -46,6 +50,10 @@ func TestEntry_cancel(t *testing.T) {
}
func TestEntry_script(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}
tests := []struct {
name string
call string

View File

@ -11,7 +11,7 @@ func entry(text string, opts options) (string, error) {
args = appendTitle(args, opts)
args = appendButtons(args, opts)
args = appendWidthHeight(args, opts)
args = appendIcon(args, opts)
args = appendWindowIcon(args, opts)
if opts.entryText != "" {
args = append(args, "--entry-text", opts.entryText)
}

View File

@ -79,6 +79,10 @@ var fileFuncs = []struct {
}
func TestSelectFile_timeout(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}
for _, tt := range fileFuncs {
t.Run(tt.name, func(t *testing.T) {
defer goleak.VerifyNone(t)
@ -115,6 +119,9 @@ func TestSelectFile_cancel(t *testing.T) {
}
func TestSelectFile_script(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}
t.Run("Cancel", func(t *testing.T) {
zenity.Info(fmt.Sprintf("In the file selection dialog, cancel."))
str, err := zenity.SelectFile()
@ -156,6 +163,9 @@ func TestSelectFile_script(t *testing.T) {
}
func TestSelectFileMutiple_script(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}
t.Run("Cancel", func(t *testing.T) {
zenity.Info(fmt.Sprintf("In the file selection dialog, cancel."))
lst, err := zenity.SelectFileMutiple()
@ -204,6 +214,9 @@ func TestSelectFileMutiple_script(t *testing.T) {
}
func TestSelectFileSave_script(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}
t.Run("Cancel", func(t *testing.T) {
zenity.Info(fmt.Sprintf("In the file save dialog, cancel."))
str, err := zenity.SelectFileSave()

View File

@ -44,6 +44,10 @@ func ExampleListMultipleItems() {
}
func TestList_timeout(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}
defer goleak.VerifyNone(t)
ctx, cancel := context.WithTimeout(context.Background(), time.Second/5)
defer cancel()
@ -72,6 +76,10 @@ func TestList_cancel(t *testing.T) {
}
func TestList_script(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}
items := []string{"apples", "oranges", "bananas", "strawberries"}
tests := []struct {
name string
@ -96,6 +104,10 @@ func TestList_script(t *testing.T) {
}
func TestListMultiple_script(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}
items := []string{"apples", "oranges", "bananas", "strawberries"}
tests := []struct {
name string

View File

@ -9,7 +9,7 @@ func list(text string, items []string, opts options) (string, error) {
args = appendTitle(args, opts)
args = appendButtons(args, opts)
args = appendWidthHeight(args, opts)
args = appendIcon(args, opts)
args = appendWindowIcon(args, opts)
args = append(args, items...)
out, err := zenutil.Run(opts.ctx, args)
@ -21,7 +21,7 @@ func listMultiple(text string, items []string, opts options) ([]string, error) {
args = appendTitle(args, opts)
args = appendButtons(args, opts)
args = appendWidthHeight(args, opts)
args = appendIcon(args, opts)
args = appendWindowIcon(args, opts)
args = append(args, items...)
out, err := zenutil.Run(opts.ctx, args)

View File

@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"os"
"runtime"
"testing"
"time"
@ -16,35 +17,24 @@ func ExampleError() {
zenity.Error("An error has occurred.",
zenity.Title("Error"),
zenity.ErrorIcon)
// Output:
}
func ExampleInfo() {
zenity.Info("All updates are complete.",
zenity.Title("Information"),
zenity.InfoIcon)
// Output:
}
func ExampleWarning() {
zenity.Warning("Are you sure you want to proceed?",
zenity.Title("Warning"),
zenity.WarningIcon)
// Output:
}
func ExampleQuestion() {
zenity.Question("Are you sure you want to proceed?",
zenity.Title("Question"),
zenity.QuestionIcon)
// Output:
}
func ExampleIcon_custom() {
zenity.Info("All updates are complete.",
zenity.Title("Information"),
zenity.Icon("testdata/icon.png"))
// Output:
}
var msgFuncs = []struct {
@ -58,6 +48,10 @@ var msgFuncs = []struct {
}
func TestMessage_timeout(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}
for _, tt := range msgFuncs {
t.Run(tt.name, func(t *testing.T) {
defer goleak.VerifyNone(t)
@ -94,6 +88,10 @@ func TestMessage_cancel(t *testing.T) {
}
func TestMessage_script(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}
for _, tt := range msgFuncs {
t.Run(tt.name+"OK", func(t *testing.T) {
err := tt.fn("Please, press OK.", zenity.OKLabel("OK"))
@ -134,12 +132,47 @@ func TestMessage_script(t *testing.T) {
t.Skip("skipping:", err)
}
if err != tt.err {
t.Errorf("Questtion() = %v; want %v", err, tt.err)
t.Errorf("Question() = %v; want %v", err, tt.err)
}
})
}
}
func TestMessage_icon(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}
err := zenity.Question("Does this dialog have an error icon?",
zenity.OKLabel("Yes"),
zenity.CancelLabel("No"),
zenity.ErrorIcon)
if skip, err := skip(err); skip {
t.Skip("skipping:", err)
}
if err != nil {
t.Errorf("Question() = %v; want nil", err)
}
}
func TestMessage_customIcon(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}
err := zenity.Question("Does this dialog have a custom icon?",
zenity.Title(""),
zenity.OKLabel("Yes"),
zenity.CancelLabel("No"),
zenity.Icon("testdata/icon.png"))
if skip, err := skip(err); skip {
t.Skip("skipping:", err)
}
if err != nil && (runtime.GOOS == "windows" || runtime.GOOS == "darwin") {
t.Errorf("Question() = %v; want nil", err)
}
}
func TestMessage_callbacks(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
cancel()

View File

@ -19,7 +19,7 @@ func message(kind messageKind, text string, opts options) error {
args = appendTitle(args, opts)
args = appendButtons(args, opts)
args = appendWidthHeight(args, opts)
args = appendIcon(args, opts)
args = appendWindowIcon(args, opts)
if opts.noWrap {
args = append(args, "--no-wrap")
}

View File

@ -37,7 +37,9 @@ func message(kind messageKind, text string, opts options) error {
flags |= _MB_ICONWARNING
case InfoIcon:
flags |= _MB_ICONINFORMATION
case nil:
case NoIcon:
//
default:
switch kind {
case errorKind:
flags |= _MB_ICONERROR

View File

@ -13,7 +13,6 @@ func ExampleNotify() {
zenity.Notify("There are system updates necessary!",
zenity.Title("Warning"),
zenity.InfoIcon)
// Output:
}
func TestNotify_cancel(t *testing.T) {
@ -29,3 +28,11 @@ func TestNotify_cancel(t *testing.T) {
t.Error("was not canceled:", err)
}
}
func TestNotify_examples(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}
ExampleNotify()
}

View File

@ -39,8 +39,6 @@ func ExampleProgress() {
dlg.Complete()
time.Sleep(time.Second)
// Output:
}
func ExampleProgress_pulsate() {
@ -66,8 +64,6 @@ func ExampleProgress_pulsate() {
dlg.Complete()
time.Sleep(time.Second)
// Output:
}
func TestProgress_cancel(t *testing.T) {
@ -103,3 +99,12 @@ func TestProgress_cancelAfter(t *testing.T) {
t.Error("was not canceled:", err)
}
}
func TestProgress_examples(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}
ExampleProgress()
ExampleProgress_pulsate()
}

View File

@ -9,7 +9,7 @@ func progress(opts options) (ProgressDialog, error) {
args = appendTitle(args, opts)
args = appendButtons(args, opts)
args = appendWidthHeight(args, opts)
args = appendIcon(args, opts)
args = appendWindowIcon(args, opts)
if opts.maxValue == 0 {
opts.maxValue = 100
}

View File

@ -23,6 +23,10 @@ func ExamplePassword_username() {
}
func TestPassword_timeout(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}
defer goleak.VerifyNone(t)
ctx, cancel := context.WithTimeout(context.Background(), time.Second/5)
defer cancel()
@ -65,6 +69,10 @@ func TestPassword_username(t *testing.T) {
}
func TestPassword_script(t *testing.T) {
if testing.Short() {
t.Skip("skipping test in short mode.")
}
tests := []struct {
name string
call string

View File

@ -41,11 +41,11 @@ func appendWidthHeight(args []string, opts options) []string {
return args
}
func appendIcon(args []string, opts options) []string {
if i, ok := opts.icon.(string); ok {
func appendWindowIcon(args []string, opts options) []string {
if i, ok := opts.windowIcon.(string); ok {
args = append(args, "--window-icon", i)
}
switch opts.icon {
switch opts.windowIcon {
case ErrorIcon:
args = append(args, "--window-icon=error")
case WarningIcon:

View File

@ -56,23 +56,24 @@ func Test_appendWidthHeight(t *testing.T) {
}
}
func Test_appendIcon(t *testing.T) {
func Test_appendWindowIcon(t *testing.T) {
tests := []struct {
name string
opts options
want []string
}{
{name: "NoIcon", opts: options{icon: NoIcon}, want: nil},
{name: "Info", opts: options{icon: InfoIcon}, want: []string{"--window-icon=info"}},
{name: "Error", opts: options{icon: ErrorIcon}, want: []string{"--window-icon=error"}},
{name: "Warning", opts: options{icon: WarningIcon}, want: []string{"--window-icon=warning"}},
{name: "Question", opts: options{icon: QuestionIcon}, want: []string{"--window-icon=question"}},
{name: "Password", opts: options{icon: PasswordIcon}, want: nil},
{name: "NoIcon", opts: options{windowIcon: NoIcon}, want: nil},
{name: "Info", opts: options{windowIcon: InfoIcon}, want: []string{"--window-icon=info"}},
{name: "Error", opts: options{windowIcon: ErrorIcon}, want: []string{"--window-icon=error"}},
{name: "Warning", opts: options{windowIcon: WarningIcon}, want: []string{"--window-icon=warning"}},
{name: "Question", opts: options{windowIcon: QuestionIcon}, want: []string{"--window-icon=question"}},
{name: "Password", opts: options{windowIcon: PasswordIcon}, want: nil},
{name: "File", opts: options{windowIcon: "png"}, want: []string{"--window-icon", "png"}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := appendIcon(nil, tt.opts); !reflect.DeepEqual(got, tt.want) {
t.Errorf("appendIcon() = %v; want %v", got, tt.want)
if got := appendWindowIcon(nil, tt.opts); !reflect.DeepEqual(got, tt.want) {
t.Errorf("appendWindowIcon() = %v; want %v", got, tt.want)
}
})
}

View File

@ -43,6 +43,7 @@ type options struct {
extraButton *string
defaultCancel bool
icon any
windowIcon any
// Message options
noWrap bool
@ -168,6 +169,19 @@ func Icon(icon any) Option {
return funcOption(func(o *options) { o.icon = icon })
}
// WindowIcon returns an Option to set the dialog icon (macOS and Unix only).
//
// WindowIcon accepts a DialogIcon, or a string path.
func WindowIcon(icon any) Option {
switch icon.(type) {
case string:
case DialogIcon:
default:
panic("interface conversion: expected string or DialogIcon")
}
return funcOption(func(o *options) { o.windowIcon = icon })
}
// CustomIcon returns an Option to set a custom dialog icon, loaded from a file.
//
// Deprecated: use Icon instead.

View File

@ -23,6 +23,8 @@ func Test_applyOptions(t *testing.T) {
{name: "CancelLabel", args: CancelLabel("Cancel"), want: options{cancelLabel: stringPtr("Cancel")}},
{name: "ExtraButton", args: ExtraButton("Extra"), want: options{extraButton: stringPtr("Extra")}},
{name: "DefaultCancel", args: DefaultCancel(), want: options{defaultCancel: true}},
{name: "WindowIcon", args: WindowIcon(ErrorIcon), want: options{windowIcon: ErrorIcon}},
{name: "WindowIcon", args: WindowIcon("error"), want: options{windowIcon: "error"}},
{name: "Icon", args: Icon(ErrorIcon), want: options{icon: ErrorIcon}},
{name: "Icon", args: Icon("error"), want: options{icon: "error"}},