The newest update focuses again on program structure and build sequence. Again a few realizations, but I hope I now can start with the actual business logic.
On Code Coverage
It took me not long to find out that the go package goveralls alone doesn't fully cover a multi-package project. But this is less of a problem of that helper, it is a known issue of go test. But, with the aid of a handy script that I fetched from that issue, I now have coverage analysis public as well.
It is not as high as I'd like, but this is limited in two ways. One, I can't test the main applications, especially the JavaScript runners. (I could, but with a lot of mocking I presume.) And the second point is bound to how coverage analysis works: A test that is in one package 'covers' only the source from that package; If the test uses code from another package of the same project, that is not taken into account.
So I moved the test suites around - and also hardened them a bit to allow re-use from other packages. Here I also found out how to get the path name of the calling file. I am still not quite happy that the tests have somehow a life on their own, but it's OK so far.
On program (package) structure
Only after I have moved the packages around and made some interfaces I found this video. In that video, an interesting concept of package separation is mentioned and made me realize I still haven't fully internalized how Go wants you to define interfaces.
What did I do: I created the concept (interface) of an application:
code
which provides the callbacks to the "outside" world. Later additions would be things like key presses.
Initially I thought I would abstract the concept of the environment and inject that into the application. But I figured that I only have two environments, but several (test) applications, which all want the same sequence from the environment: setup, register callbacks, run loop until quit.
Then I have two runners, which set up the window and enter the render loop. One for native apps, one for the browser. The result of these runners is that the respective main functions look very similar (native - browser). Apart from being very short, they only differ in the inclusion of the runner package.
So far I haven't figured out how (or whether it is even possible) to dynamically load a package. Well, a quick search solved that: nope, currently not supported. Actually, I don't need a dynamically loaded package - I only want to be able to reuse the same main file and specify which runner to use at compile time...
Perhaps I can do something like "go build main/main.go main/native/runner.go" or "gopher-js build main/main.go main/browser/runner.go" - and the two runner files would also be in the main package.
I guess I'll try this out when I move around the files once again to have a symmetric structure.
Either way, because of the small main file, I could devise a procedure to js-compile test applications for browser-based tests! The browser test suite provides functions to compile and "fetch" an application for a test. It uses a template for the main function.
That way I could separate the tests from the main application and have dedicated graphics tests, independent from the main application. As a result, the current main application provides again an empty, black screen. The triangle example was refactored into dedicated test cases, based on the same logic.
Now the test cases themselves become very similar (between native and browser), but I'm not sure whether additional effort to abstract them as well is necessary.
What's next
Apart from the urge to clean up the startup code and the dependencies even further, I think I can start to focus on the actual application.
One idea that I had was to write a standard, quick-and-dirty, two-dimensional Game-Of-Life with simple, 2D tiles instead of trying to come up with a full-blown design. Agility, iterations and all that...