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

Convert mocking to mockable imports (3/4) #1086

Merged
merged 3 commits into from
May 1, 2019
Merged

Conversation

robertknight
Copy link
Member

This is a follow-up to #1061 which converts remaining uses of proxyquire in .coffee files to use $imports.$mock instead - see earlier PR for a detailed explanation.

After this PR and #1085 are merged, the final PR will remove proxyquire as a dependency.

@@ -37,7 +38,7 @@ module.exports = class Guest extends Delegator
TextSelection: {}

# Anchoring module
anchoring: require('./anchoring/html')
anchoring: htmlAnchoring
Copy link
Member Author

Choose a reason for hiding this comment

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

The new approach to mocking only currently supports dependencies declared at the top level of the module, so this hoists the require to the top of the file. This is needed anyway if we later convert this module to JS with import and export statements, since import can only appear at the top level as well.

@codecov
Copy link

codecov bot commented Apr 23, 2019

Codecov Report

Merging #1086 into master will increase coverage by <.01%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1086      +/-   ##
==========================================
+ Coverage   92.25%   92.26%   +<.01%     
==========================================
  Files         156      156              
  Lines        6136     6138       +2     
  Branches      975      975              
==========================================
+ Hits         5661     5663       +2     
  Misses        475      475
Impacted Files Coverage Δ
src/annotator/guest.coffee 79.73% <100%> (+0.18%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 6a9248a...6e2fc70. Read the comment docs.

yarn.lock Outdated
integrity sha512-KqKIFsPDQcXf2XZZazAxGa7xUgbGueLfCQb4mD7G16lvLYfz13SakC6IAcRaBueXwNn2O0K6VGlXZzPs0aLL3Q==
version "1.3.0"
resolved "https://registry.yarnpkg.com/babel-plugin-mockable-imports/-/babel-plugin-mockable-imports-1.3.0.tgz#29183a735fc3a27395b15b519e059fba7f61fde4"
integrity sha512-1kUED0ZXOLMKh1P90zHX9juD6IRWXgMB5yPtdupsaTJ9lKueAdGmRsuMnKXOlqtyaMYCW6oKwSz/gFLpiXaONA==

Copy link
Member Author

Choose a reason for hiding this comment

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

This update resolves an issue with the way CoffeeScript compiles groups of <name> = require(<module>) statements.

}
htmlAnchoring = {
anchor: sinon.stub()
}

Copy link
Member Author

Choose a reason for hiding this comment

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

This ensures that the mocks for the highlighter and HTML anchoring modules are initialized for each test, for consistency with how we set up mocks in other tests.

Convert proxyquire mocking of several CoffeeScript modules.
Note that the exports of the `anchoring/html` module are captured when
the class is constructed, so cannot be mocked later via `$imports`.
Instead the created `Guest` object has to be monkey-patched.
@robertknight robertknight force-pushed the mockable-imports-part-3 branch from f32ac48 to 403bbda Compare April 30, 2019 13:19
Copy link

@hmstepanek hmstepanek left a comment

Choose a reason for hiding this comment

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

I had a question about one of the previously mocked imports being moved. Otherwise looks good!


createGuest = (config={}) ->
config = Object.assign({}, guestConfig, config)
element = document.createElement('div')
return new Guest(element, config)
guest = new Guest(element, config)
guest.anchoring = htmlAnchoring

Choose a reason for hiding this comment

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

Why is this here instead of in the mocked imports? This feels hacky to me.

Copy link
Member Author

Choose a reason for hiding this comment

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

This is necessary because guest.anchoring is initialized when the module is first evaluated, and so isn't affected by mocking that happens later. That's one limitation of this approach to mocking. See this node in the mocking plugin's README. The same issue applies to patch in Python.

An alternative solution would be to use constructor injection. Something conceptually like this:

class Guest(element, config, anchoring = htmlAnchoring) {
   this.anchoring = anchoring
}

With this approach, the default initialization expression is evaluated when the Guest constructor is called, so mocking would work.

Copy link
Member Author

Choose a reason for hiding this comment

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

I've pushed a change which does this to handle the issue in a cleaner way ^

This enables mocking of the `anchoring/html` module in tests without having
to patch the `anchoring` property after the class is constructed.
@robertknight robertknight requested a review from hmstepanek May 1, 2019 07:45
@hmstepanek hmstepanek merged commit b2ad6fb into master May 1, 2019
@hmstepanek hmstepanek deleted the mockable-imports-part-3 branch May 1, 2019 16:55
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.

2 participants