-- love.run: main entrypoint function for LÖVE -- -- Most apps can just use the default shown in https://love2d.org/wiki/love.run, -- but we need to override it to install a test harness. -- -- A test harness needs to check what the 'real' code did. -- To do this it needs to hook into primitive operations performed by code. -- Our hooks all go through the `App` global. When running tests they operate -- on fake screen, keyboard and so on. Once all tests pass, the App global -- will hook into the real screen, keyboard and so on. -- -- Scroll below this function for more details. function love.run() App.snapshot_love() -- Tests always run at the start. App.run_tests_and_initialize() --? print('==') love.timer.step() local dt = 0 return function() if love.event then love.event.pump() for name, a,b,c,d,e,f in love.event.poll() do if name == "quit" then if not love.quit or not love.quit() then return a or 0 end end love.handlers[name](a,b,c,d,e,f) end end dt = love.timer.step() App.update(dt) love.graphics.origin() love.graphics.clear(love.graphics.getBackgroundColor()) App.draw() love.graphics.present() love.timer.sleep(0.001) end end -- I've been building LÖVE apps for a couple of months now, and often feel -- stupid. I seem to have a smaller short-term memory than most people, and -- LÖVE apps quickly grow to a point where I need longer and longer chunks of -- focused time to make changes to them. The reason: I don't have a way to -- write tests yet. So before I can change any piece of an app, I have to -- bring into my head all the ways it can break. This isn't the case on other -- platforms, where I can be productive in 5- or 10-minute increments. Because -- I have tests. -- -- Most test harnesses punt on testing I/O, and conventional wisdom is to test -- business logic, not I/O. However, any non-trivial app does non-trivial I/O -- that benefits from tests. And tests aren't very useful if it isn't obvious -- after reading them what the intent is. Including the I/O allows us to write -- tests that mimic how people use our program. -- -- There's a major open research problem in testing I/O: how to write tests -- for graphics. Pixel-by-pixel assertions get too verbose, and they're often -- brittle because you don't care about the precise state of every last pixel. -- Except when you do. Pixels are usually -- but not always -- the trees -- rather than the forest. -- -- I'm not in the business of doing research, so I'm going to shave off a -- small subset of the problem for myself here: how to write tests about text -- (ignoring font, color, etc.) on a graphic screen. -- -- For example, here's how you may write a test of a simple text paginator -- like `less`: -- function test_paginator() -- -- initialize environment -- App.filesystem['/tmp/foo'] = filename([[ -- >abc -- >def -- >ghi -- >jkl -- ]]) -- App.args = {'/tmp/foo'} -- -- define a screen with room for 2 lines of text -- App.screen.init{ -- width=100 -- height=30 -- } -- App.font.init{ -- height=15 -- } -- -- check that screen shows next 2 lines of text after hitting pagedown -- App.run_after_keychord('pagedown') -- App.screen.check(0, 'ghi') -- App.screen.check(15, 'jkl') -- end -- -- All functions starting with 'test_' (no modules) will run before the app -- runs "for real". Each such test is a fake run of our entire program. It can -- set as much of the environment as it wants, then run the app. Here we've -- got a 30px screen and a 15px font, so the screen has room for 2 lines. The -- file we're viewing has 4 lines. We assert that hitting the 'pagedown' key -- shows the third and fourth lines. -- -- Programs can still perform graphics, and all graphics will work in the real -- program. We can't yet write tests for graphics, though. Those pixels are -- basically always blank in tests. Really, there isn't even any -- representation for them. All our fake screens know about is lines of text, -- and what (x,y) coordinates they start at. There's some rudimentary support -- for concatenating all blobs of text that start at the same 'y' coordinate, -- but beware: text at y=100 is separate and non-
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><title>Python: package test</title>
</head><body bgcolor="#f0f0f8">

<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
<tr bgcolor="#7799ee">
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong>test</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/hut/ranger/test/__init__.py">/home/hut/ranger/test/__init__.py</a></font></td></tr></table>
    <p></p>
<p>
<table width="100%" cellspacing=0