bubbles
bubbles copied to clipboard
fix(textinput): make textinput.Model satisfy tea.Model interface
An early step towards #483.
The CI failures are in a different package, so probably unrelated to this PR 😕
Hey @twpayne! Heads up, we're figuring out a solution to this right now. When we try to make the bubbles implement the tea.Model
interface, we end up having to do a lot of type assertions. For example, here's what it would look like to update a viewport
bubble that implements tea.Model
:
// Pretend viewport.Model implements
// tea.Model here
type model {
vp viewport.Model
}
// Some time later...
newModel, cmd := m.vp.Update(msg)
if newVPModel, ok := newModel(viewport.Model); ok {
m.vp = newCVPModel
}
by comparison, this is the solution with the way to update the viewport
model right now:
m.vp, cmd := m.vp.Update(msg) // DONE
Just wanted to be transparent on this one as any activity on this PR is likely going to be on hold until these refactors are ironed out :)
Ah, thanks for the info. I wanted to add this so I could easily add tests in a follow-up PR. I've been using the following generic function in my tests for my small collection of bubbles:
func testRunModelWithInput[M tea.Model](t *testing.T, model M, input string) M {
t.Helper()
for _, msg := range makeKeyMsgs(input) {
m, _ := model.Update(msg)
var ok bool
model, ok = m.(M)
assert.True(t, ok)
}
return model
}
This allows me to write generic tests without type assertions, like this:
t.Run(tc.name, func(t *testing.T) {
actualModel := testRunModelWithInput(t, NewBoolInputModel("prompt", tc.defaultValue), tc.input)
assert.Equal(t, tc.expectedCanceled, actualModel.Canceled())
assert.Equal(t, tc.expectedValue, actualModel.Value())
})
I'm sure you've already considering this and similar approaches.