Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: refactor handlebars into template literals. #978

Closed
wants to merge 3 commits into from

Conversation

aorinevo
Copy link

@aorinevo aorinevo commented Mar 27, 2020

Changes

  • replace handlebards with natively supported template strings in a backwards compatible fashion.
  • feature is hidden behind a feature flag. To enable simply set enableTemplateStringHTMLReporter to 'true' in .labrc.js.
  • add lint to scripts.

Notes

  • dependent on approval of open issue Replace Handlebars with Template Strings #977
  • while this PR adds 1069 lines of code, ~185 correspond to unit tests. In addition, 714 lines of code can be removed once we/if backwards compatibility is dropped. More related stats:
    • hapijs:master branch consists of 95.5% javascript, 3.8% html, and 0.7% other.
    • aorinevo:replace_handlebars branch consists of 95.5% javascript, 3.9% html, and 0.7% other.
    • Percentage of html can go down to 0% once/if backwards compatibility is dropped.
  • handlebars package can be removed from package.json once/if backwards compatibility is dropped.

package.json Outdated Show resolved Hide resolved
test.html Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
lib/reporters/index.js Outdated Show resolved Hide resolved
test/reporters.js Outdated Show resolved Hide resolved
@aorinevo
Copy link
Author

Status update:

  • Fix 5 of 13 failing tests.
  • Need to increase coverage on new js files.

@aorinevo
Copy link
Author

Status update:

  • Only 2 tests left to fix.
  • Still need to increase coverage for new js files.

@@ -15,3 +15,7 @@
- [Changelog](https://hapi.dev/family/lab/changelog/)
- [Project policies](https://hapi.dev/policies/)
- [Free and commercial support options](https://hapi.dev/support/)


# Notes
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove

@@ -1427,7 +1614,7 @@ describe('Reporter', () => {
'<td class="source"><div> while ( </div><div class="miss false" data-tooltip>value ) </div><div>{</div></td>']);
expect(output, 'missed original line not included').to.contains([
'<tr id="while.js__14" class="miss">',
'<td class="source" data-tooltip> value &#x3D; false;</td>']);
'<td class="source" data-tooltip> value = false;</td>']);
Copy link
Author

@aorinevo aorinevo Mar 28, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fails with feature flag off but passes with feature flag on.

It is possible to wrap this in the feature flag as well, but not sure it is worth the effort (see #977 (comment)).

@aorinevo
Copy link
Author

All tests pass and coverage is at 100% with feature flag on. There is one unit test that fails with feature flag off. While it is possible to change the test to be backwards compatible, it might not be worth the effort (see #977 (comment)).

Copy link

@jugaltheshah jugaltheshah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not familiar with this codebase but mostly LGTM and minor suggestions. Only saw once potential issue (potential off by one).

.labrc.js Outdated
@@ -0,0 +1,3 @@
module.exports = {
enableTemplateStringHTMLReporter: 'true'
};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

EOL


exports.scripts = () => {

return `<script>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: extra tab / spaces?

var links = document.querySelectorAll('#menu a')
, link;

for (var i = 0, len = links.length; i < len; ++i) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
for (var i = 0, len = links.length; i < len; ++i) {
for (var i = 0; i < links.length; ++i) {

This seems like it would be slightly simpler.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Property lookup for links.length each and every time through the loop is wasteful, as the value doesn't change during the execution of the loop. By storing the value on len var we avoid subsequent lookups.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Array lookups are O(C) so either one should be equivalent. The advice in the link shared is specifically with regards to property lookups, which have the potential for additional costs due to needing to look up the prototype chain if local lookup fails.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, I think I miunderstood. The idea is to make it a constant-time lookup rather than looking up the property on an Array object. The point I believe still stands though bc JS engines optimize for these sorts of things. E.g. see https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JIT_Optimization_Strategies.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JIT compilation is eventually performant. First the JIT compiler needs to identify warm and hot code segments. The warm code segments get sent to a baseline compiler and reused by the compiler where possible. The hot code segments get sent to an optimizing compiler to be used until the assumptions under which the hot code was identified are invalidated at which point the optimized code is discarded (see https://blog.logrocket.com/how-javascript-works-optimizing-the-v8-compiler-for-efficiency/).

TL;DR there is a performance hit initially but indistinguishable for n sufficiently large, where n is the right hand of the for-loop conditional.


function find (y) {
var i = headings.length
, heading;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what's happening here, bit oddly formatted.

var i = headings.length
, heading;

while (i--) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this would exit when i === 0, does headings[0] not need to be processed?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 does get processed. The while Evals then the -1 is done

lib/reporters/html/partials/scripts.js Show resolved Hide resolved
lib/reporters/html/partials/scripts.js Show resolved Hide resolved
lib/reporters/html/partials/scripts.js Show resolved Hide resolved
package.json Outdated Show resolved Hide resolved
aorinevo and others added 2 commits March 28, 2020 21:23
Co-Authored-By: Jugal S <jugaltheshah@users.noreply.github.com>
@aorinevo
Copy link
Author

Closing this PR for now as the vulnerability was addressed through a combination of PRs to Handlebars:

@aorinevo aorinevo closed this Apr 10, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants