mirror of
				https://github.com/Maks1mS/bubbles.git
				synced 2025-11-03 23:21:22 +03:00 
			
		
		
		
	feat(spinners): Construct new spinners with WithSpinner + WithStyle options (#148)
				
					
				
			* Add spinner.New test Signed-off-by: Leandro López (inkel) <inkel.ar@gmail.com> * Add spinner.Option type and spinner.WithSpinner option Signed-off-by: Leandro López (inkel) <inkel.ar@gmail.com> * Allow passing options in spinner.New This doesn't break existing code as it uses variadic arguments, so any existing code as the following should continue to work: s := spinner.New() s.spinner = spinner.Dot This change allows for instead of those two lines, having a call: s := spinner.New(spinner.WithSpinner(spinner.Dot)) Signed-off-by: Leandro López (inkel) <inkel.ar@gmail.com> * Add spinner.WithX option for each spinner.Spinner Signed-off-by: Leandro López (inkel) <inkel.ar@gmail.com> * Refactor spinner tests Signed-off-by: Leandro López (inkel) <inkel.ar@gmail.com> * Add spinner.WithStyle option function Signed-off-by: Leandro López (inkel) <inkel.ar@gmail.com> * refactor: remove With... Spinner aliases Co-authored-by: Maas Lalani <maas@lalani.dev>
This commit is contained in:
		
				
					committed by
					
						
						Maas Lalani
					
				
			
			
				
	
			
			
			
						parent
						
							2578480343
						
					
				
				
					commit
					69bf367d37
				
			@@ -109,11 +109,17 @@ func (m Model) ID() int {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// New returns a model with default values.
 | 
					// New returns a model with default values.
 | 
				
			||||||
func New() Model {
 | 
					func New(opts ...Option) Model {
 | 
				
			||||||
	return Model{
 | 
						m := Model{
 | 
				
			||||||
		Spinner: Line,
 | 
							Spinner: Line,
 | 
				
			||||||
		id:      nextID(),
 | 
							id:      nextID(),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, opt := range opts {
 | 
				
			||||||
 | 
							opt(&m)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return m
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewModel returns a model with default values.
 | 
					// NewModel returns a model with default values.
 | 
				
			||||||
@@ -199,3 +205,23 @@ func (m Model) tick(id, tag int) tea.Cmd {
 | 
				
			|||||||
func Tick() tea.Msg {
 | 
					func Tick() tea.Msg {
 | 
				
			||||||
	return TickMsg{Time: time.Now()}
 | 
						return TickMsg{Time: time.Now()}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Option is used to set options in New. For example:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//    spinner := New(WithSpinner(Dot))
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					type Option func(*Model)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// WithSpinner is an option to set the spinner.
 | 
				
			||||||
 | 
					func WithSpinner(spinner Spinner) Option {
 | 
				
			||||||
 | 
						return func(m *Model) {
 | 
				
			||||||
 | 
							m.Spinner = spinner
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// WithStyle is an option to set the spinner style.
 | 
				
			||||||
 | 
					func WithStyle(style lipgloss.Style) Option {
 | 
				
			||||||
 | 
						return func(m *Model) {
 | 
				
			||||||
 | 
							m.Style = style
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										61
									
								
								spinner/spinner_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								spinner/spinner_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					package spinner_test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/charmbracelet/bubbles/spinner"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestSpinnerNew(t *testing.T) {
 | 
				
			||||||
 | 
						assertEqualSpinner := func(t *testing.T, exp, got spinner.Spinner) {
 | 
				
			||||||
 | 
							t.Helper()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if exp.FPS != got.FPS {
 | 
				
			||||||
 | 
								t.Errorf("expecting %d FPS, got %d", exp.FPS, got.FPS)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if e, g := len(exp.Frames), len(got.Frames); e != g {
 | 
				
			||||||
 | 
								t.Fatalf("expecting %d frames, got %d", e, g)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for i, e := range exp.Frames {
 | 
				
			||||||
 | 
								if g := got.Frames[i]; e != g {
 | 
				
			||||||
 | 
									t.Errorf("expecting frame index %d with value %q, got %q", i, e, g)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.Run("default", func(t *testing.T) {
 | 
				
			||||||
 | 
							s := spinner.New()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							assertEqualSpinner(t, spinner.Line, s.Spinner)
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						t.Run("WithSpinner", func(t *testing.T) {
 | 
				
			||||||
 | 
							customSpinner := spinner.Spinner{
 | 
				
			||||||
 | 
								Frames: []string{"a", "b", "c", "d"},
 | 
				
			||||||
 | 
								FPS:    16,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							s := spinner.New(spinner.WithSpinner(customSpinner))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							assertEqualSpinner(t, customSpinner, s.Spinner)
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						tests := map[string]spinner.Spinner{
 | 
				
			||||||
 | 
							"Line":    spinner.Line,
 | 
				
			||||||
 | 
							"Dot":     spinner.Dot,
 | 
				
			||||||
 | 
							"MiniDot": spinner.MiniDot,
 | 
				
			||||||
 | 
							"Jump":    spinner.Jump,
 | 
				
			||||||
 | 
							"Pulse":   spinner.Pulse,
 | 
				
			||||||
 | 
							"Points":  spinner.Points,
 | 
				
			||||||
 | 
							"Globe":   spinner.Globe,
 | 
				
			||||||
 | 
							"Moon":    spinner.Moon,
 | 
				
			||||||
 | 
							"Monkey":  spinner.Monkey,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for name, s := range tests {
 | 
				
			||||||
 | 
							t.Run(name, func(t *testing.T) {
 | 
				
			||||||
 | 
								assertEqualSpinner(t, spinner.New(spinner.WithSpinner(s)).Spinner, s)
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user