[JW Lua] Unit-testing with jwlua scripts?

Nick Mazuk nick at nickmazuk.com
Tue Sep 14 05:30:13 CEST 2021


Neat stuff about OOP, Thomas! I haven't personally had a need to use OOP with JW Lua (since most things I've needed to do just work best functionally, anyways), but good to know that it's possible.

> 
> I wonder how you come to that conclusion.  JW Lua does not take anything
> away from Lua that would make those not work.  It just adds some
> functions, tables and user data, but that's not a problem.  As long as
> they are implemented in pure Lua and Lua 5.2 compatible.
> 

>From my understanding, JW Lua allows you to interact with the PDK framework via Lua. The PDK framework, though, is written in C++. Therefore, if you write something like…

local measure = finale.FCMeasure()

…it will eventually invoke some C++ code. While it is possible outside of JW Lua to have Lua bind to C++ code, JW Lua isn't something you can just import/require. It's added when the plugin itself runs the script. Therefore, JW Lua code run outside of the plugin won't work. I'm also unsure how one might mock/stub PDK values to do true unit/integration testing.

Hopefully that clears up my reasoning. I'll admit, I haven't tried using a Lua testing framework with JW Lua, so perhaps I'm wrong. I'd actually be glad to be wrong about this. If anyone has/does get unit testing working, that's exciting!

Nick

On Mon, Sep 13, 2021 at 9:34 AM, Thomas Weber < thomas.weber at notengrafik.com > wrote:

> 
> Am 11.09.21 um 21:26 schrieb Nick Mazuk:
> 
> 
>> 
>> *Unit testing*
>> 
>> 
>> 
>> Testing is a feature that's missing in JW Lua. Lua (the language that
>> powers JW Lua) does have several testing frameworks you can use, but
>> because JW Lua adds so many features on top of regular Lua, you likely
>> won't be able to use any of these frameworks.
>> 
>> 
> 
> 
> 
> 
> 
> 
> 
> 
> I wonder how you come to that conclusion.  JW Lua does not take anything
> away from Lua that would make those not work.  It just adds some
> functions, tables and user data, but that's not a problem.  As long as
> they are implemented in pure Lua and Lua 5.2 compatible.
> 
> 
> 
> 
> 
> 
> 
> 
>> 
>> 
>> 
>> *OOP*
>> 
>> 
>> 
>> Lua does not have objects, classes, inheritance, or most other features
>> you'd expect with object oriented programming. The closest thing is a
>> "table" (like a dictionary in Python or a hash map in Javascript). So the
>> code you write is mostly going to be functional (which realistically this
>> works really well for JW Lua).
>> 
>> 
> 
> 
> 
> 
> 
> 
> 
> 
> Well, some say you can even program in an object oriented way in C, but
> you'd have to roll your own.  In Lua, you have to roll your own as well,
> but depending on what you want, it's not that involved.  For example to
> implement instantiation and inheritence using metatables:
> 
> 
> 
>> 
>> 
>> function inherits(parentMetatable, classMetatable)
>> return {
>> __index = setmetatable(classMetatable.__index, parentMetatable)
>> }
>> end
>> 
>> function new(classMetatable)
>> return setmetatable({}, classMetatable)
>> end
>> 
>> 
>> 
>> 
>> 
>> local Cat = {__index = {
>> shout = function(self)
>> print(self.sound)
>> end,
>> sound = "meow",
>> }}
>> 
>> local Lion = inherits(Cat, {__index = {
>> sound = "roar",
>> }})
>> 
>> 
>> local cat = new(Cat)
>> local lion = new(Lion)
>> 
>> 
>> 
>> 
>> cat:shout()
>> lion:shout()
>> 
>> 
>> 
> 
> 
> 
> Another approach using prototypes:
> 
> 
> 
>> function inherits(parentPrototype, classPrototype)
>> for key, value in pairs(parentPrototype) do
>> if classPrototype[key] == nil then
>> classPrototype[key] = value
>> end
>> end
>> return classPrototype
>> end
>> 
>> function new(classPrototype)
>> return inherits(classPrototype, {})
>> end
>> 
>> local Cat = {
>> shout = function(self)
>> print(self.sound)
>> end,
>> sound = "meow",
>> }
>> 
>> local Lion = inherits(Cat, {
>> sound = "roar",
>> })
>> 
>> local cat = new(Cat)
>> local lion = new(Lion)
>> 
>> cat:shout()
>> lion:shout()
> 
> 
> 
> Or – maybe the best choice for non-trivial cases – a constructor based
> approach, which allows better object initialization and registering of
> super stuff, where needed:
> 
> 
> 
>> 
>> 
>> function Cat()
>> -- "Constructor" that just creates an object and returns it
>> return {
>> shout = function(self)
>> print(self.sound)
>> end,
>> sound = "meow",
>> }
>> end
>> 
>> function Lion()
>> -- "Constructor" that initializes an object
>> local lion = Cat()
>> local super_shout = lion.shout
>> lion.shout = function(self)
>> -- Just to demonstrate use of a "super" method.
>> super_shout(self)
>> print "roar"
>> end
>> return lion
>> end
>> 
>> 
>> local cat = Cat()
>> local lion = Lion()
>> 
>> cat:shout()
>> lion:shout()
>> 
>> 
>> 
> 
> 
> 
> I think the question should be, what do you actually need and what is a
> good way to achieve it in Lua.  Do I only need composition and
> encapsulation?  Then that's sort of supported with Lua's tables out of the
> box.  Do I need inheritance?  That's also possible, as the approaches
> above show.  I just have to pick one that works for me.  If an equivalent
> of an "instanceof" operator is needed, then that can be implemented, too,
> with a bit of creativity.
> 
> 
> 
> 
> There is also "official" material about OOP ( https:/ / www. lua. org/ pil/
> 16. html ( https://www.lua.org/pil/16.html ) ) and on the Lua wiki ( http:/
> / lua-users. org/ wiki/ ObjectOrientationTutorial (
> http://lua-users.org/wiki/ObjectOrientationTutorial ) ).
> 
> 
> 
> 
> Thomas Weber
> 
> 
> -- 
> 
> Notengrafik Berlin GmbH
> HRB 150007
> 
> UstID: DE 289234097
> Geschäftsführer:
> Thomas Weber und Werner J. Wolff
> 
> fon: +49 30 25359505
> Friedrichstraße 23a
> 10969 Berlin
> 
> notengrafik. com ( http://notengrafik.com/ )
> 
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://jwmusic.nu/pipermail/jwlua_jwmusic.nu/attachments/20210914/94781aa6/attachment.htm>


More information about the JWLua mailing list