New version
Here comes the new version:
- Stories and bugs implemented
- Sources
- Documentation
- NPM package
Release content
Sporadic Travis issues
From time to time, the Travis continuous integration build was failing with a message indicating that the coverage information was missing for the browser. Here is a recent example.
I was first suspecting the concurrent execution of quality checks to be the root cause of the issue. I disabled it but, still, the problem persisted.
So, I took a closer look on how the coverage information was generated while executing tests in the browser.
In the Travis environment, chrome is spawned as a command line with options to disable user interface. When the tests are completed, an AJAX request is triggered to save the tests results through the cache middleware. In the meantime a command line, responsible of spawning the browser, waits for the cache to be updated before closing the process.
Also, the test page is responsible of saving the coverage information through another AJAX request that goes to fs middleware.
I realized that the sequence was incorrect: the tests results were sent before the coverage information. The two steps are now executed in the correct order.
Improved gpf.require namespace
The modularization helper was improved following the feedback obtained after the first use:
- Errors are better documented to help the developer figure what went wrong and where
- Loaded files now appear inside the browser debugger. The trick consisted in augmenting the file content with a SourceURL information
gpf.require.js
Flavor specification
In the previous version, the dependency wheel was added to the source tile to give a visual representation of the dependencies. Also, each source file has been documented with 'tags' qualifying the feature or the host the source relates to.
Sources without any flavor selection
Also, in the previous version, a syntax was initiated to instruct, in a readable way, which sources should be kept for a given flavor. Combining the features list, hosts specification and dependencies, an algorithm - not my proudest one - is capable of generating an array of booleans filtering the list of sources.
As a result, the list of sources is reduced to meet the flavor specification.
Sources with a flavor selection
Everything was ready to setup the require flavor specification, it contains:
- The version in which the flavor was introduced: it is required to build the versions table in the readme page
- The flavor filter string
- The tests required to validate the flavor
- A functional description of the flavor: it will be used to document flavors (not yet implemented)
- A technical description of the exposed API: the goal is to narrow down the list of namespaces / methods that are exposed by the flavor (not yet implemented)
Reducing flavor size
The very first results were quite disappointing:
- NodeJS implementation of require depended on gpf.fs, almost the whole library was included (gpf.define, gpf.interfaces, gpf.stream, ...). So I decided to isolate gpf.fs.read into a smaller read feature.
- The same way, Browser implementation of require depends on gpf.http to load the resource content. This namespace offers a mocking helper that is not needed for require. The code had to be drastically changed to successfully unplug this source.
Testing the flavor
There is no way the flavor could be officially released without making sure it works as expected. Luckily, the whole library is already 100% tested. Since the flavor description lists the test files to run, the development framework was altered to support a flavor parameter that:
- loads the flavor output file
- loads and executes the necessary test files
Mostly, the following files were modified:
- test/host/web_loader.js: as it takes care of browsers tests execution
- test/host/loader.js: as it takes care of the other - command line type - hosts
- grunt/exec.js: it declares all the exec:test tasks
- grunt/concurrent.js: it creates tasks to run all tests for a given version or flavor
Obviously, the grunt make task that schedules all the tasks required to build the version was also modified.
Lessons learned
Creating this first flavor was quite an interesting challenge and it took longer than expected. It forced me to rethink the way the code is articulated, especially with regards to host specific implementations.
The original pattern consisted in dictionaries containing operations indexed by host name. However, this had a major drawback: every time it was accessed, it was uselessly impacting the performances and producing complex code.
Now, when appropriate, a new helper is introduced to define the proper implementation depending on the host.
Here is the gpf.http use case:
- _gpfHttpSetRequestImplIf sets the http request method if the provided host matches the detected one
- NodeJS' implementation call
Regarding gpf.http.mock, I decided to plug it in the gpf.http implementation only when loaded, improving its modularity.
All this work paid, the maintainability ratio increased to 82.22.
One last thing, the require flavor supports only 'modern' browsers meaning the ones where the compatibility layer is not required. However, as of now, the development framework does not distinguish the configured browsers.
A configuration will be defined.
Next release
The next release content is not yet clearly defined. Since I will participate to UICon'18 as a presenter, I will first focus on delivering a good presentation.
I expect to work again on the library after June.
No comments:
Post a Comment