Only a heads up on this, I have solved most of the issues by
using Webpack:
- Imports mechanism is replaced with ES6 imports, by defining
the target library to UMD for webpack this should be a problem.
Webpack creates a single extension file with all the needed
configurations.
- Since we are using ES6 imports now, there's no problem while
testing. Karma has to be setup with support for webpack though.
- The GS polyfill is still needed for tests to run correctly.
- The GS API remains, although I found a library for tracking
signals online, it was not documented and the repository for it
was actually removed.
- Integration testing is still not possible.
- Tests run now on PhantomJS. For this, I had to use a
transpiler (babel) with webpack. This has the added benefit of
generating JS code that is backwards compatible between GS
versions, while allowing us to use ES6 features.
- This was all integrated with Travis CI (see the github repo
for reference).
NOTE: I had to keep classes that extend native GS classes using
Lang.Class instead of ES6 classes, because there were some
problems with the transpiled code when calling super constructors.
If you are not using a transpiler for releases, all classes can be
refactored to ES6.
I hope this helps anyone trying to provide quality code for
GJS/GSE.
Regards.
On 27/11/17 11:08, Edgar Merino wrote:
Hello:
Recently, while solving some problems with an extension I
created when upgrading gnome shell, I realized there's no way to
actually perform tests on GSE code. I'm an agile advocate, so
for most of the work I do I always rely on tests (unit tests and
integration tests mostly). So, I spent the last couple of days
working on refactoring the code for the extension, and I
introduced unit testing using npm/karma/jasmine/firefox. You can
see the whole code in this github repository:
https://github.com/emerinohdz/power-alt-tab
There where a couple of issues I encounter:
- GS uses an "imports" mechanism, in order to include a script
into another. This was solved by using a really simple "class
finder" (defined under utils.js). The implementation is not
really pleasant, it requires so called "classes" to be
manually declared (and they should be declared according to
order of use). The idea is that you can use something like
'const MyClass = Utils.use("gs.MyClass")' to include MyClass
into your current script. It would be wonderful if GS included
this sort of functionality out of the box, and maybe include
something like "autoloaders" which can be defined depending on
the environment where the code is being run (e.g. under
firefox for unit testing or under real GS enviroment). Or
maybe implementing something like AMD?
- For unit testing (with karma), all the code is read when
tests run, this presented a problem with the way GS loads
scripts, because using "const" globally presented problems
when running under karma, while it was needed for GS. What I
did here consisted on using self executing functions to
provide a narrower scope for each script, so now "const" could
be declared on every script without problems when running
under karma.
- For unit testing to work fine, I had to include a GS
polyfill (test/polyfill_gs.js). This polyfill only covers what
I needed, the way I needed it, mostly mocking every global GS
object needed.
- I've worked on a really small GS API (which is by no means
complete), located under "src/gs". The idea here is to have a
higher level API to work with, which will handle most of the
low level stuff. This additional layer would help with changes
made to the lower level APIs, since extensions can be coded
against this higher level GS API which should not change
often. I only included a GS screen wrapper and a signal
tracker (for tracking signal connect/disconnect). Things like
keybinding could be included in the API too, and many other
facilities I'm not using with my extension too. This should be
an additional effort, but well worth it IMO.
- Integration testing was not possible, this would be a huge
step forward. Right now it is becoming harder to test the
extension on a real GS environment, you have to revert to some
sort of virtual environment, specially if using Wayland (where
restarting GS is not possible). Providing some type of test
API where things could be integrated and tested before moving
to production would mean faster delivery of new functionality
IMO. This is of course the greatest challenge.
- I had to use firefox, in order to use some of the ES6
features, but things can be worked out to include an ES5/5
polyfill to use PhantomJS (not tested).
NOTE: I used constructor functions instead of Lang.Class to
define so called "classes" for most of my code, but it's not a
problem to use Lang.Class, as you can see here
"src/nuevebit/workspace_switcher_popup.js".
I don't know if this is something the GSE devs are
interested in taking a look at, I would be more than glad to
contribute to this project if needed.
Regards.
Edgar Merino
|