cli + tui to publish to leaflet (wip) & manage tasks, notes & watch/read lists 馃崈
charm leaflet readability golang
29
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 204 lines 5.4 kB view raw
1package main 2 3import ( 4 "bytes" 5 "context" 6 "errors" 7 "strings" 8 "testing" 9 10 "github.com/charmbracelet/fang" 11 "github.com/spf13/cobra" 12 "github.com/stormlightlabs/noteleaf/internal/handlers" 13 "github.com/stormlightlabs/noteleaf/internal/store" 14) 15 16func executeCommand(t *testing.T, cmd *cobra.Command, args ...string) string { 17 buf := &bytes.Buffer{} 18 cmd.SetOut(buf) 19 cmd.SetArgs(args) 20 if err := cmd.Execute(); err != nil { 21 t.Fatalf("command %q failed: %v", args, err) 22 } 23 return buf.String() 24} 25 26func TestNewApp(t *testing.T) { 27 t.Run("Success", func(t *testing.T) { 28 origDB := store.NewDatabase 29 origConfig := store.LoadConfig 30 defer func() { 31 store.NewDatabase = origDB 32 store.LoadConfig = origConfig 33 }() 34 35 store.NewDatabase = func() (*store.Database, error) { return &store.Database{}, nil } 36 store.LoadConfig = func() (*store.Config, error) { return &store.Config{}, nil } 37 38 app, err := NewApp() 39 if err != nil { 40 t.Fatalf("expected no error, got %v", err) 41 } 42 if app.db == nil || app.config == nil { 43 t.Fatalf("expected db and config to be initialized") 44 } 45 }) 46 47 t.Run("DBError", func(t *testing.T) { 48 origDB := store.NewDatabase 49 defer func() { store.NewDatabase = origDB }() 50 store.NewDatabase = func() (*store.Database, error) { return nil, errors.New("db boom") } 51 52 _, err := NewApp() 53 if err == nil || !strings.Contains(err.Error(), "failed to initialize database") { 54 t.Errorf("expected db init error, got %v", err) 55 } 56 }) 57 58 t.Run("ConfigError", func(t *testing.T) { 59 origDB := store.NewDatabase 60 origConfig := store.LoadConfig 61 defer func() { 62 store.NewDatabase = origDB 63 store.LoadConfig = origConfig 64 }() 65 store.NewDatabase = func() (*store.Database, error) { return &store.Database{}, nil } 66 store.LoadConfig = func() (*store.Config, error) { return nil, errors.New("config boom") } 67 68 _, err := NewApp() 69 if err == nil || !strings.Contains(err.Error(), "failed to load configuration") { 70 t.Errorf("expected config load error, got %v", err) 71 } 72 }) 73} 74 75func TestRootCmd(t *testing.T) { 76 t.Run("Help", func(t *testing.T) { 77 root := rootCmd() 78 root.SetArgs([]string{}) 79 if err := root.Execute(); err != nil { 80 t.Fatalf("expected no error, got %v", err) 81 } 82 }) 83 84 t.Run("PrintArgs", func(t *testing.T) { 85 root := rootCmd() 86 root.SetArgs([]string{"hello", "world"}) 87 buf := &bytes.Buffer{} 88 root.SetOut(buf) 89 90 if err := root.Execute(); err != nil { 91 t.Fatalf("unexpected error: %v", err) 92 } 93 if got := buf.String(); !strings.Contains(got, "hello world") { 94 t.Errorf("expected output to contain 'hello world', got %q", got) 95 } 96 }) 97} 98 99func TestStatusCmd(t *testing.T) { 100 output := executeCommand(t, statusCmd(), nil...) 101 if output == "" { 102 t.Errorf("expected some status output, got empty string") 103 } 104} 105 106func TestResetCmd(t *testing.T) { 107 _ = executeCommand(t, resetCmd(), nil...) 108} 109 110func TestSetupCmd(t *testing.T) { 111 _ = executeCommand(t, setupCmd(), nil...) 112} 113 114func TestConfCmd(t *testing.T) { 115 cmd := confCmd() 116 buf := &bytes.Buffer{} 117 cmd.SetOut(buf) 118 cmd.SetArgs([]string{"path"}) 119 120 if err := cmd.Execute(); err != nil { 121 t.Errorf("config path command failed: %v", err) 122 } 123} 124 125func TestRun(t *testing.T) { 126 t.Run("Success", func(t *testing.T) { 127 code := run() 128 if code != 0 { 129 t.Errorf("expected exit code 0, got %d", code) 130 } 131 }) 132 133 t.Run("TaskHandlerError", func(t *testing.T) { 134 orig := newTaskHandler 135 defer func() { newTaskHandler = orig }() 136 newTaskHandler = func() (*handlers.TaskHandler, error) { return nil, errors.New("boom") } 137 138 if code := run(); code != 1 { 139 t.Errorf("expected exit code 1, got %d", code) 140 } 141 }) 142 143 t.Run("MovieHandlerError", func(t *testing.T) { 144 orig := newMovieHandler 145 defer func() { newMovieHandler = orig }() 146 newMovieHandler = func() (*handlers.MovieHandler, error) { return nil, errors.New("boom") } 147 148 if code := run(); code != 1 { 149 t.Errorf("expected exit code 1, got %d", code) 150 } 151 }) 152 153 t.Run("TVHandlerError", func(t *testing.T) { 154 orig := newTVHandler 155 defer func() { newTVHandler = orig }() 156 newTVHandler = func() (*handlers.TVHandler, error) { return nil, errors.New("boom") } 157 158 if code := run(); code != 1 { 159 t.Errorf("expected exit code 1, got %d", code) 160 } 161 }) 162 163 t.Run("NoteHandlerError", func(t *testing.T) { 164 orig := newNoteHandler 165 defer func() { newNoteHandler = orig }() 166 newNoteHandler = func() (*handlers.NoteHandler, error) { return nil, errors.New("boom") } 167 168 if code := run(); code != 1 { 169 t.Errorf("expected exit code 1, got %d", code) 170 } 171 }) 172 173 t.Run("BookHandlerError", func(t *testing.T) { 174 orig := newBookHandler 175 defer func() { newBookHandler = orig }() 176 newBookHandler = func() (*handlers.BookHandler, error) { return nil, errors.New("boom") } 177 178 if code := run(); code != 1 { 179 t.Errorf("expected exit code 1, got %d", code) 180 } 181 }) 182 183 t.Run("ArticleHandlerError", func(t *testing.T) { 184 orig := newArticleHandler 185 defer func() { newArticleHandler = orig }() 186 newArticleHandler = func() (*handlers.ArticleHandler, error) { return nil, errors.New("boom") } 187 188 if code := run(); code != 1 { 189 t.Errorf("expected exit code 1, got %d", code) 190 } 191 }) 192 193 t.Run("FangExecuteError", func(t *testing.T) { 194 orig := exc 195 defer func() { exc = orig }() 196 exc = func(ctx context.Context, cmd *cobra.Command, opts ...fang.Option) error { 197 return errors.New("fang failed") 198 } 199 200 if code := run(); code != 1 { 201 t.Errorf("expected exit code 1, got %d", code) 202 } 203 }) 204}