Let’s improve CodeaUnit a bit. But first, what’s the deal with iOS shortcuts? An odd report on an odd morning.
It turns out that there’s a user guide for Shortcuts. Who knew Apple could document things for the iPhone and Pad? I’m the sort of person who reads user guides. I’ve even read the entire Procreate1 user guide, more than once, because they keep improving the product.
It says here that you can run a Shortcut from the Shortcuts app, your home screen, a widget, your Apple watch, another app’s share sheet, or via Siri. Maybe I can shout “Hey, Siri, Commit” and have her do it. I fear the HomePod would try to do it. I have so many Siri instances in this house that it’s scary. She seems mostly benign, but I’m surrounded.
The Shortcuts documentation does drag on, but I’ve managed to learn enough to create this one:
When I execute that shortcut, it copies that new function text to the clipboard and then opens Codea. It seems that you cannot auto-paste into an app. Perhaps that makes sense. So I’ll type command+V when we get there, and we’ll see the following:
I can also ask Siri to run the shortcut for me. I’m a newbie here in Shortcut Land, but I’m told that I can put a quick action button on my home screen as well. Or on my watch, but I don’t see that as useful here.
So this is potentially pretty useful. My idea with “new function” was to include a return statement, which Codea doesn’t insert, so as to avoid my common mistake of not having one. Some more useful shortcuts might help me create new CodeaUnit test functions, which I often copy and paste to my detriment.
Shortcuts can prompt for input, so it’s probably possible to customize what gets pasted.
I don’t think anyone will find it productive to watch me fumbling with my initial shortcuts, so I’ll do further learning offline, but if you have useful experience, or specific questions, please tweet me up.
In the D2 (Dung) program, I’ve made some changes to CodeaUnit to make it relate better to the way I work with that program:
It prints total test time to the console. My tests were taking a long time to run, and I wanted a reminder.
When tests are green, it doesn’t display anything, it just lets the program run.
It has a more robust check for whether tests have failed:
if CodeaUnit and CodeaTestsVisible then if Console:find("[1-9] Failed") or Console:find("[1-9] Ignored") or Console:find("[1-9][0-9] Failed") or Console:find("[1-9][0-9] Ignored") then showingTests = true showCodeaUnitTests() end end
The code above is looking at the Ignored and Failed lines to see whether any of them are non-zero. There may be a better way to do that but that one works.
showingTests flag is used to stop the program from running until I touch the screen, in the event that the tests are not green:
if not showingTests then background(0) Runner:draw() end
Frankly, as I look at all the related code, I find it odd:
function draw() local showingTests = false if CodeaUnit and CodeaTestsVisible then if Console:find("[1-9] Failed") or Console:find("[1-9] Ignored") or Console:find("[1-9][0-9] Failed") or Console:find("[1-9][0-9] Ignored") then showingTests = true showCodeaUnitTests() end end if not showingTests then background(0) Runner:draw() end end function touched(aTouch) CodeaTestsVisible = false if aTouch.state == BEGAN then Bus:publish("touchBegan", nil, aTouch.pos, capture) elseif TouchCaptured and aTouch.state == ENDED then TouchCaptured:touchEnded(aTouch.pos, Runner.player) TouchCaptured:setHighlight(false) TouchCaptured = nil end end
I guess it’s OK, the
CodeaTestsVisible flag, going to false after a touch, leaves the
showingTests flag also false. It’s odd, though.
The Dung app has its own copy of CodeaUnit, rather than using a dependency on my “library” copy. I’d best look to see what I’ve done to it. It appears that all I’ve done is comment out some prints, so that it doesn’t display anything but errors. That sort of thing should be handled with control flags, and probably should be set via parameters.
CodeaUnit presently creates just one:
parameter.action("CodeaUnit Runner", function() CodeaUnit.execute() end)
That’s the button you press to run CodeaUnit. I think we could add another parameter or two, to control its behavior a bit. That’s trickier than one might really prefer.
There are three Codea projects involved when we use CodeaUnit.
- The CodeaUnit “library”, containing the CodeaUnit class and a few utility functions;
- The “CUBase” project template, containing a starting test tab, a starting Main tab, and with a reference to the library above;
- Your actual project, which starts out containing the “CUBase” tabs and references CodeaUnit.
Over time, my use of CodeaUnit has varied, and it’s probably time to clean up the Main tab. Let’s start there. The starting Main:
-- CUBase function setup() if CodeaUnit then codeaTestsVisible(true) runCodeaUnitTests() end end function draw() if CodeaUnit then showCodeaUnitTests() end end -- ------ functions below here function runCodeaUnitTests() local det = CodeaUnit.detailed CodeaUnit.detailed = false Console = _.execute() CodeaUnit.detailed = det end function showCodeaUnitTests() if CodeaVisible then background(40, 40, 50) pushMatrix() pushStyle() fontSize(50) textAlign(CENTER) if not Console:find("0 Failed") then stroke(255,0,0) fill(255,0,0) elseif not Console:find("0 Ignored") then stroke(255,255,0) fill(255,255,0) else fill(0,255,0,50) end text(Console, WIDTH/2, HEIGHT-100) popStyle() popMatrix() end end function codeaTestsVisible(aBoolean) CodeaVisible = aBoolean end
Let’s make some decisions here. The “new” design will have some parameters that come up, in addition to the button that runs the tests. There will be no special functions in the CUbase Main tab, just the minimum necessary code to run the tests from setup and display the results.
So the first thing I have to do with my new sample program is to bring CodeaUnit into it, in a separate tab, so that I can edit it as needed. Then I’ll put it back into CodeaUnit, and save what we wind up with as the new CUbase. Or roughly that, anyway …
I’ve built a boolean parameter “CodeaUnit_Detailed”, that suppresses print of all output except for errors. I’ve improved the code to show the summaries in green red, or yellow, depending on whether the tests pass, fail, or have an ignored test, respectively.
I like the trick I did in the Dung program, that lets the program own the screen if tests are green, and locks the screen to the CodeaUnit summary if they’re yellow or red, until the user touches the screen.
Let’s do that with another parameter “CodeaUnit_Lock”.
I’ve got the default main tab down to this now:
-- CUBase function setup() --CodeaUnit_Detailed = false --CodeaUnit_Lock = false if CodeaUnit then _.execute() end end function draw() background(40) if CodeaUnit and CodeaUnit_Lock then _.showTests() else background(128) stroke(0) fill(0) text("Your App Here", WIDTH/2,HEIGHT/2) end end function touched() CodeaUnit_Lock = false end
The two comments are there as a reminder that you can init the two new parameters to your liking. I think, with any luck, this will serve as a decent base. I do rather suspect that if I save this CodeaUnit back to the one used as a dependency, that old programs may behave oddly. I wonder if that means I should make a new version for this one.
I do, naming it CodeaUnit2. Now I can create the new base.
It turns out that none of these projects are under version control. I’ll put the new CUBase and CodeaUnit2 into WorkingCopy. Done.
Now what about converting D2 to use the new CodeaUnit? Sure, let’s try. The changes are easy but even after I reformat the output a bit I don’t like this:
When there’s an error anywhere, the entire output turns red. I can’t really make out which lines have problems. I think in the next version we’ll improve that. But for now, let’s sum up.
We’ve managed to make a new version of CodeaUnit that works for new projects and for D2. Older projects would perhaps require a bit of conversion but they can be left pointed at the old one.
I think I like the two new parameters, one for abbreviated output, which I’m tempted to make the default, and the other to unlock the screen and let your app run. For that one, I’m not entirely sure it’s right. As it stands now, it will unconditionally lock the screen until you touch it, even if your tests are green. I may decide that I don’t like that. We’ll see.
Looking forward, I think what I’ll do is create utilities, like the CodeaStats project, and rig them up to be included as additional dependencies (perhaps just one dependency), providing additional buttons and widgets that you can press to get their results. These could evolve into a somewhat nicer experience making larger Codea projects. I’ll be evolving toward a Codea “Making App”.
And I’ll experiment further with Shortcuts, to see whether there’s something actually helpful to do there. They need to be useful enough to be worth doing whatever special operation one has to do to trigger them, but pressing the Siri button and saying “new function” isn’t what I’d call difficult.
Anyway, kind of an odd morning, but some useful results. I hope to see you next time!
Procreate is a simply marvelous drawing app for iPadOS. It costs less than $10 and is incredibly powerful, with layers, custom brushes, and more. If you draw, and want to draw on a tablet, check it out. I am not compensated in any way for touting their excellent product. ↩