Unit testing and NodeJS with SugarCube2?

tweego, version 2.1.1+81d1d71 (2020-02-25T07:09:26Z) [darwin/amd64] “name”:“SugarCube”,“version”:“2.36.1”

I understand that SugarCube is built on NodeJS. I also understand that NodeJS has some idioms such as export modules and the require keyword (e.g. Node.js Export Module). I’m new to NodeJS as well as SugarCube, and I’d like to use NodeJS and additionally unit testing for my JavaScript.

Can anyone provide a working example with this technology? Thanks!

1 Like

To clarify….

If, by “built on Node”, you meant that SugarCube has dependencies upon Node—i.e., integrating Node libraries or other Node-isms in some way—then no, SugarCube is not built on Node.

If you meant that SugarCube’s build script has Node dependencies, then yes, that would be correct.

In other words, SugarCube itself has no Node dependencies, rather its build script does—in Node parlance those called development dependencies.

Oh I didn’t realise it was for the build scripts. Alright, thank you.

Concerning the unit testing? Any possibility about that?

Good question, I’ve been trying to do something along the same lines! The NodeJS integration, not the unit testing, so I can use TypeScript in a Sugarcube game. Haven’t made that much progress but I did find a convoluted way to use JS written in a Node environment with Sugarcube. Don’t know how useful this will be, it also may be slightly inaccurate, but:

Node and browser JS are different, so I used Browserify (https://browserify.org/) to convert my Node stuff to something that the browser/Sugarcube can understand.

Download that into your Node environment. Then based on this StackOverflow question (node.js - Browserify - How to call function bundled in a file generated through browserify in browser - Stack Overflow) use Browserify to export the JS file you want with the standalone option (e.g. command I ran was something like npx browserify nodeJavascriptFile.js --s moduleName > jsFileToUseWithSugarcube.js but might be different if you use Windows). That gives you one Javascript file, jsFileToUseWithSugarcube.js (or whatever you decide to call it), that should have all the stuff you need in it.

Then in your Sugarcube project, put importScripts("jsFileToUseWithSugarcube.js") in your javascript. (You can’t just put <script src="jsFileToUseWithSugarcube.js"> in StoryInit because it doesn’t work for some reason. Guessing either it interferes with Sugarcube’s own scripts or I screwed up somewhere.)

According to the StackOverflow question (and my own testing), there should now be an object window.moduleName that you can access globally (e.g. from the developer tools console) which provides you access to all the stuff in the Node javascript that you bundled into the one jsFileToUseWithSugarcube.js using Browserify.

So you can access it by placing something like this in a passage:

<<done>>
<<script>>
console.log(window.moduleName.stringWhatever);
<</script>>
<</done>>

Or if you want another example -

State.variables.test = 

:: Main [Menu] {"position":"100,200","size":"100,100"}

[[testPassage]]

<<done>>
<<script>>
State.variables.test = window.moduleName.stringWhatever;
<</script>>
<</done>>


:: testPassage {"position":"275,200","size":"100,100"}
$test

So if you exported stringWhatever back in your original Node JS file, now you can access it from the JS in Sugarcube/Twine.

(I put <<done>> in front of <<script>> so the stuff in <<script>> only executes once the passage is done loading, which is useful since it can take time to import stuff with importScripts. If the script tries to execute before you’re done importing the jsFileToUseWithSugarcube.js then it won’t work.)


Sorry if all that’s confusing, been meaning to put the thing I’m making onto Github so it might be useful as an example?

As for unit tests, I imagine they’d be specific to what you’re doing so you’d probably have to write your own. If you could get the Node integration to work I feel like you could make a file in the Node environment with functions dedicated to unit tests. Not that I’m experienced with this kind of thing!

Edit: Oh yeah, I just discovered that this (GitHub - ChapelR/tweego-setup: A Tweego project boilerplate.) exists, so you might want to take a look at that. Would’ve saved me a lot of trouble if I’d found it earlier…

Edit 2: Actually, I’m not sure if that repo has support for using Node in Twine, it might just use Node to build the Twine game. Too lazy to check right now though.

It would probably make sense to unit test a Twine story with a browser-based testing framework like Puppeteer.

1 Like

That would depend on what your JavaScript is and does. If it’s not dependent upon browser features in any way, then you should be able to test it in isolation, mocking SugarCube APIs as necessary. Elsewise, you’ll probably want a browser-based testing solution—e.g., the aforementioned Puppeteer.

 

SugarCube has TypeScript definitions via Definitely Typed (@types/twine-sugarcube). As shown in the documentation you can install the package via NPM using the following command:

npm install --save-dev @types/twine-sugarcube

From there you just need to transpile your TypeSscript code to JavaScript and get it into your project somehow. What the code is and does will determine whether it needs to be loaded within SugarCube’s own scope or globally.

1 Like