1package component
2
3import (
4 "encoding/binary"
5 "errors"
6 "sync"
7 "sync/atomic"
8 "testing"
9
10 "github.com/bnema/dumber/assets"
11 "github.com/bnema/puregotk/v4/gdk"
12 "github.com/stretchr/testify/require"
13)
14
15func resetLogoForTest() {
16 logoTexture = nil
17 logoTextureOnce = sync.Once{}
18}
19
20func TestLogoPNG512AssetSignatureAndDimensions(t *testing.T) {
21 data := assets.LogoPNG512
22 require.NotEmpty(t, data)
23 require.Equal(t, []byte{0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A}, data[:8])
24 require.GreaterOrEqual(t, len(data), 33)
25 require.Equal(t, "IHDR", string(data[12:16]))
26 width := binary.BigEndian.Uint32(data[16:20])
27 height := binary.BigEndian.Uint32(data[20:24])
28 require.Equal(t, uint32(512), width)
29 require.Equal(t, uint32(512), height)
30 require.NotEmpty(t, assets.LogoSVG, "SVG source for desktop icons must remain")
31}
32
33func TestGetLogoTextureRequestsRasterOnce(t *testing.T) {
34 resetLogoForTest()
35 origAsset, origDecode := logoAssetBytes, logoDecodeTexture
36 defer func() {
37 logoAssetBytes, logoDecodeTexture = origAsset, origDecode
38 resetLogoForTest()
39 }()
40 var calls atomic.Int32
41 logoAssetBytes = func() []byte {
42 calls.Add(1)
43 return assets.LogoPNG512
44 }
45 logoDecodeTexture = func(data []byte) (*gdk.Texture, error) {
46 require.Equal(t, assets.LogoPNG512, data)
47 return nil, errors.New("native unavailable in unit test")
48 }
49 require.NotPanics(t, func() {
50 require.Nil(t, GetLogoTexture())
51 require.Nil(t, GetLogoTexture())
52 })
53 require.Equal(t, int32(1), calls.Load(), "raster bytes must be requested once")
54}
55
56func TestGetLogoTextureConcurrentCallersShareResult(t *testing.T) {
57 resetLogoForTest()
58 origAsset, origDecode := logoAssetBytes, logoDecodeTexture
59 defer func() {
60 logoAssetBytes, logoDecodeTexture = origAsset, origDecode
61 resetLogoForTest()
62 }()
63 var calls atomic.Int32
64 logoAssetBytes = func() []byte {
65 calls.Add(1)
66 return assets.LogoPNG512
67 }
68 logoDecodeTexture = func([]byte) (*gdk.Texture, error) {
69 return nil, errors.New("native unavailable in unit test")
70 }
71 var wg sync.WaitGroup
72 for range 16 {
73 wg.Add(1)
74 go func() {
75 defer wg.Done()
76 _ = GetLogoTexture()
77 }()
78 }
79 wg.Wait()
80 require.Equal(t, int32(1), calls.Load())
81}
82
83func TestGetLogoTextureFailureDoesNotPanic(t *testing.T) {
84 resetLogoForTest()
85 origAsset, origDecode := logoAssetBytes, logoDecodeTexture
86 defer func() {
87 logoAssetBytes, logoDecodeTexture = origAsset, origDecode
88 resetLogoForTest()
89 }()
90 logoAssetBytes = func() []byte { return nil }
91 logoDecodeTexture = func([]byte) (*gdk.Texture, error) {
92 return nil, errors.New("must not be called with empty asset")
93 }
94 require.NotPanics(t, func() {
95 require.Nil(t, GetLogoTexture())
96 })
97}