Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[major fix] support ee.removeLisenter and ee.on('newListener')

  • Loading branch information...
commit c101aaeba233e5cdfdc57a8d614e473f8a5c5a83 1 parent f42b90f
Andreas Madsen authored

Showing 2 changed files with 135 additions and 0 deletions. Show diff stats Hide diff stats

  1. +29 0 hook.js
  2. +106 0 test/events.js
29 hook.js
@@ -131,14 +131,43 @@ function monkeyPatchMethod(prefix, root, name) {
131 131 // monkeypatch EventEmitter.once
132 132 var once = root.once;
133 133 root.once = function () {
  134 + var origin = arguments[1];
134 135 var args = eventHook._intercept('events.EventEmitter.once', arguments);
  136 +
  137 + // .listener is a little nodejs secret, there makes removeListener work
  138 + // when monkey-patching an event handler.
  139 + args[1].listener = origin;
  140 +
135 141 return once.apply(this, args);
136 142 };
137 143
138 144 // monkeypatch EventEmitter.on and EventEmitter.addListener
139 145 var on = root.on;
140 146 root.on = root.addListener = function () {
  147 + var origin = arguments[1];
  148 +
  149 + // if .on was called from .once
  150 + if (typeof origin.listener === 'function') {
  151 +
  152 + // restore the input function attachment
  153 + if (typeof origin.listener.listener === 'function') {
  154 +
  155 + // origin will be a node internal g() function
  156 + // origin.lisenter will be attach(input);
  157 + // origin.lisenter.lisenter will be input;
  158 + // where input is event.once('name', input);
  159 + arguments[1].listener = origin.listener.listener;
  160 + }
  161 +
  162 + return on.apply(this, arguments);
  163 + }
  164 +
141 165 var args = eventHook._intercept('events.EventEmitter.on', arguments);
  166 +
  167 + // .listener is a little nodejs secret, there makes removeListener work
  168 + // when monkey-patching an event handler.
  169 + args[1].listener = origin;
  170 +
142 171 return on.apply(this, args);
143 172 };
144 173 })();
106 test/events.js
@@ -158,4 +158,110 @@ test("events hook", function (t) {
158 158 t.end();
159 159 });
160 160
  161 + t.test('e.once self removeing', function (t) {
  162 +
  163 + // attach a simple patcher
  164 + function eventAttach(name, callback) {
  165 + return function () {
  166 + callback.apply(this, arguments);
  167 + };
  168 + }
  169 + hook.event.attach(eventAttach);
  170 +
  171 + // expected to be executed
  172 + function boo() {
  173 + t.end();
  174 + }
  175 +
  176 + // create EventEmitter objecct
  177 + var e = new EventEmitter();
  178 +
  179 + // check that the final newListener is equal to boo
  180 + e.once('newListener', function (name, fn) {
  181 + t.equal(fn, boo);
  182 + });
  183 +
  184 + // add boo event handler
  185 + e.once('boo', boo, 'input fn was boo()');
  186 +
  187 + // expect boo to execute
  188 + e.emit('boo');
  189 +
  190 + // do not expect boo to execute
  191 + e.emit('boo');
  192 +
  193 + // cleanup
  194 + hook.event.deattach(eventAttach);
  195 + });
  196 +
  197 + t.test('e.once manual remove', function (t) {
  198 +
  199 + // attach a simple patcher
  200 + function eventAttach(name, callback) {
  201 + return function () {
  202 + callback.apply(this, arguments);
  203 + };
  204 + }
  205 + hook.event.attach(eventAttach);
  206 +
  207 + // do not expect this to execute
  208 + function boo() {
  209 + t.end();
  210 + }
  211 +
  212 + // create EventEmitter object
  213 + var e = new EventEmitter();
  214 +
  215 + // check that the final newLisenter is equal to boo
  216 + e.once('newListener', function (name, fn) {
  217 + t.equal(fn, boo, 'input fn was boo()');
  218 + });
  219 +
  220 + // do not expect boo to execute
  221 + e.once('boo', boo);
  222 + e.removeListener('boo', boo);
  223 + e.emit('boo');
  224 +
  225 + // cleanup
  226 + hook.event.deattach(eventAttach);
  227 +
  228 + // done
  229 + t.end();
  230 + });
  231 +
  232 + t.test('e.on manual remove', function (t) {
  233 +
  234 + // attach a simple patcher
  235 + function eventAttach(name, callback) {
  236 + return function () {
  237 + callback.apply(this, arguments);
  238 + };
  239 + }
  240 + hook.event.attach(eventAttach);
  241 +
  242 + // do not expect this to execute
  243 + function boo() {
  244 + t.end();
  245 + }
  246 +
  247 + // create EventEmitter object
  248 + var e = new EventEmitter();
  249 +
  250 + // check that the final newLisenter is equal to boo
  251 + e.once('newListener', function (name, fn) {
  252 + t.equal(fn, boo, 'input fn was boo()');
  253 + });
  254 +
  255 + // do not expect boo to execute
  256 + e.on('boo', boo);
  257 + e.removeListener('boo', boo);
  258 + e.emit('boo');
  259 +
  260 + // cleanup
  261 + hook.event.deattach(eventAttach);
  262 +
  263 + // done
  264 + t.end();
  265 + });
  266 +
161 267 });

0 comments on commit c101aae

Please sign in to comment.
Something went wrong with that request. Please try again.