@MichaelE2 MUnit used to work fine when it was part of the Workbench. But when they updated it and included it in M10.0, it got completely broken. I kept getting random incorrect failures. It was such an awful experience that it scared me away from the official testing framework for good.
A few times I considered trying it again, but these stories keep me away ...
@MichaelE2 I figured out a workflow where I put VerificationTest(s) in a package and call TestReport["packageWithTests.wl"]from notebook or another script (from command line). See this answer for details. This workflow works reliably for me, I use it for more than a year on multiple projects.
@Szabolcs I haven't used it, but it's very interesting. Have you looked at the WLL Interface repo by the same user? Again, very interesting but I haven't used it
@JasonB. No, thanks for pointing it out! I'm going to take a close look. It seems very complete, even having sparse array support. It is really a lot of work to make something like this.
There were similar things in the past, but this is properly templates and avoids overhead
I'd love to have a discussion with the developer. It's a pity he didn't talk to me before starting this. I could have pointed out to him the mistakes I made in LTemplate (which are now too late to fix without a complete rewrite)
Do you know if he is active on this site and what his username is?
@JasonB. I think one of the biggest mistakes I made with LTemplate was trying to keep things simple for everyone and trying to have my MTensor wrappers act similarly to a C++ reference rather than a pointer (thinking that pointers are too hard and allowing null pointers is too dangerous).
This library seems to embrace modern C++ without hesitation. That's probably better, but I still suspect that it's harder to get started with for people who are mainly used to plain C
But then: basically no one uses LTemplate seriously (except me), so what's the point of making it friendly at the cost of flexibility?
And if someone does use it, they're very likely already comfortable enough with C++.
One difference in scope between this and LTemplate seems to be that this one does not explicitly support managed library expressions (or did I just miss it?) while LTemplate was built around the concept of managed library expressions
Originally it was meant to make using managed library expressions easy to use. Have you used them, and does you package have any explicit support? Or have y ou considered adding them?
The most interesting feature I always wanted for LTemplate, but never got around to it (it's not easy) was to connect to "templated" C++ functions
This would be particularly useful for images
Images come with multiple element types: 8-bit, 16-bit, real 32-bit, real 64-bit. Sometimes one can use the very same algorith for all of them. Some image processing libraries, like ITK use templates in C++
It would be really nice if one could write a templated image processing function once in C++, automatically instantiate the template for the relevant types, and have the correct function be called depending on the type of Image that is being passed to the library
That's an idea, but making is work and be useful in practice is not so easy ...
@njpipeorgan Maybe you could send me an email. I have not yet had the time to try your package, but it looks very interesting, and I am looking forward to exploring it. It must have been a lot of work to make it!
Keep me in the loop for this discussion. I use a modified version of LTemplate for all my library work. I've been wanting to show you, @Szabolcs, what changes I made for my use case.
Maybe we should make a separate chat room here for it?
@Kuba Unfortunately I don't. There doesn't seem to be anything in the FE contexts that seems explicitly to manage that and since the token is just a token I've got no good way beyond making an invisible notebook, writing the boxes, converting that selection, then reading the boxes again and closing the notebook. Obviously that'll mess with the FE experience though.
@Kuba @b3m2a1 It's not exactly the same, but there is FrontEndExecute[FrontEnd`ExportPacket[boxes, "InputText"]]. I didn't look for differences too carefully though... (the whitespaces at least seem to be different)
@LukasLang Yeah I use that a lot, but it's not gonna give quite the same behaviour. You can use like FrontEndExecute[FrontEnd`ReparseBoxStructurePacket@First@FrontEndExecute@FrontEnd`ExportPacket[boxes, "InputText"]] or something if you go through the text route.
There is also actually a somewhat better version of "InputText" called something like "Package" (I learned about this from JF--think I put it in my answer detailing FE packets) which respects the cell type as well for Cell expressions and which makes the output text not word wrap and doesn't insert weird spaces all over the place
@LukasLang yep, I know, does not work the way I want, that is why I want that utility which, when used interactively, does what I need. @b3m2a1 And what I need it to import an input cell with 2D typeset entity e.g. Ctrl+= --> France --> Return
as Entity["Country", "France"] without changing the cell.
PlainText gives "Country France" and InputText gives string representation of boxes behind Entities'.
@Kuba in this case aren't you really trying to apply ToExpression to the box expression then? There the real issue is that NamespaceBox can't be interpreted by ToExpression...
@Kuba It looks like that might be an annoying special case, since the standard way you get rid of one of those things is by using that little check mark, but that calls into a ButtonFunction that looks like:
So it's using the BoxReference mechanism to find the parent "LinguisticAssistant" box and replace it with a set of boxes that the NamespaceBox has cooked into it
(which is the first TemplateBox argument in the expression)
Right, I didn't notice it is not 'final' entity yet. I don't work with them at all. This was the first time I pressed that check mark. They should be 'accepted' once you evaluate that cell, shouldn't they?
Which you can call like tryTheThing@getTheBox[PreviousCell[]]
The hard part is getting the NamespaceBox, but if you are writing the expression for it already you might be able to get that more precisely, especially if you know the Cell into which you are writing
The button has a distinct advantage in that it knows where it is already