(Note: though this is tagged Mini Micro, it also applies to Farmtronics and command-line MiniScript.)
A user on Discord recently found a bug in the read
method of FileHandle (the type of object you get back from file.open
), in the specific case where file.open
was called with mode "r". I have fixed that (Mini Micro update coming soon!), and in the process I also wrote a test program that exercises all the different open modes.
I thought it might be helpful to share that here, since it also serves as a good demonstration of what these do.
// Testing all the read/write file modes.
path = "data/test.txt" // NOTE: data folder must already exist.
checkContent = function(context, expectedLines)
actual = file.readLines(path)
if expectedLines != actual then
print "ERROR (" + context + "), expected:"
print expectedLines.join(char(13))
print "...actual:"
print actual.join(char(13))
exit
end if
end function
checkString = function(context, actual, expected)
if actual != expected then
print "ERROR (" + context + "), expected:"
print expected
print "...actual:"
print actual
exit
end if
end function
// Write-only file stream; previous data (if any) is discarded.
f = file.open(path, "w")
f.write "Hello "
f.writeLine "world!"
f.writeLine "(mode w)"
f.close
checkContent "mode w", ["Hello world!", "(mode w)", ""]
// Write-only file stream; previous data (if any) is discarded.
f = file.open(path, "w+")
f.write "Hello "
f.writeLine "world!"
f.writeLine "(mode w+)"
f.close
checkContent "mode w+", ["Hello world!", "(mode w+)", ""]
// Read/write file stream; file created if it doesn't exist.
// (Same as "a+" but we start at the beginning rather than the end.)
f = file.open(path, "rw+")
f.write "Haloo"
f.close
checkContent "mode rw+", ["Haloo world!", "(mode w+)", ""]
// Append: read existing data (if any), but then be ready to add more.
f = file.open(path, "a")
f.writeLine "(mode a)"
f.close
checkContent "mode rw+", ["Haloo world!", "(mode w+)", "(mode a)", ""]
// Append: read existing data (if any), but then be ready to add more.
f = file.open(path, "a+")
f.write "(mode a+)"
f.close
checkContent "mode rw+", ["Haloo world!", "(mode w+)", "(mode a)", "(mode a+)"]
// Read-only file stream: test first on a nonexistent file.
f = file.open(path+"nosuch", "r")
checkString "r", "Error: file not found", f
// Read-only file stream on existing file.
f = file.open(path, "r")
checkString "r", f.readLine, "Haloo world!"
checkString "r", f.readLine, "(mode w+)"
checkString "r", f.readLine, "(mode a)"
checkString "r", f.read, "(mode a+)"
f.close
// Now check f.read with a character (code point) count.
// Make sure it properly handles non-ASCII characters.
f = file.open(path, "w")
f.write "AπB•CD"
f.close
f = file.open(path, "r")
checkString "r", f.read(2), "Aπ"
checkString "r", f.read(1), "B"
checkString "r", f.read(2), "•C"
f.close
If you run this in Mini Micro 1.1.0, it will fail on the "r" methods. But it will work fine in 1.1.1. 😃
Also, I decided to add an optional codePointsToRead
parameter to FileHandle.read. If omitted, it reads to the end of the file like it always did. But now you can specify to read just 1 character or 3 characters or however many you want. These are not bytes, but Unicode code points, so they work properly even with non-ASCII characters. The above code tests/demonstrates that too.