github.com/noqcks/syft@v0.0.0-20230920222752-a9e2c4e288e5/cmd/syft/cli/ui/util_test.go (about)

     1  package ui
     2  
     3  import (
     4  	"reflect"
     5  	"sync"
     6  	"testing"
     7  	"unsafe"
     8  
     9  	tea "github.com/charmbracelet/bubbletea"
    10  )
    11  
    12  func runModel(t testing.TB, m tea.Model, iterations int, message tea.Msg, h ...*sync.WaitGroup) string {
    13  	t.Helper()
    14  	if iterations == 0 {
    15  		iterations = 1
    16  	}
    17  	m.Init()
    18  	var cmd tea.Cmd = func() tea.Msg {
    19  		return message
    20  	}
    21  
    22  	for _, each := range h {
    23  		if each != nil {
    24  			each.Wait()
    25  		}
    26  	}
    27  
    28  	for i := 0; cmd != nil && i < iterations; i++ {
    29  		msgs := flatten(cmd())
    30  		var nextCmds []tea.Cmd
    31  		var next tea.Cmd
    32  		for _, msg := range msgs {
    33  			t.Logf("Message: %+v %+v\n", reflect.TypeOf(msg), msg)
    34  			m, next = m.Update(msg)
    35  			nextCmds = append(nextCmds, next)
    36  		}
    37  		cmd = tea.Batch(nextCmds...)
    38  	}
    39  
    40  	return m.View()
    41  }
    42  
    43  func flatten(p tea.Msg) (msgs []tea.Msg) {
    44  	if reflect.TypeOf(p).Name() == "batchMsg" {
    45  		partials := extractBatchMessages(p)
    46  		for _, m := range partials {
    47  			msgs = append(msgs, flatten(m)...)
    48  		}
    49  	} else {
    50  		msgs = []tea.Msg{p}
    51  	}
    52  	return msgs
    53  }
    54  
    55  func extractBatchMessages(m tea.Msg) (ret []tea.Msg) {
    56  	sliceMsgType := reflect.SliceOf(reflect.TypeOf(tea.Cmd(nil)))
    57  	value := reflect.ValueOf(m) // note: this is technically unaddressable
    58  
    59  	// make our own instance that is addressable
    60  	valueCopy := reflect.New(value.Type()).Elem()
    61  	valueCopy.Set(value)
    62  
    63  	cmds := reflect.NewAt(sliceMsgType, unsafe.Pointer(valueCopy.UnsafeAddr())).Elem()
    64  	for i := 0; i < cmds.Len(); i++ {
    65  		item := cmds.Index(i)
    66  		r := item.Call(nil)
    67  		ret = append(ret, r[0].Interface().(tea.Msg))
    68  	}
    69  	return ret
    70  }