-- 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
MIT/X Consortium License
(C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
(C)opyright MMVI Sander van Dijk <a dot h dot vandijk at gmail dot com>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.