"All this" is some CoffeeScript specs (using Jasmine via Jasminerice) and code to exercise the Medialize ContextMenu jQuery plugin, through a thin wrapper class.
Specifically, this Gist contains source and spec files demonstrating the main problem that led to the filing of this issue on the jQuery-contextMenu
project.
Seemingly logically enough, during spec setup we want to set up and display the menu, and during (later) spec teardown we want to remove any of the effects induced by showing and acting upon it. Therein lies the current problem: as noted in the comments within the spec snippet (immediately following), I've tried half a dozen ways to restore the state of the menu <ul>
container and contents to its original state. None have worked. Witbout being able to "clean up" after ourselves, many things we would like to do in tests using Jasmine (or other similar frameworks) become unwieldy at best.
Simply put, we need to be able to restore the DOM to its initial state and prove it.
- Calls to
$.contextMenu('hide')
, as per the docs - Triggering another
contextmenu
DOM event (theory being that since triggering that event shows the menu, it might act as a toggle. Nope.) - Triggering a
mousedown
event, or amousedown
event followed by amouseup
event; both events being sent to the document body. - Triggering a
keypress
event on the document body
Following this introduction are three files that should help anyone trying to help solve the problem:
ContextMenuSpec-snippet.js.coffee
is a subset of the full Jasmine spec file for the source; it includes the shared setup and the single spec demonstrating the problem;ContextMenu.js.coffee
is my wrapper class around the jQuery context-menu pluginContextMenuSpec.js.coffee
is the (current, incomplete) full Jasmine spec file excerpted in the first attachment.
Not included here is the source of the actual ContextMenu plugin; it may be retrieved from here or here.
Why bother wrapping a CoffeeScript class around the thing? I wasn't always using this plugin for my context menu; putting it in was a direct result of ripping out a previous plugin that had proven unsuitable (precisely which one isn't currently relevant). My long-held coding practices, which heavily inform our evolving shop standards, require that replacing an outside component requires wrapping it in a class or module for that project, so that any later changes to yet another outside component should require no code changes outside that code (and its specs, of course). Therefore, wrapping it in a class allows me to do two things that aren't nearly as practical:
- Define and enforce the usage I would make of the wrapped component; and
- Trivially prove that later releases of the wrapped component (or its replacement) would have no impact on my code (since it's written to my wrapper's API, not the component's).
Neither of these can be reliably done without some form of home-grown encapsulation/abstraction.
Because Gists, unlike issue reports, have no Preview
button. All changes after this Gist was created have been to this description, not to any of the attached code.