This commit is contained in:
parent
88b9e5f965
commit
629bdf27b4
@ -60,6 +60,13 @@ function FnComponentContext:update(new_state)
|
||||
if self.on_change then vim.schedule(function() self.on_change() end) end
|
||||
end
|
||||
|
||||
--- @private
|
||||
--- @param new_state TState
|
||||
function FnComponentContext:update_immediate(new_state)
|
||||
self.state = new_state
|
||||
if self.on_change then self.on_change() end
|
||||
end
|
||||
|
||||
--- @alias u.renderer.FnComponent<TProps, TState> fun(ctx: u.renderer.FnComponentContext<TProps, TState>): u.renderer.Tree
|
||||
|
||||
--- @class u.renderer.Tag
|
||||
|
@ -294,4 +294,99 @@ describe('Renderer', function()
|
||||
assert.are.same(bounds, { start = { 0, 9 }, stop = { 0, 19 } })
|
||||
end)
|
||||
end)
|
||||
|
||||
it('should mount and rerender components', function()
|
||||
withbuf({}, function()
|
||||
--- @type any
|
||||
local leaked_state = { app = {}, c1 = {}, c2 = {} }
|
||||
|
||||
--- @param ctx u.renderer.FnComponentContext<any, { phase: string, count: integer }>
|
||||
local function Counter(ctx)
|
||||
if ctx.phase == 'mount' then ctx.state = { phase = ctx.phase, count = 1 } end
|
||||
local state = assert(ctx.state)
|
||||
state.phase = ctx.phase
|
||||
leaked_state[ctx.props.id].ctx = ctx
|
||||
|
||||
return {
|
||||
{ 'Value: ', R.h.Number({}, tostring(state.count)) },
|
||||
}
|
||||
end
|
||||
|
||||
--- @param ctx u.renderer.FnComponentContext<any, {
|
||||
--- toggle1: boolean,
|
||||
--- show2: boolean
|
||||
--- }>
|
||||
function App(ctx)
|
||||
if ctx.phase == 'mount' then ctx.state = { toggle1 = false, show2 = true } end
|
||||
local state = assert(ctx.state)
|
||||
leaked_state.app.ctx = ctx
|
||||
|
||||
return {
|
||||
state.toggle1 and 'Toggle1' or R.h(Counter, { id = 'c1' }, {}),
|
||||
'\n',
|
||||
|
||||
state.show2 and {
|
||||
'\n',
|
||||
R.h(Counter, { id = 'c2' }, {}),
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
local renderer = R.Renderer.new()
|
||||
renderer:mount(R.h(App, {}, {}))
|
||||
|
||||
local Buffer = require 'u.buffer'
|
||||
local buf = Buffer.current()
|
||||
assert.are.same(buf:all():lines(), {
|
||||
'Value: 1',
|
||||
'',
|
||||
'Value: 1',
|
||||
})
|
||||
assert.are.same(leaked_state.c1.ctx.state.phase, 'mount')
|
||||
assert.are.same(leaked_state.c2.ctx.state.phase, 'mount')
|
||||
leaked_state.app.ctx:update_immediate { toggle1 = true, show2 = true }
|
||||
assert.are.same(buf:all():lines(), {
|
||||
'Toggle1',
|
||||
'',
|
||||
'Value: 1',
|
||||
})
|
||||
assert.are.same(leaked_state.c1.ctx.state.phase, 'unmount')
|
||||
assert.are.same(leaked_state.c2.ctx.state.phase, 'update')
|
||||
|
||||
leaked_state.app.ctx:update_immediate { toggle1 = true, show2 = false }
|
||||
assert.are.same(buf:all():lines(), {
|
||||
'Toggle1',
|
||||
'',
|
||||
})
|
||||
assert.are.same(leaked_state.c1.ctx.state.phase, 'unmount')
|
||||
assert.are.same(leaked_state.c2.ctx.state.phase, 'unmount')
|
||||
|
||||
leaked_state.app.ctx:update_immediate { toggle1 = false, show2 = true }
|
||||
assert.are.same(buf:all():lines(), {
|
||||
'Value: 1',
|
||||
'',
|
||||
'Value: 1',
|
||||
})
|
||||
assert.are.same(leaked_state.c1.ctx.state.phase, 'mount')
|
||||
assert.are.same(leaked_state.c2.ctx.state.phase, 'mount')
|
||||
|
||||
leaked_state.c1.ctx:update_immediate { count = 2 }
|
||||
assert.are.same(buf:all():lines(), {
|
||||
'Value: 2',
|
||||
'',
|
||||
'Value: 1',
|
||||
})
|
||||
assert.are.same(leaked_state.c1.ctx.state.phase, 'update')
|
||||
assert.are.same(leaked_state.c2.ctx.state.phase, 'update')
|
||||
|
||||
leaked_state.c2.ctx:update_immediate { count = 3 }
|
||||
assert.are.same(buf:all():lines(), {
|
||||
'Value: 2',
|
||||
'',
|
||||
'Value: 3',
|
||||
})
|
||||
assert.are.same(leaked_state.c1.ctx.state.phase, 'update')
|
||||
assert.are.same(leaked_state.c2.ctx.state.phase, 'update')
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
Loading…
x
Reference in New Issue
Block a user