Before I set up the project, I wanted to see how easy it would be to read the contents of a web page in Lua. It turned out to be very easy once I had installed luasocket.
sudo luarocks-jit install luasocket
Reading a webpage highlighted, for me, the ability to return multiple values from a Lua function:
http = require 'socket.http'
body,code,headers,status = http.request('http://bbc.co.uk')
I also noticed that much Lua is written defensively in the sense that care is taken to minimise opportunities for crashes through the use of the assert function and other such techniques. Clearly, being able to return a status code and a value from a function will help to write robust code.
Knowing how to read websites in Lua, I proceeded to set up the project. I adopted a directory structure that will be familiar to many people but I don't know how common it is in Lua circles.
The basic structure is:
stockfetch/ -- main directory
stockfetch-cli.lua -- command line interface
src/ -- lua modules
stockfetch.lua -- main app module
test/ -- tests
stockfetch-busted.lua -- busted tests
stockfetch-unit.lua -- Lua unit tests
After setting up the project, I wanted to work out how best to test its main program, stock watch-cli.lua. It's basically a three line script to initiate the main stockfetch module.
local stockfetch = require('src/stockfetch');
local rc = stockfetch.run()
I'm glad I did as I found out a few things about file paths in Lua that were useful to know from the off:
- Lua retains the current working director setting from the OS. So relative paths calculated in a script can change depending on the directory from which the script was launched
- Another way of looking at that is the Lua does not change the current working directory to that from which a script is loaded
- The dofile function only accepts absolute file paths
- There is no builtin function to "clean" a file path limiting the use of setting a base-file path and a relative path including ../
It soon became apparent that I wasn't going to be able to test stock watch-cli by using docile. (I would be delighted to learn of such a way if there is one.) Instead, I used Lua's command line interfaces to test it.
I found two different ways to run command line programs from Lua - os.execute and io.popen. The first returns the return code from the command executed, the second returns the output from the command. I wanted both, so I chose to use os.execute and redirect the command output to a file. That way I'm able to get both the output and the return code.
I successfully wrote tests in both Busted and LuaUnit using this approach.
Finally, I loaded the project into a GitHub repository.
Next, I will complete the stockfetch app following a test-driven approach and start to learn how to code in Lua.