mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-24 13:32:50 -05:00
remove tests from master
This commit is contained in:
@@ -1,456 +0,0 @@
|
||||
package clipboard
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestEncodeDecodeEntry_Roundtrip(t *testing.T) {
|
||||
original := Entry{
|
||||
ID: 12345,
|
||||
Data: []byte("hello world"),
|
||||
MimeType: "text/plain;charset=utf-8",
|
||||
Preview: "hello world",
|
||||
Size: 11,
|
||||
Timestamp: time.Now().Truncate(time.Second),
|
||||
IsImage: false,
|
||||
}
|
||||
|
||||
encoded, err := encodeEntry(original)
|
||||
assert.NoError(t, err)
|
||||
|
||||
decoded, err := decodeEntry(encoded)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, original.ID, decoded.ID)
|
||||
assert.Equal(t, original.Data, decoded.Data)
|
||||
assert.Equal(t, original.MimeType, decoded.MimeType)
|
||||
assert.Equal(t, original.Preview, decoded.Preview)
|
||||
assert.Equal(t, original.Size, decoded.Size)
|
||||
assert.Equal(t, original.Timestamp.Unix(), decoded.Timestamp.Unix())
|
||||
assert.Equal(t, original.IsImage, decoded.IsImage)
|
||||
}
|
||||
|
||||
func TestEncodeDecodeEntry_Image(t *testing.T) {
|
||||
original := Entry{
|
||||
ID: 99999,
|
||||
Data: []byte{0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A},
|
||||
MimeType: "image/png",
|
||||
Preview: "[[ image 8 B png 100x100 ]]",
|
||||
Size: 8,
|
||||
Timestamp: time.Now().Truncate(time.Second),
|
||||
IsImage: true,
|
||||
}
|
||||
|
||||
encoded, err := encodeEntry(original)
|
||||
assert.NoError(t, err)
|
||||
|
||||
decoded, err := decodeEntry(encoded)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, original.ID, decoded.ID)
|
||||
assert.Equal(t, original.Data, decoded.Data)
|
||||
assert.True(t, decoded.IsImage)
|
||||
assert.Equal(t, original.Preview, decoded.Preview)
|
||||
}
|
||||
|
||||
func TestEncodeDecodeEntry_EmptyData(t *testing.T) {
|
||||
original := Entry{
|
||||
ID: 1,
|
||||
Data: []byte{},
|
||||
MimeType: "text/plain",
|
||||
Preview: "",
|
||||
Size: 0,
|
||||
Timestamp: time.Now().Truncate(time.Second),
|
||||
IsImage: false,
|
||||
}
|
||||
|
||||
encoded, err := encodeEntry(original)
|
||||
assert.NoError(t, err)
|
||||
|
||||
decoded, err := decodeEntry(encoded)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, original.ID, decoded.ID)
|
||||
assert.Empty(t, decoded.Data)
|
||||
}
|
||||
|
||||
func TestEncodeDecodeEntry_LargeData(t *testing.T) {
|
||||
largeData := make([]byte, 100000)
|
||||
for i := range largeData {
|
||||
largeData[i] = byte(i % 256)
|
||||
}
|
||||
|
||||
original := Entry{
|
||||
ID: 777,
|
||||
Data: largeData,
|
||||
MimeType: "application/octet-stream",
|
||||
Preview: "binary data...",
|
||||
Size: len(largeData),
|
||||
Timestamp: time.Now().Truncate(time.Second),
|
||||
IsImage: false,
|
||||
}
|
||||
|
||||
encoded, err := encodeEntry(original)
|
||||
assert.NoError(t, err)
|
||||
|
||||
decoded, err := decodeEntry(encoded)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, original.Data, decoded.Data)
|
||||
assert.Equal(t, original.Size, decoded.Size)
|
||||
}
|
||||
|
||||
func TestStateEqual_BothNil(t *testing.T) {
|
||||
assert.False(t, stateEqual(nil, nil))
|
||||
}
|
||||
|
||||
func TestStateEqual_OneNil(t *testing.T) {
|
||||
s := &State{Enabled: true}
|
||||
assert.False(t, stateEqual(s, nil))
|
||||
assert.False(t, stateEqual(nil, s))
|
||||
}
|
||||
|
||||
func TestStateEqual_EnabledDiffers(t *testing.T) {
|
||||
a := &State{Enabled: true, History: []Entry{}}
|
||||
b := &State{Enabled: false, History: []Entry{}}
|
||||
assert.False(t, stateEqual(a, b))
|
||||
}
|
||||
|
||||
func TestStateEqual_HistoryLengthDiffers(t *testing.T) {
|
||||
a := &State{Enabled: true, History: []Entry{{ID: 1}}}
|
||||
b := &State{Enabled: true, History: []Entry{}}
|
||||
assert.False(t, stateEqual(a, b))
|
||||
}
|
||||
|
||||
func TestStateEqual_BothEqual(t *testing.T) {
|
||||
a := &State{Enabled: true, History: []Entry{{ID: 1}, {ID: 2}}}
|
||||
b := &State{Enabled: true, History: []Entry{{ID: 3}, {ID: 4}}}
|
||||
assert.True(t, stateEqual(a, b))
|
||||
}
|
||||
|
||||
func TestManager_ConcurrentSubscriberAccess(t *testing.T) {
|
||||
m := &Manager{
|
||||
subscribers: make(map[string]chan State),
|
||||
dirty: make(chan struct{}, 1),
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
const goroutines = 20
|
||||
|
||||
for i := 0; i < goroutines; i++ {
|
||||
wg.Add(1)
|
||||
go func(id int) {
|
||||
defer wg.Done()
|
||||
subID := string(rune('a' + id))
|
||||
ch := m.Subscribe(subID)
|
||||
assert.NotNil(t, ch)
|
||||
time.Sleep(time.Millisecond)
|
||||
m.Unsubscribe(subID)
|
||||
}(i)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestManager_ConcurrentGetState(t *testing.T) {
|
||||
m := &Manager{
|
||||
state: &State{
|
||||
Enabled: true,
|
||||
History: []Entry{{ID: 1}, {ID: 2}},
|
||||
},
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
const goroutines = 50
|
||||
const iterations = 100
|
||||
|
||||
for i := 0; i < goroutines/2; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for j := 0; j < iterations; j++ {
|
||||
s := m.GetState()
|
||||
_ = s.Enabled
|
||||
_ = len(s.History)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
for i := 0; i < goroutines/2; i++ {
|
||||
wg.Add(1)
|
||||
go func(i int) {
|
||||
defer wg.Done()
|
||||
for j := 0; j < iterations; j++ {
|
||||
m.stateMutex.Lock()
|
||||
m.state = &State{
|
||||
Enabled: j%2 == 0,
|
||||
History: []Entry{{ID: uint64(j)}},
|
||||
}
|
||||
m.stateMutex.Unlock()
|
||||
}
|
||||
}(i)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestManager_ConcurrentConfigAccess(t *testing.T) {
|
||||
m := &Manager{
|
||||
config: DefaultConfig(),
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
const goroutines = 30
|
||||
const iterations = 100
|
||||
|
||||
for i := 0; i < goroutines/2; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for j := 0; j < iterations; j++ {
|
||||
cfg := m.getConfig()
|
||||
_ = cfg.MaxHistory
|
||||
_ = cfg.MaxEntrySize
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
for i := 0; i < goroutines/2; i++ {
|
||||
wg.Add(1)
|
||||
go func(i int) {
|
||||
defer wg.Done()
|
||||
for j := 0; j < iterations; j++ {
|
||||
m.configMutex.Lock()
|
||||
m.config.MaxHistory = 50 + j
|
||||
m.config.MaxEntrySize = int64(1024 * j)
|
||||
m.configMutex.Unlock()
|
||||
}
|
||||
}(i)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestManager_NotifySubscribersNonBlocking(t *testing.T) {
|
||||
m := &Manager{
|
||||
dirty: make(chan struct{}, 1),
|
||||
}
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
m.notifySubscribers()
|
||||
}
|
||||
|
||||
assert.Len(t, m.dirty, 1)
|
||||
}
|
||||
|
||||
func TestManager_ConcurrentOfferAccess(t *testing.T) {
|
||||
m := &Manager{
|
||||
offerMimeTypes: make(map[any][]string),
|
||||
offerRegistry: make(map[uint32]any),
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
const goroutines = 20
|
||||
const iterations = 50
|
||||
|
||||
for i := 0; i < goroutines; i++ {
|
||||
wg.Add(1)
|
||||
go func(id int) {
|
||||
defer wg.Done()
|
||||
key := uint32(id)
|
||||
|
||||
for j := 0; j < iterations; j++ {
|
||||
m.offerMutex.Lock()
|
||||
m.offerRegistry[key] = struct{}{}
|
||||
m.offerMimeTypes[key] = []string{"text/plain"}
|
||||
m.offerMutex.Unlock()
|
||||
|
||||
m.offerMutex.RLock()
|
||||
_ = m.offerRegistry[key]
|
||||
_ = m.offerMimeTypes[key]
|
||||
m.offerMutex.RUnlock()
|
||||
|
||||
m.offerMutex.Lock()
|
||||
delete(m.offerRegistry, key)
|
||||
delete(m.offerMimeTypes, key)
|
||||
m.offerMutex.Unlock()
|
||||
}
|
||||
}(i)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestManager_ConcurrentPersistAccess(t *testing.T) {
|
||||
m := &Manager{
|
||||
persistData: make(map[string][]byte),
|
||||
persistMimeTypes: []string{},
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
const goroutines = 20
|
||||
const iterations = 50
|
||||
|
||||
for i := 0; i < goroutines/2; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for j := 0; j < iterations; j++ {
|
||||
m.persistMutex.RLock()
|
||||
_ = m.persistData
|
||||
_ = m.persistMimeTypes
|
||||
m.persistMutex.RUnlock()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
for i := 0; i < goroutines/2; i++ {
|
||||
wg.Add(1)
|
||||
go func(id int) {
|
||||
defer wg.Done()
|
||||
for j := 0; j < iterations; j++ {
|
||||
m.persistMutex.Lock()
|
||||
m.persistMimeTypes = []string{"text/plain", "text/html"}
|
||||
m.persistData = map[string][]byte{
|
||||
"text/plain": []byte("test"),
|
||||
}
|
||||
m.persistMutex.Unlock()
|
||||
}
|
||||
}(i)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestManager_ConcurrentOwnerAccess(t *testing.T) {
|
||||
m := &Manager{}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
const goroutines = 30
|
||||
const iterations = 100
|
||||
|
||||
for i := 0; i < goroutines/2; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for j := 0; j < iterations; j++ {
|
||||
m.ownerLock.Lock()
|
||||
_ = m.isOwner
|
||||
m.ownerLock.Unlock()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
for i := 0; i < goroutines/2; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for j := 0; j < iterations; j++ {
|
||||
m.ownerLock.Lock()
|
||||
m.isOwner = j%2 == 0
|
||||
m.ownerLock.Unlock()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestItob(t *testing.T) {
|
||||
tests := []struct {
|
||||
input uint64
|
||||
expected []byte
|
||||
}{
|
||||
{0, []byte{0, 0, 0, 0, 0, 0, 0, 0}},
|
||||
{1, []byte{0, 0, 0, 0, 0, 0, 0, 1}},
|
||||
{256, []byte{0, 0, 0, 0, 0, 0, 1, 0}},
|
||||
{0xFFFFFFFFFFFFFFFF, []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
result := itob(tt.input)
|
||||
assert.Equal(t, tt.expected, result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSizeStr(t *testing.T) {
|
||||
tests := []struct {
|
||||
input int
|
||||
expected string
|
||||
}{
|
||||
{0, "0 B"},
|
||||
{100, "100 B"},
|
||||
{1024, "1 KiB"},
|
||||
{2048, "2 KiB"},
|
||||
{1048576, "1 MiB"},
|
||||
{5242880, "5 MiB"},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
result := sizeStr(tt.input)
|
||||
assert.Equal(t, tt.expected, result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSelectMimeType(t *testing.T) {
|
||||
m := &Manager{}
|
||||
|
||||
tests := []struct {
|
||||
mimes []string
|
||||
expected string
|
||||
}{
|
||||
{[]string{"text/plain;charset=utf-8", "text/html"}, "text/plain;charset=utf-8"},
|
||||
{[]string{"text/html", "text/plain"}, "text/plain"},
|
||||
{[]string{"application/json", "image/png"}, "image/png"},
|
||||
{[]string{"application/json", "application/xml"}, ""},
|
||||
{[]string{}, ""},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
result := m.selectMimeType(tt.mimes)
|
||||
assert.Equal(t, tt.expected, result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsImageMimeType(t *testing.T) {
|
||||
m := &Manager{}
|
||||
|
||||
assert.True(t, m.isImageMimeType("image/png"))
|
||||
assert.True(t, m.isImageMimeType("image/jpeg"))
|
||||
assert.True(t, m.isImageMimeType("image/gif"))
|
||||
assert.False(t, m.isImageMimeType("text/plain"))
|
||||
assert.False(t, m.isImageMimeType("application/json"))
|
||||
}
|
||||
|
||||
func TestTextPreview(t *testing.T) {
|
||||
m := &Manager{}
|
||||
|
||||
short := m.textPreview([]byte("hello world"))
|
||||
assert.Equal(t, "hello world", short)
|
||||
|
||||
withWhitespace := m.textPreview([]byte(" hello world "))
|
||||
assert.Equal(t, "hello world", withWhitespace)
|
||||
|
||||
longText := make([]byte, 200)
|
||||
for i := range longText {
|
||||
longText[i] = 'a'
|
||||
}
|
||||
preview := m.textPreview(longText)
|
||||
assert.True(t, len(preview) > 100)
|
||||
assert.Contains(t, preview, "…")
|
||||
}
|
||||
|
||||
func TestDefaultConfig(t *testing.T) {
|
||||
cfg := DefaultConfig()
|
||||
assert.Equal(t, 100, cfg.MaxHistory)
|
||||
assert.Equal(t, int64(5*1024*1024), cfg.MaxEntrySize)
|
||||
assert.Equal(t, 0, cfg.AutoClearDays)
|
||||
assert.False(t, cfg.ClearAtStartup)
|
||||
assert.False(t, cfg.Disabled)
|
||||
assert.False(t, cfg.DisableHistory)
|
||||
assert.False(t, cfg.DisablePersist)
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
package wlcontext
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestSharedContext_ConcurrentPostNonBlocking(t *testing.T) {
|
||||
sc := &SharedContext{
|
||||
cmdQueue: make(chan func(), 256),
|
||||
stopChan: make(chan struct{}),
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
const goroutines = 100
|
||||
const iterations = 50
|
||||
|
||||
for i := 0; i < goroutines; i++ {
|
||||
wg.Add(1)
|
||||
go func(id int) {
|
||||
defer wg.Done()
|
||||
for j := 0; j < iterations; j++ {
|
||||
sc.Post(func() {
|
||||
_ = id + j
|
||||
})
|
||||
}
|
||||
}(i)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestSharedContext_PostQueueFull(t *testing.T) {
|
||||
sc := &SharedContext{
|
||||
cmdQueue: make(chan func(), 2),
|
||||
stopChan: make(chan struct{}),
|
||||
}
|
||||
|
||||
sc.Post(func() {})
|
||||
sc.Post(func() {})
|
||||
sc.Post(func() {})
|
||||
sc.Post(func() {})
|
||||
|
||||
assert.Len(t, sc.cmdQueue, 2)
|
||||
}
|
||||
|
||||
func TestSharedContext_StartMultipleTimes(t *testing.T) {
|
||||
sc := &SharedContext{
|
||||
cmdQueue: make(chan func(), 256),
|
||||
stopChan: make(chan struct{}),
|
||||
started: false,
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
const goroutines = 10
|
||||
|
||||
for i := 0; i < goroutines; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
sc.Start()
|
||||
}()
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
||||
assert.True(t, sc.started)
|
||||
}
|
||||
|
||||
func TestSharedContext_DrainCmdQueue(t *testing.T) {
|
||||
sc := &SharedContext{
|
||||
cmdQueue: make(chan func(), 256),
|
||||
stopChan: make(chan struct{}),
|
||||
}
|
||||
|
||||
counter := 0
|
||||
for i := 0; i < 10; i++ {
|
||||
sc.cmdQueue <- func() {
|
||||
counter++
|
||||
}
|
||||
}
|
||||
|
||||
sc.drainCmdQueue()
|
||||
|
||||
assert.Equal(t, 10, counter)
|
||||
assert.Len(t, sc.cmdQueue, 0)
|
||||
}
|
||||
|
||||
func TestSharedContext_DrainCmdQueueEmpty(t *testing.T) {
|
||||
sc := &SharedContext{
|
||||
cmdQueue: make(chan func(), 256),
|
||||
stopChan: make(chan struct{}),
|
||||
}
|
||||
|
||||
sc.drainCmdQueue()
|
||||
|
||||
assert.Len(t, sc.cmdQueue, 0)
|
||||
}
|
||||
|
||||
func TestSharedContext_ConcurrentDrainAndPost(t *testing.T) {
|
||||
sc := &SharedContext{
|
||||
cmdQueue: make(chan func(), 256),
|
||||
stopChan: make(chan struct{}),
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for i := 0; i < 100; i++ {
|
||||
sc.Post(func() {})
|
||||
}
|
||||
}()
|
||||
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for i := 0; i < 50; i++ {
|
||||
sc.drainCmdQueue()
|
||||
}
|
||||
}()
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
Reference in New Issue
Block a user