gioui.org@v0.6.1-0.20240506124620-7a9ce51988ce/io/input/clipboard_test.go (about) 1 // SPDX-License-Identifier: Unlicense OR MIT 2 3 package input 4 5 import ( 6 "io" 7 "strings" 8 "testing" 9 10 "gioui.org/io/clipboard" 11 "gioui.org/io/transfer" 12 "gioui.org/op" 13 ) 14 15 func TestClipboardDuplicateEvent(t *testing.T) { 16 ops, r, handlers := new(op.Ops), new(Router), make([]int, 2) 17 18 // Both must receive the event once. 19 r.Source().Execute(clipboard.ReadCmd{Tag: &handlers[0]}) 20 r.Source().Execute(clipboard.ReadCmd{Tag: &handlers[1]}) 21 22 event := transfer.DataEvent{ 23 Type: "application/text", 24 Open: func() io.ReadCloser { 25 return io.NopCloser(strings.NewReader("Test")) 26 }, 27 } 28 r.Queue(event) 29 for i := range handlers { 30 f := transfer.TargetFilter{Target: &handlers[i], Type: "application/text"} 31 assertEventTypeSequence(t, events(r, -1, f), transfer.DataEvent{}) 32 } 33 assertClipboardReadCmd(t, r, 0) 34 35 r.Source().Execute(clipboard.ReadCmd{Tag: &handlers[0]}) 36 37 r.Frame(ops) 38 // No ClipboardEvent sent 39 assertClipboardReadCmd(t, r, 1) 40 for i := range handlers { 41 f := transfer.TargetFilter{Target: &handlers[i]} 42 assertEventTypeSequence(t, events(r, -1, f)) 43 } 44 } 45 46 func TestQueueProcessReadClipboard(t *testing.T) { 47 ops, r, handler := new(op.Ops), new(Router), make([]int, 2) 48 49 // Request read 50 r.Source().Execute(clipboard.ReadCmd{Tag: &handler[0]}) 51 52 assertClipboardReadCmd(t, r, 1) 53 ops.Reset() 54 55 for i := 0; i < 3; i++ { 56 // No ReadCmd 57 // One receiver must still wait for response 58 59 r.Frame(ops) 60 assertClipboardReadDuplicated(t, r, 1) 61 } 62 63 // Send the clipboard event 64 event := transfer.DataEvent{ 65 Type: "application/text", 66 Open: func() io.ReadCloser { 67 return io.NopCloser(strings.NewReader("Text 2")) 68 }, 69 } 70 r.Queue(event) 71 assertEventTypeSequence(t, events(r, -1, transfer.TargetFilter{Target: &handler[0], Type: "application/text"}), transfer.DataEvent{}) 72 assertClipboardReadCmd(t, r, 0) 73 } 74 75 func TestQueueProcessWriteClipboard(t *testing.T) { 76 r := new(Router) 77 78 const mime = "application/text" 79 r.Source().Execute(clipboard.WriteCmd{Type: mime, Data: io.NopCloser(strings.NewReader("Write 1"))}) 80 81 assertClipboardWriteCmd(t, r, mime, "Write 1") 82 assertClipboardWriteCmd(t, r, "", "") 83 84 r.Source().Execute(clipboard.WriteCmd{Type: mime, Data: io.NopCloser(strings.NewReader("Write 2"))}) 85 86 assertClipboardReadCmd(t, r, 0) 87 assertClipboardWriteCmd(t, r, mime, "Write 2") 88 } 89 90 func assertClipboardReadCmd(t *testing.T, router *Router, expected int) { 91 t.Helper() 92 if got := len(router.state().receivers); got != expected { 93 t.Errorf("unexpected %d receivers, got %d", expected, got) 94 } 95 if router.ClipboardRequested() != (expected > 0) { 96 t.Error("missing requests") 97 } 98 } 99 100 func assertClipboardReadDuplicated(t *testing.T, router *Router, expected int) { 101 t.Helper() 102 if len(router.state().receivers) != expected { 103 t.Error("receivers removed") 104 } 105 if router.ClipboardRequested() != false { 106 t.Error("duplicated requests") 107 } 108 } 109 110 func assertClipboardWriteCmd(t *testing.T, router *Router, mimeExp, expected string) { 111 t.Helper() 112 if (router.cqueue.text != nil) != (expected != "") { 113 t.Error("text not defined") 114 } 115 mime, text, ok := router.cqueue.WriteClipboard() 116 if ok != (expected != "") { 117 t.Error("duplicated requests") 118 } 119 if string(mime) != mimeExp { 120 t.Errorf("got MIME type %s, expected %s", mime, mimeExp) 121 } 122 if string(text) != expected { 123 t.Errorf("got text %s, expected %s", text, expected) 124 } 125 }