first successful pagedown test, first bug found by test
I also really need to rethink how people debug my programs. My approach of inserting and deleting print() takes a lot of commitment. I need my old trace-based whitebox testing idea. However, in my past projects I never did figure out a good framework for tweaking how verbose a trace to emit. Perhaps that's too many knobs. Perhaps we just need a way to run a single test with the most verbose trace possible. Then it's just a matter of having the trace tell a coherent story? But even if the trace stays out of program output in that situation, it's still in the programmer's face in the _code_. Ugh. Current plan: ship program with maximum tests and zero commented-out prints. If you want to debug, insert prints. This is better than previous, text-mode, projects just by virtue of the stdout channel being dedicated to debug stuff.
This commit is contained in:
parent
46d4c4de10
commit
37f1313b16
12
app.lua
12
app.lua
|
@ -93,7 +93,7 @@ end
|
||||||
-- App.font{
|
-- App.font{
|
||||||
-- height=15
|
-- height=15
|
||||||
-- }
|
-- }
|
||||||
-- App.run_with_keypress('pagedown')
|
-- App.run_after_keypress('pagedown')
|
||||||
-- App.check_screen_contents{
|
-- App.check_screen_contents{
|
||||||
-- y0='ghi'
|
-- y0='ghi'
|
||||||
-- y15=''
|
-- y15=''
|
||||||
|
@ -138,6 +138,7 @@ end
|
||||||
|
|
||||||
function App.screen.print(msg, x,y)
|
function App.screen.print(msg, x,y)
|
||||||
local screen_row = 'y'..tostring(y)
|
local screen_row = 'y'..tostring(y)
|
||||||
|
print('drawing "'..msg..'" at y '..tostring(y))
|
||||||
local screen = App.screen
|
local screen = App.screen
|
||||||
if screen.contents[screen_row] == nil then
|
if screen.contents[screen_row] == nil then
|
||||||
screen.contents[screen_row] = {}
|
screen.contents[screen_row] = {}
|
||||||
|
@ -175,6 +176,12 @@ function App.run_after_textinput(t)
|
||||||
App.draw()
|
App.draw()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function App.run_after_keychord(key)
|
||||||
|
App.keychord_pressed(key)
|
||||||
|
App.screen.contents = {}
|
||||||
|
App.draw()
|
||||||
|
end
|
||||||
|
|
||||||
function App.width(text)
|
function App.width(text)
|
||||||
return text.text:getWidth()
|
return text.text:getWidth()
|
||||||
end
|
end
|
||||||
|
@ -182,6 +189,9 @@ end
|
||||||
function App.screen.check(y, expected_contents, msg)
|
function App.screen.check(y, expected_contents, msg)
|
||||||
local screen_row = 'y'..tostring(y)
|
local screen_row = 'y'..tostring(y)
|
||||||
local contents = ''
|
local contents = ''
|
||||||
|
if App.screen.contents[screen_row] == nil then
|
||||||
|
error('no text at y '..tostring(y))
|
||||||
|
end
|
||||||
for i,s in ipairs(App.screen.contents[screen_row]) do
|
for i,s in ipairs(App.screen.contents[screen_row]) do
|
||||||
contents = contents..s
|
contents = contents..s
|
||||||
end
|
end
|
||||||
|
|
12
file.lua
12
file.lua
|
@ -107,13 +107,18 @@ end
|
||||||
function load_array(a)
|
function load_array(a)
|
||||||
local result = {}
|
local result = {}
|
||||||
local next_line = ipairs(a)
|
local next_line = ipairs(a)
|
||||||
local i,line = 0, ''
|
local i,line,drawing = 0, ''
|
||||||
while true do
|
while true do
|
||||||
i,line = next_line(a, i)
|
i,line = next_line(a, i)
|
||||||
if i == nil then break end
|
if i == nil then break end
|
||||||
|
--? print(line)
|
||||||
if line == '```lines' then -- inflexible with whitespace since these files are always autogenerated
|
if line == '```lines' then -- inflexible with whitespace since these files are always autogenerated
|
||||||
table.insert(result, load_drawing_from_array(next_line, a, i))
|
--? print('inserting drawing')
|
||||||
|
i, drawing = load_drawing_from_array(next_line, a, i)
|
||||||
|
--? print('i now', i)
|
||||||
|
table.insert(result, drawing)
|
||||||
else
|
else
|
||||||
|
--? print('inserting text')
|
||||||
table.insert(result, {mode='text', data=line})
|
table.insert(result, {mode='text', data=line})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -129,6 +134,7 @@ function load_drawing_from_array(iter, a, i)
|
||||||
while true do
|
while true do
|
||||||
i, line = iter(a, i)
|
i, line = iter(a, i)
|
||||||
assert(i)
|
assert(i)
|
||||||
|
--? print(i)
|
||||||
if line == '```' then break end
|
if line == '```' then break end
|
||||||
local shape = json.decode(line)
|
local shape = json.decode(line)
|
||||||
if shape.mode == 'freehand' then
|
if shape.mode == 'freehand' then
|
||||||
|
@ -156,5 +162,5 @@ function load_drawing_from_array(iter, a, i)
|
||||||
end
|
end
|
||||||
table.insert(drawing.shapes, shape)
|
table.insert(drawing.shapes, shape)
|
||||||
end
|
end
|
||||||
return drawing
|
return i, drawing
|
||||||
end
|
end
|
||||||
|
|
15
main.lua
15
main.lua
|
@ -81,7 +81,7 @@ Zoom = 1.5
|
||||||
|
|
||||||
Filename = love.filesystem.getUserDirectory()..'/lines.txt'
|
Filename = love.filesystem.getUserDirectory()..'/lines.txt'
|
||||||
|
|
||||||
New_foo = true
|
Debug_main = false
|
||||||
|
|
||||||
if #arg > 0 then
|
if #arg > 0 then
|
||||||
Filename = arg[1]
|
Filename = arg[1]
|
||||||
|
@ -120,9 +120,9 @@ function App.draw()
|
||||||
line.y = nil
|
line.y = nil
|
||||||
end
|
end
|
||||||
local y = 15
|
local y = 15
|
||||||
if New_foo then print('== draw') end
|
if Debug_main then print('== draw') end
|
||||||
for line_index,line in ipairs(Lines) do
|
for line_index,line in ipairs(Lines) do
|
||||||
if New_foo then print('draw:', line_index, y) end
|
if Debug_main then print('draw:', line_index, y) end
|
||||||
if y + math.floor(15*Zoom) > App.screen.height then break end
|
if y + math.floor(15*Zoom) > App.screen.height then break end
|
||||||
if line_index >= Screen_top1.line then
|
if line_index >= Screen_top1.line then
|
||||||
Screen_bottom1.line = line_index
|
Screen_bottom1.line = line_index
|
||||||
|
@ -146,15 +146,15 @@ function App.draw()
|
||||||
Drawing.draw(line)
|
Drawing.draw(line)
|
||||||
y = y + Drawing.pixels(line.h) + 10 -- padding
|
y = y + Drawing.pixels(line.h) + 10 -- padding
|
||||||
else
|
else
|
||||||
if New_foo then print('text') end
|
if Debug_main then print('text') end
|
||||||
line.y = y
|
line.y = y
|
||||||
y, Screen_bottom1.pos = Text.draw(line, Line_width, line_index)
|
y, Screen_bottom1.pos = Text.draw(line, Line_width, line_index)
|
||||||
y = y + math.floor(15*Zoom) -- text height
|
y = y + math.floor(15*Zoom) -- text height
|
||||||
if New_foo then print('aa', y) end
|
if Debug_main then print('aa', y) end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
New_foo = false
|
Debug_main = false
|
||||||
--? print('screen bottom: '..tostring(Screen_bottom1.pos)..' in '..tostring(Lines[Screen_bottom1.line].data))
|
--? print('screen bottom: '..tostring(Screen_bottom1.pos)..' in '..tostring(Lines[Screen_bottom1.line].data))
|
||||||
--? os.exit(1)
|
--? os.exit(1)
|
||||||
end
|
end
|
||||||
|
@ -195,7 +195,7 @@ function App.textinput(t)
|
||||||
end
|
end
|
||||||
|
|
||||||
function App.keychord_pressed(chord)
|
function App.keychord_pressed(chord)
|
||||||
New_foo = true
|
--? Debug_main = true
|
||||||
if love.mouse.isDown('1') or chord:sub(1,2) == 'C-' then
|
if love.mouse.isDown('1') or chord:sub(1,2) == 'C-' then
|
||||||
Drawing.keychord_pressed(chord)
|
Drawing.keychord_pressed(chord)
|
||||||
elseif chord == 'escape' and love.mouse.isDown('1') then
|
elseif chord == 'escape' and love.mouse.isDown('1') then
|
||||||
|
@ -226,6 +226,7 @@ function App.keychord_pressed(chord)
|
||||||
end
|
end
|
||||||
save_to_disk(Lines, Filename)
|
save_to_disk(Lines, Filename)
|
||||||
elseif chord == 'pagedown' then
|
elseif chord == 'pagedown' then
|
||||||
|
print('setting top to', Screen_bottom1.line)
|
||||||
Screen_top1.line = Screen_bottom1.line
|
Screen_top1.line = Screen_bottom1.line
|
||||||
Screen_top1.pos = Screen_bottom1.pos
|
Screen_top1.pos = Screen_bottom1.pos
|
||||||
Cursor1.line = Screen_top1.line
|
Cursor1.line = Screen_top1.line
|
||||||
|
|
61
text.lua
61
text.lua
|
@ -28,7 +28,7 @@ function Text.draw(line, line_width, line_index)
|
||||||
assert(x > 25) -- no overfull lines
|
assert(x > 25) -- no overfull lines
|
||||||
if line_index > Screen_top1.line or pos > Screen_top1.pos then
|
if line_index > Screen_top1.line or pos > Screen_top1.pos then
|
||||||
y = y + math.floor(15*Zoom)
|
y = y + math.floor(15*Zoom)
|
||||||
if New_foo then print('text: new screen line', y, Screen_height, screen_line_starting_pos) end
|
if New_foo then print('text: new screen line', y, App.screen.height, screen_line_starting_pos) end
|
||||||
screen_line_starting_pos = pos
|
screen_line_starting_pos = pos
|
||||||
if Debug_new_render then print('y', y) end
|
if Debug_new_render then print('y', y) end
|
||||||
end
|
end
|
||||||
|
@ -39,7 +39,7 @@ function Text.draw(line, line_width, line_index)
|
||||||
table.insert(line.screen_line_starting_pos, pos)
|
table.insert(line.screen_line_starting_pos, pos)
|
||||||
end
|
end
|
||||||
if line_index > Screen_top1.line or pos > Screen_top1.pos then
|
if line_index > Screen_top1.line or pos > Screen_top1.pos then
|
||||||
if y + math.floor(15*Zoom) >= Screen_height then
|
if y + math.floor(15*Zoom) >= App.screen.height then
|
||||||
return y, screen_line_starting_pos
|
return y, screen_line_starting_pos
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -79,6 +79,7 @@ function Text.draw_cursor(x, y)
|
||||||
end
|
end
|
||||||
|
|
||||||
function test_draw_text()
|
function test_draw_text()
|
||||||
|
print('test_draw_text')
|
||||||
App.screen.init{width=120, height=60}
|
App.screen.init{width=120, height=60}
|
||||||
Lines = load_array{'abc', 'def', 'ghi'}
|
Lines = load_array{'abc', 'def', 'ghi'}
|
||||||
Line_width = 120
|
Line_width = 120
|
||||||
|
@ -97,6 +98,59 @@ function test_draw_text()
|
||||||
App.screen.check(y, 'ghi', 'F - test_draw_text/screen:3')
|
App.screen.check(y, 'ghi', 'F - test_draw_text/screen:3')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function test_pagedown()
|
||||||
|
print('test_pagedown')
|
||||||
|
App.screen.init{width=120, height=45}
|
||||||
|
Lines = load_array{'abc', 'def', 'ghi'}
|
||||||
|
Line_width = 120
|
||||||
|
Cursor1 = {line=1, pos=1}
|
||||||
|
Screen_top1 = {line=1, pos=1}
|
||||||
|
Screen_bottom1 = {}
|
||||||
|
Zoom = 1
|
||||||
|
local screen_top_margin = 15 -- pixels
|
||||||
|
local line_height = math.floor(15*Zoom) -- pixels
|
||||||
|
-- initially the first two lines are displayed
|
||||||
|
App.draw()
|
||||||
|
local y = screen_top_margin
|
||||||
|
App.screen.check(y, 'abc', 'F - test_pagedown/baseline/screen:1')
|
||||||
|
y = y + line_height
|
||||||
|
App.screen.check(y, 'def', 'F - test_pagedown/baseline/screen:2')
|
||||||
|
-- after pagedown the bottom line becomes the top
|
||||||
|
App.run_after_keychord('pagedown')
|
||||||
|
y = screen_top_margin
|
||||||
|
App.screen.check(y, 'def', 'F - test_pagedown/screen:1')
|
||||||
|
y = y + line_height
|
||||||
|
App.screen.check(y, 'ghi', 'F - test_pagedown/screen:2')
|
||||||
|
end
|
||||||
|
|
||||||
|
function test_pagedown_skip_drawings()
|
||||||
|
print('test_pagedown_skip_drawings')
|
||||||
|
-- some lines of text with a drawing intermixed
|
||||||
|
App.screen.init{width=50, height=45}
|
||||||
|
Lines = load_array{'abc',
|
||||||
|
'```lines', '```',
|
||||||
|
'def',
|
||||||
|
'ghi'}
|
||||||
|
check_eq(Lines[2].mode, 'drawing', 'F - test_pagedown_skip_drawings/baseline/lines')
|
||||||
|
Line_width = App.screen.width
|
||||||
|
Cursor1 = {line=1, pos=1}
|
||||||
|
Screen_top1 = {line=1, pos=1}
|
||||||
|
Screen_bottom1 = {}
|
||||||
|
Zoom = 1
|
||||||
|
local screen_top_margin = 15 -- pixels
|
||||||
|
local drawing_height = App.screen.width / 2 -- default
|
||||||
|
-- initially the screen displays the first line and part of the drawing
|
||||||
|
App.draw()
|
||||||
|
local y = screen_top_margin
|
||||||
|
App.screen.check(y, 'abc', 'F - test_pagedown_skip_drawings/baseline/screen:1')
|
||||||
|
-- after pagedown the screen draws the screen up top
|
||||||
|
App.run_after_keychord('pagedown')
|
||||||
|
y = screen_top_margin + drawing_height
|
||||||
|
App.screen.check(y, 'def', 'F - test_pagedown_skip_drawings/screen:1')
|
||||||
|
y = y + line_height
|
||||||
|
App.screen.check(y, 'ghi', 'F - test_pagedown_skip_drawings/screen:2')
|
||||||
|
end
|
||||||
|
|
||||||
function Text.compute_fragments(line, line_width)
|
function Text.compute_fragments(line, line_width)
|
||||||
line.fragments = {}
|
line.fragments = {}
|
||||||
local x = 25
|
local x = 25
|
||||||
|
@ -376,6 +430,7 @@ function Text.move_cursor_down_to_next_text_line_while_scrolling_again_if_necess
|
||||||
table.insert(Lines, {mode='text', data=''})
|
table.insert(Lines, {mode='text', data=''})
|
||||||
end
|
end
|
||||||
if Cursor1.line > Screen_bottom1.line then
|
if Cursor1.line > Screen_bottom1.line then
|
||||||
|
print('scroll up')
|
||||||
Screen_top1.line = Cursor1.line
|
Screen_top1.line = Cursor1.line
|
||||||
Text.scroll_up_while_cursor_on_screen()
|
Text.scroll_up_while_cursor_on_screen()
|
||||||
end
|
end
|
||||||
|
@ -384,7 +439,7 @@ end
|
||||||
function Text.scroll_up_while_cursor_on_screen()
|
function Text.scroll_up_while_cursor_on_screen()
|
||||||
local top2 = Text.to2(Cursor1)
|
local top2 = Text.to2(Cursor1)
|
||||||
--? print('cursor pos '..tostring(Cursor1.pos)..' is on the #'..tostring(top2.screen_line)..' screen line down')
|
--? print('cursor pos '..tostring(Cursor1.pos)..' is on the #'..tostring(top2.screen_line)..' screen line down')
|
||||||
local y = Screen_height - math.floor(15*Zoom)
|
local y = App.screen.height - math.floor(15*Zoom)
|
||||||
-- duplicate some logic from love.draw
|
-- duplicate some logic from love.draw
|
||||||
while true do
|
while true do
|
||||||
--? print(y, 'top2:', top2.line, top2.screen_line, top2.screen_pos)
|
--? print(y, 'top2:', top2.line, top2.screen_line, top2.screen_pos)
|
||||||
|
|
Loading…
Reference in New Issue