[Pkg-javascript-commits] [node-eventemitter2] 01/01: Initial import of node-eventemitter2 version 0.4.13

matthew pideil mpideil-guest at moszumanska.debian.org
Sat Mar 29 18:27:40 UTC 2014


This is an automated email from the git hooks/post-receive script.

mpideil-guest pushed a commit to branch master
in repository node-eventemitter2.

commit ca0a524a3b7a080fbad4c894cc191544bb274a7e
Author: Matthew Pideil <matthewp_debian at teledetection.fr>
Date:   Sat Mar 29 18:16:17 2014 +0000

    Initial import of node-eventemitter2 version 0.4.13
---
 README.md                              | 212 +++++++++++++
 bower.json                             |   6 +
 index.js                               |   1 +
 lib/eventemitter2.js                   | 561 +++++++++++++++++++++++++++++++++
 package.json                           |  29 ++
 test/common.js                         | 127 ++++++++
 test/perf/benchmark.js                 |  53 ++++
 test/simple/addListener.js             | 179 +++++++++++
 test/simple/emit.js                    | 142 +++++++++
 test/simple/reconfigure.js             |  55 ++++
 test/simple/removeListener.js          | 196 ++++++++++++
 test/simple/setMax.js                  | 135 ++++++++
 test/simple/ttl.js                     | 115 +++++++
 test/wildcardEvents/addListener.js     | 338 ++++++++++++++++++++
 test/wildcardEvents/all.js             | 248 +++++++++++++++
 test/wildcardEvents/customDelimiter.js | 250 +++++++++++++++
 test/wildcardEvents/k1.js              |  56 ++++
 test/wildcardEvents/options.js         |  72 +++++
 test/wildcardEvents/removeListener.js  | 348 ++++++++++++++++++++
 test/wildcardEvents/ttl.js             | 223 +++++++++++++
 20 files changed, 3346 insertions(+)

diff --git a/README.md b/README.md
new file mode 100644
index 0000000..9501fa3
--- /dev/null
+++ b/README.md
@@ -0,0 +1,212 @@
+# EventEmitter2
+
+EventEmitter2 is an implementation of the EventEmitter found in Node.js
+
+## Features
+
+ - Namespaces/Wildcards.
+ - Times To Listen (TTL), extends the `once` concept with `many`.
+ - Browser environment compatibility.
+ - Demonstrates good performance in benchmarks
+
+```
+EventEmitterHeatUp x 3,728,965 ops/sec \302\2610.68% (60 runs sampled)
+EventEmitter x 2,822,904 ops/sec \302\2610.74% (63 runs sampled)
+EventEmitter2 x 7,251,227 ops/sec \302\2610.55% (58 runs sampled)
+EventEmitter2 (wild) x 3,220,268 ops/sec \302\2610.44% (65 runs sampled)
+Fastest is EventEmitter2
+```
+
+## Differences (Non breaking, compatible with existing EventEmitter)
+
+ - The constructor takes a configuration object.
+ 
+```javascript
+    var EventEmitter2 = require('eventemitter2').EventEmitter2;
+    var server = new EventEmitter2({
+      wildcard: true, // should the event emitter use wildcards.
+      delimiter: '::', // the delimiter used to segment namespaces, defaults to `.`.
+      newListener: false, // if you want to emit the newListener event set to true.
+      maxListeners: 20, // the max number of listeners that can be assigned to an event, defaults to 10.
+    });
+```
+
+ - Getting the actual event that fired.
+
+```javascript
+    server.on('foo.*', function(value1, value2) {
+      console.log(this.event, value1, value2);
+    });
+```
+
+ - Fire an event N times and then remove it, an extension of the `once` concept.
+
+```javascript
+    server.many('foo', 4, function() {
+      console.log('hello');
+    });
+```
+
+ - Pass in a namespaced event as an array rather than a delimited string.
+
+```javascript
+    server.many(['foo', 'bar', 'bazz'], function() {
+      console.log('hello');
+    });
+```
+
+
+## API
+
+When an `EventEmitter` instance experiences an error, the typical action is
+to emit an `error` event. Error events are treated as a special case.
+If there is no listener for it, then the default action is to print a stack
+trace and exit the program.
+
+All EventEmitters emit the event `newListener` when new listeners are
+added.
+
+
+**Namespaces** with **Wildcards**
+To use namespaces/wildcards, pass the `wildcard` option into the EventEmitter constructor.
+When namespaces/wildcards are enabled, events can either be strings (`foo.bar`) separated
+by a delimiter or arrays (`['foo', 'bar']`). The delimiter is also configurable as a 
+constructor option.
+
+An event name passed to any event emitter method can contain a wild card (the `*` character).
+If the event name is a string, a wildcard may appear as `foo.*`. If the event name is an array, 
+the wildcard may appear as `['foo', '*']`.
+
+If either of the above described events were passed to the `on` method, subsequent emits such 
+as the following would be observed...
+
+```javascript
+   emitter.emit('foo.bazz');
+   emitter.emit(['foo', 'bar']);
+```
+
+
+#### emitter.addListener(event, listener)
+#### emitter.on(event, listener)
+
+Adds a listener to the end of the listeners array for the specified event.
+
+```javascript
+    server.on('data', function(value1, value2, value3 /* accepts any number of expected values... */) {
+      console.log('The event was raised!');
+    });
+```
+
+```javascript
+    server.on('data', function(value) {
+      console.log('The event was raised!');
+    });
+```
+
+#### emitter.onAny(listener)
+
+Adds a listener that will be fired when any event is emitted.
+
+```javascript
+    server.onAny(function(value) {
+      console.log('All events trigger this.');
+    });
+```
+
+#### emitter.offAny(listener)
+
+Removes the listener that will be fired when any event is emitted.
+
+```javascript
+    server.offAny(function(value) {
+      console.log('The event was raised!');
+    });
+```
+
+#### emitter.once(event, listener)
+
+Adds a **one time** listener for the event. The listener is invoked only the first time the event is fired, after which it is removed.
+
+```javascript
+    server.once('get', function (value) {
+      console.log('Ah, we have our first value!');
+    });
+```
+
+#### emitter.many(event, timesToListen, listener)
+
+Adds a listener that will execute **n times** for the event before being removed. The listener is invoked only the first time the event is fired, after which it is removed.
+
+```javascript
+    server.many('get', 4, function (value) {
+      console.log('This event will be listened to exactly four times.');
+    });
+```
+
+
+#### emitter.removeListener(event, listener)
+#### emitter.off(event, listener)
+
+Remove a listener from the listener array for the specified event. **Caution**: changes array indices in the listener array behind the listener.
+
+```javascript
+    var callback = function(value) {
+      console.log('someone connected!');
+    };
+    server.on('get', callback);
+    // ...
+    server.removeListener('get', callback);
+```
+
+
+#### emitter.removeAllListeners([event])
+
+Removes all listeners, or those of the specified event.
+
+
+#### emitter.setMaxListeners(n)
+
+By default EventEmitters will print a warning if more than 10 listeners are added to it. This is a useful default which helps finding memory leaks. Obviously not all Emitters should be limited to 10. This function allows that to be increased. Set to zero for unlimited.
+
+
+#### emitter.listeners(event)
+
+Returns an array of listeners for the specified event. This array can be manipulated, e.g. to remove listeners.
+
+```javascript
+    server.on('get', function(value) {
+      console.log('someone connected!');
+    });
+    console.log(console.log(server.listeners('get')); // [ [Function] ]
+```
+
+#### emitter.listenersAny()
+
+Returns an array of listeners that are listening for any event that is specified. This array can be manipulated, e.g. to remove listeners.
+
+```javascript
+    server.onAny(function(value) {
+      console.log('someone connected!');
+    });
+    console.log(console.log(server.listenersAny()[0]); // [ [Function] ] // someone connected!
+```
+
+#### emitter.emit(event, [arg1], [arg2], [...])
+
+Execute each of the listeners that may be listening for the specified event name in order with the list of arguments.
+
+## Test coverage
+
+There is a test suite that tries to cover each use case, it can be found <a href="https://github.com/hij1nx/EventEmitter2/tree/master/test">here</a>.
+
+## Licence
+
+(The MIT License)
+
+Copyright (c) 2011 hij1nx <http://www.twitter.com/hij1nx>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/bower.json b/bower.json
new file mode 100644
index 0000000..e2d68fc
--- /dev/null
+++ b/bower.json
@@ -0,0 +1,6 @@
+{
+  "name": "eventemitter2",
+  "version": "0.4.13",
+  "description": "A Node.js event emitter implementation with namespaces, wildcards, TTL and browser support.",
+  "main": "lib/eventemitter2.js"
+}
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..6f583b5
--- /dev/null
+++ b/index.js
@@ -0,0 +1 @@
+module.exports = require('./lib/eventemitter2');
diff --git a/lib/eventemitter2.js b/lib/eventemitter2.js
new file mode 100644
index 0000000..dc9849e
--- /dev/null
+++ b/lib/eventemitter2.js
@@ -0,0 +1,561 @@
+;!function(exports, undefined) {
+
+  var isArray = Array.isArray ? Array.isArray : function _isArray(obj) {
+    return Object.prototype.toString.call(obj) === "[object Array]";
+  };
+  var defaultMaxListeners = 10;
+
+  function init() {
+    this._events = {};
+    if (this._conf) {
+      configure.call(this, this._conf);
+    }
+  }
+
+  function configure(conf) {
+    if (conf) {
+
+      this._conf = conf;
+
+      conf.delimiter && (this.delimiter = conf.delimiter);
+      conf.maxListeners && (this._events.maxListeners = conf.maxListeners);
+      conf.wildcard && (this.wildcard = conf.wildcard);
+      conf.newListener && (this.newListener = conf.newListener);
+
+      if (this.wildcard) {
+        this.listenerTree = {};
+      }
+    }
+  }
+
+  function EventEmitter(conf) {
+    this._events = {};
+    this.newListener = false;
+    configure.call(this, conf);
+  }
+
+  //
+  // Attention, function return type now is array, always !
+  // It has zero elements if no any matches found and one or more
+  // elements (leafs) if there are matches
+  //
+  function searchListenerTree(handlers, type, tree, i) {
+    if (!tree) {
+      return [];
+    }
+    var listeners=[], leaf, len, branch, xTree, xxTree, isolatedBranch, endReached,
+        typeLength = type.length, currentType = type[i], nextType = type[i+1];
+    if (i === typeLength && tree._listeners) {
+      //
+      // If at the end of the event(s) list and the tree has listeners
+      // invoke those listeners.
+      //
+      if (typeof tree._listeners === 'function') {
+        handlers && handlers.push(tree._listeners);
+        return [tree];
+      } else {
+        for (leaf = 0, len = tree._listeners.length; leaf < len; leaf++) {
+          handlers && handlers.push(tree._listeners[leaf]);
+        }
+        return [tree];
+      }
+    }
+
+    if ((currentType === '*' || currentType === '**') || tree[currentType]) {
+      //
+      // If the event emitted is '*' at this part
+      // or there is a concrete match at this patch
+      //
+      if (currentType === '*') {
+        for (branch in tree) {
+          if (branch !== '_listeners' && tree.hasOwnProperty(branch)) {
+            listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+1));
+          }
+        }
+        return listeners;
+      } else if(currentType === '**') {
+        endReached = (i+1 === typeLength || (i+2 === typeLength && nextType === '*'));
+        if(endReached && tree._listeners) {
+          // The next element has a _listeners, add it to the handlers.
+          listeners = listeners.concat(searchListenerTree(handlers, type, tree, typeLength));
+        }
+
+        for (branch in tree) {
+          if (branch !== '_listeners' && tree.hasOwnProperty(branch)) {
+            if(branch === '*' || branch === '**') {
+              if(tree[branch]._listeners && !endReached) {
+                listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], typeLength));
+              }
+              listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i));
+            } else if(branch === nextType) {
+              listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+2));
+            } else {
+              // No match on this one, shift into the tree but not in the type array.
+              listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i));
+            }
+          }
+        }
+        return listeners;
+      }
+
+      listeners = listeners.concat(searchListenerTree(handlers, type, tree[currentType], i+1));
+    }
+
+    xTree = tree['*'];
+    if (xTree) {
+      //
+      // If the listener tree will allow any match for this part,
+      // then recursively explore all branches of the tree
+      //
+      searchListenerTree(handlers, type, xTree, i+1);
+    }
+
+    xxTree = tree['**'];
+    if(xxTree) {
+      if(i < typeLength) {
+        if(xxTree._listeners) {
+          // If we have a listener on a '**', it will catch all, so add its handler.
+          searchListenerTree(handlers, type, xxTree, typeLength);
+        }
+
+        // Build arrays of matching next branches and others.
+        for(branch in xxTree) {
+          if(branch !== '_listeners' && xxTree.hasOwnProperty(branch)) {
+            if(branch === nextType) {
+              // We know the next element will match, so jump twice.
+              searchListenerTree(handlers, type, xxTree[branch], i+2);
+            } else if(branch === currentType) {
+              // Current node matches, move into the tree.
+              searchListenerTree(handlers, type, xxTree[branch], i+1);
+            } else {
+              isolatedBranch = {};
+              isolatedBranch[branch] = xxTree[branch];
+              searchListenerTree(handlers, type, { '**': isolatedBranch }, i+1);
+            }
+          }
+        }
+      } else if(xxTree._listeners) {
+        // We have reached the end and still on a '**'
+        searchListenerTree(handlers, type, xxTree, typeLength);
+      } else if(xxTree['*'] && xxTree['*']._listeners) {
+        searchListenerTree(handlers, type, xxTree['*'], typeLength);
+      }
+    }
+
+    return listeners;
+  }
+
+  function growListenerTree(type, listener) {
+
+    type = typeof type === 'string' ? type.split(this.delimiter) : type.slice();
+
+    //
+    // Looks for two consecutive '**', if so, don't add the event at all.
+    //
+    for(var i = 0, len = type.length; i+1 < len; i++) {
+      if(type[i] === '**' && type[i+1] === '**') {
+        return;
+      }
+    }
+
+    var tree = this.listenerTree;
+    var name = type.shift();
+
+    while (name) {
+
+      if (!tree[name]) {
+        tree[name] = {};
+      }
+
+      tree = tree[name];
+
+      if (type.length === 0) {
+
+        if (!tree._listeners) {
+          tree._listeners = listener;
+        }
+        else if(typeof tree._listeners === 'function') {
+          tree._listeners = [tree._listeners, listener];
+        }
+        else if (isArray(tree._listeners)) {
+
+          tree._listeners.push(listener);
+
+          if (!tree._listeners.warned) {
+
+            var m = defaultMaxListeners;
+
+            if (typeof this._events.maxListeners !== 'undefined') {
+              m = this._events.maxListeners;
+            }
+
+            if (m > 0 && tree._listeners.length > m) {
+
+              tree._listeners.warned = true;
+              console.error('(node) warning: possible EventEmitter memory ' +
+                            'leak detected. %d listeners added. ' +
+                            'Use emitter.setMaxListeners() to increase limit.',
+                            tree._listeners.length);
+              console.trace();
+            }
+          }
+        }
+        return true;
+      }
+      name = type.shift();
+    }
+    return true;
+  }
+
+  // By default EventEmitters will print a warning if more than
+  // 10 listeners are added to it. This is a useful default which
+  // helps finding memory leaks.
+  //
+  // Obviously not all Emitters should be limited to 10. This function allows
+  // that to be increased. Set to zero for unlimited.
+
+  EventEmitter.prototype.delimiter = '.';
+
+  EventEmitter.prototype.setMaxListeners = function(n) {
+    this._events || init.call(this);
+    this._events.maxListeners = n;
+    if (!this._conf) this._conf = {};
+    this._conf.maxListeners = n;
+  };
+
+  EventEmitter.prototype.event = '';
+
+  EventEmitter.prototype.once = function(event, fn) {
+    this.many(event, 1, fn);
+    return this;
+  };
+
+  EventEmitter.prototype.many = function(event, ttl, fn) {
+    var self = this;
+
+    if (typeof fn !== 'function') {
+      throw new Error('many only accepts instances of Function');
+    }
+
+    function listener() {
+      if (--ttl === 0) {
+        self.off(event, listener);
+      }
+      fn.apply(this, arguments);
+    }
+
+    listener._origin = fn;
+
+    this.on(event, listener);
+
+    return self;
+  };
+
+  EventEmitter.prototype.emit = function() {
+
+    this._events || init.call(this);
+
+    var type = arguments[0];
+
+    if (type === 'newListener' && !this.newListener) {
+      if (!this._events.newListener) { return false; }
+    }
+
+    // Loop through the *_all* functions and invoke them.
+    if (this._all) {
+      var l = arguments.length;
+      var args = new Array(l - 1);
+      for (var i = 1; i < l; i++) args[i - 1] = arguments[i];
+      for (i = 0, l = this._all.length; i < l; i++) {
+        this.event = type;
+        this._all[i].apply(this, args);
+      }
+    }
+
+    // If there is no 'error' event listener then throw.
+    if (type === 'error') {
+
+      if (!this._all &&
+        !this._events.error &&
+        !(this.wildcard && this.listenerTree.error)) {
+
+        if (arguments[1] instanceof Error) {
+          throw arguments[1]; // Unhandled 'error' event
+        } else {
+          throw new Error("Uncaught, unspecified 'error' event.");
+        }
+        return false;
+      }
+    }
+
+    var handler;
+
+    if(this.wildcard) {
+      handler = [];
+      var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice();
+      searchListenerTree.call(this, handler, ns, this.listenerTree, 0);
+    }
+    else {
+      handler = this._events[type];
+    }
+
+    if (typeof handler === 'function') {
+      this.event = type;
+      if (arguments.length === 1) {
+        handler.call(this);
+      }
+      else if (arguments.length > 1)
+        switch (arguments.length) {
+          case 2:
+            handler.call(this, arguments[1]);
+            break;
+          case 3:
+            handler.call(this, arguments[1], arguments[2]);
+            break;
+          // slower
+          default:
+            var l = arguments.length;
+            var args = new Array(l - 1);
+            for (var i = 1; i < l; i++) args[i - 1] = arguments[i];
+            handler.apply(this, args);
+        }
+      return true;
+    }
+    else if (handler) {
+      var l = arguments.length;
+      var args = new Array(l - 1);
+      for (var i = 1; i < l; i++) args[i - 1] = arguments[i];
+
+      var listeners = handler.slice();
+      for (var i = 0, l = listeners.length; i < l; i++) {
+        this.event = type;
+        listeners[i].apply(this, args);
+      }
+      return (listeners.length > 0) || this._all;
+    }
+    else {
+      return this._all;
+    }
+
+  };
+
+  EventEmitter.prototype.on = function(type, listener) {
+
+    if (typeof type === 'function') {
+      this.onAny(type);
+      return this;
+    }
+
+    if (typeof listener !== 'function') {
+      throw new Error('on only accepts instances of Function');
+    }
+    this._events || init.call(this);
+
+    // To avoid recursion in the case that type == "newListeners"! Before
+    // adding it to the listeners, first emit "newListeners".
+    this.emit('newListener', type, listener);
+
+    if(this.wildcard) {
+      growListenerTree.call(this, type, listener);
+      return this;
+    }
+
+    if (!this._events[type]) {
+      // Optimize the case of one listener. Don't need the extra array object.
+      this._events[type] = listener;
+    }
+    else if(typeof this._events[type] === 'function') {
+      // Adding the second element, need to change to array.
+      this._events[type] = [this._events[type], listener];
+    }
+    else if (isArray(this._events[type])) {
+      // If we've already got an array, just append.
+      this._events[type].push(listener);
+
+      // Check for listener leak
+      if (!this._events[type].warned) {
+
+        var m = defaultMaxListeners;
+
+        if (typeof this._events.maxListeners !== 'undefined') {
+          m = this._events.maxListeners;
+        }
+
+        if (m > 0 && this._events[type].length > m) {
+
+          this._events[type].warned = true;
+          console.error('(node) warning: possible EventEmitter memory ' +
+                        'leak detected. %d listeners added. ' +
+                        'Use emitter.setMaxListeners() to increase limit.',
+                        this._events[type].length);
+          console.trace();
+        }
+      }
+    }
+    return this;
+  };
+
+  EventEmitter.prototype.onAny = function(fn) {
+
+    if(!this._all) {
+      this._all = [];
+    }
+
+    if (typeof fn !== 'function') {
+      throw new Error('onAny only accepts instances of Function');
+    }
+
+    // Add the function to the event listener collection.
+    this._all.push(fn);
+    return this;
+  };
+
+  EventEmitter.prototype.addListener = EventEmitter.prototype.on;
+
+  EventEmitter.prototype.off = function(type, listener) {
+    if (typeof listener !== 'function') {
+      throw new Error('removeListener only takes instances of Function');
+    }
+
+    var handlers,leafs=[];
+
+    if(this.wildcard) {
+      var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice();
+      leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0);
+    }
+    else {
+      // does not use listeners(), so no side effect of creating _events[type]
+      if (!this._events[type]) return this;
+      handlers = this._events[type];
+      leafs.push({_listeners:handlers});
+    }
+
+    for (var iLeaf=0; iLeaf<leafs.length; iLeaf++) {
+      var leaf = leafs[iLeaf];
+      handlers = leaf._listeners;
+      if (isArray(handlers)) {
+
+        var position = -1;
+
+        for (var i = 0, length = handlers.length; i < length; i++) {
+          if (handlers[i] === listener ||
+            (handlers[i].listener && handlers[i].listener === listener) ||
+            (handlers[i]._origin && handlers[i]._origin === listener)) {
+            position = i;
+            break;
+          }
+        }
+
+        if (position < 0) {
+          continue;
+        }
+
+        if(this.wildcard) {
+          leaf._listeners.splice(position, 1);
+        }
+        else {
+          this._events[type].splice(position, 1);
+        }
+
+        if (handlers.length === 0) {
+          if(this.wildcard) {
+            delete leaf._listeners;
+          }
+          else {
+            delete this._events[type];
+          }
+        }
+        return this;
+      }
+      else if (handlers === listener ||
+        (handlers.listener && handlers.listener === listener) ||
+        (handlers._origin && handlers._origin === listener)) {
+        if(this.wildcard) {
+          delete leaf._listeners;
+        }
+        else {
+          delete this._events[type];
+        }
+      }
+    }
+
+    return this;
+  };
+
+  EventEmitter.prototype.offAny = function(fn) {
+    var i = 0, l = 0, fns;
+    if (fn && this._all && this._all.length > 0) {
+      fns = this._all;
+      for(i = 0, l = fns.length; i < l; i++) {
+        if(fn === fns[i]) {
+          fns.splice(i, 1);
+          return this;
+        }
+      }
+    } else {
+      this._all = [];
+    }
+    return this;
+  };
+
+  EventEmitter.prototype.removeListener = EventEmitter.prototype.off;
+
+  EventEmitter.prototype.removeAllListeners = function(type) {
+    if (arguments.length === 0) {
+      !this._events || init.call(this);
+      return this;
+    }
+
+    if(this.wildcard) {
+      var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice();
+      var leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0);
+
+      for (var iLeaf=0; iLeaf<leafs.length; iLeaf++) {
+        var leaf = leafs[iLeaf];
+        leaf._listeners = null;
+      }
+    }
+    else {
+      if (!this._events[type]) return this;
+      this._events[type] = null;
+    }
+    return this;
+  };
+
+  EventEmitter.prototype.listeners = function(type) {
+    if(this.wildcard) {
+      var handlers = [];
+      var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice();
+      searchListenerTree.call(this, handlers, ns, this.listenerTree, 0);
+      return handlers;
+    }
+
+    this._events || init.call(this);
+
+    if (!this._events[type]) this._events[type] = [];
+    if (!isArray(this._events[type])) {
+      this._events[type] = [this._events[type]];
+    }
+    return this._events[type];
+  };
+
+  EventEmitter.prototype.listenersAny = function() {
+
+    if(this._all) {
+      return this._all;
+    }
+    else {
+      return [];
+    }
+
+  };
+
+  if (typeof define === 'function' && define.amd) {
+    define(function() {
+      return EventEmitter;
+    });
+  } else {
+    exports.EventEmitter2 = EventEmitter;
+  }
+
+}(typeof process !== 'undefined' && typeof process.title !== 'undefined' && typeof exports !== 'undefined' ? exports : window);
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..f98655a
--- /dev/null
+++ b/package.json
@@ -0,0 +1,29 @@
+{
+  "name": "eventemitter2",
+  "version": "0.4.13",
+  "description": "A Node.js event emitter implementation with namespaces, wildcards, TTL and browser support.",
+  "keywords": ["event", "events", "emitter", "eventemitter"],
+  "author": "hij1nx <paolo at async.ly> http://twitter.com/hij1nx",
+  "contributors": [
+    "Eric Elliott",
+    "Charlie Robbins <charlie at nodejitsu.com> http://twitter.com/indexzero",
+    "Jameson Lee <jameson at nodejitsu.com> http://twitter.com/Jamesonjlee",
+    "Jeroen van Duffelen <jvduf at nodejitsu.com> http://www.twitter.com/jvduf",
+    "Fedor Indutny <fedor.indutny at gmail.com> http://www.twitter.com/indutny"
+  ],
+  "license": "MIT",
+  "repository": "git://github.com/hij1nx/EventEmitter2.git",
+  "devDependencies": {
+    "nodeunit": "*",
+    "benchmark" : ">= 0.2.2"
+  },
+  "main": "./lib/eventemitter2.js",
+  "scripts" : {
+    "test" : "nodeunit test/simple/ && nodeunit test/wildcardEvents/",
+    "benchmark" : "node test/perf/benchmark.js"
+  },
+  "files": [
+    "lib/eventemitter2.js",
+    "index.js"
+  ]
+}
diff --git a/test/common.js b/test/common.js
new file mode 100644
index 0000000..87c8139
--- /dev/null
+++ b/test/common.js
@@ -0,0 +1,127 @@
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var path = require('path');
+var assert = require('assert');
+
+exports.testDir = path.dirname(__filename);
+exports.fixturesDir = path.join(exports.testDir, 'fixtures');
+exports.libDir = path.join(exports.testDir, '../lib');
+exports.tmpDir = path.join(exports.testDir, 'tmp');
+exports.PORT = 12346;
+
+if (process.platform == 'win32') {
+  exports.PIPE = '\\\\.\\pipe\\libuv-test';
+} else {
+  exports.PIPE = exports.tmpDir + '/test.sock';
+}
+
+var util = require('util');
+for (var i in util) exports[i] = util[i];
+//for (var i in exports) global[i] = exports[i];
+
+function protoCtrChain(o) {
+  var result = [];
+  for (; o; o = o.__proto__) { result.push(o.constructor); }
+  return result.join();
+}
+
+exports.indirectInstanceOf = function(obj, cls) {
+  if (obj instanceof cls) { return true; }
+  var clsChain = protoCtrChain(cls.prototype);
+  var objChain = protoCtrChain(obj);
+  return objChain.slice(-clsChain.length) === clsChain;
+};
+
+
+// Turn this off if the test should not check for global leaks.
+exports.globalCheck = true;
+
+process.on('exit', function() {
+  if (!exports.globalCheck) return;
+  var knownGlobals = [setTimeout,
+                      setInterval,
+                      clearTimeout,
+                      clearInterval,
+                      console,
+                      Buffer,
+                      process,
+                      testFullSpec_param_found,
+                      TAP_Global_Harness,
+                      global.ArrayBuffer!==undefined?ArrayBuffer:null,
+                      global.Int8Array!==undefined?Int8Array:null,
+                      global.Uint8Array!==undefined?Uint8Array:null,
+                      global.Int16Array!==undefined?Int16Array:null,
+                      global.Uint16Array!==undefined?Uint16Array:null,
+                      global.Int32Array!==undefined?Int32Array:null,
+                      global.Uint32Array!==undefined?Uint32Array:null,
+                      global.Float32Array!==undefined?Float32Array:null,
+                      global.Float64Array!==undefined?Float64Array:null,
+                      global.DataView!==undefined?DataView:null,
+                      global.Uint8ClampedArray!==undefined?Uint8ClampedArray:null,
+                      AssertionError,
+                      global
+                      ];
+
+  if (global.setImmediate) {
+    knownGlobals.push(setImmediate, clearImmediate);
+  }
+  if (global.errno) {
+    knownGlobals.push(errno);
+  }
+
+  if (global.gc) {
+    knownGlobals.push(gc);
+  }
+
+  if (global.DTRACE_HTTP_SERVER_RESPONSE) {
+    knownGlobals.push(DTRACE_HTTP_SERVER_RESPONSE);
+    knownGlobals.push(DTRACE_HTTP_SERVER_REQUEST);
+    knownGlobals.push(DTRACE_HTTP_CLIENT_RESPONSE);
+    knownGlobals.push(DTRACE_HTTP_CLIENT_REQUEST);
+    knownGlobals.push(DTRACE_NET_STREAM_END);
+    knownGlobals.push(DTRACE_NET_SERVER_CONNECTION);
+    knownGlobals.push(DTRACE_NET_SOCKET_READ);
+    knownGlobals.push(DTRACE_NET_SOCKET_WRITE);
+  }
+
+  for (var x in global) {
+    var found = false;
+
+    for (var y in knownGlobals) {
+      if (global[x] === knownGlobals[y]) {
+        found = true;
+        break;
+      }
+    }
+
+    if (!found) {
+      console.error('Unknown global: %s', x);
+      assert.ok(false, 'Unknown global founded');
+    }
+  }
+});
+
+
+// This function allows one two run an HTTP test agaist both HTTPS and
+// normal HTTP modules. This ensures they fit the same API.
+exports.httpTest = function httpTest(cb) {
+};
diff --git a/test/perf/benchmark.js b/test/perf/benchmark.js
new file mode 100644
index 0000000..b5af6d8
--- /dev/null
+++ b/test/perf/benchmark.js
@@ -0,0 +1,53 @@
+
+var Benchmark = require('benchmark');
+var suite = new Benchmark.Suite();
+
+var EventEmitter = require('events').EventEmitter;
+var emitter = new EventEmitter;
+
+var EventEmitter2 = require('../../lib/eventemitter2').EventEmitter2;
+var emitter2 = new EventEmitter2;
+
+var EventEmitter3 = require('events').EventEmitter;
+var emitter3 = new EventEmitter3;
+
+suite
+
+  .add('EventEmitterHeatUp', function() {
+
+      emitter3.on('test3', function () { 1==1; });
+      emitter3.emit('test3');
+      emitter3.removeAllListeners('test3');
+
+  })
+  .add('EventEmitter', function() {
+
+    emitter.on('test1', function () { 1==1; });
+    emitter.emit('test1');
+    emitter.removeAllListeners('test1');
+
+  })
+  .add('EventEmitter2', function() {
+
+    emitter2.on('test2', function () { 1==1; });
+    emitter2.emit('test2');
+    emitter2.removeAllListeners('test2');
+
+  })
+
+  .add('EventEmitter2 (wild)', function() {
+
+    emitter2.on('test2.foo', function () { 1==1; });
+    emitter2.emit('test2.foo');
+    emitter2.removeAllListeners('test2.foo');
+
+  })
+
+  .on('cycle', function(event, bench) {
+    console.log(String(event.target));
+  })
+  .on('complete', function() {
+    console.log('\nFastest is ' + this.filter('fastest').pluck('name'));
+  })
+
+  .run(true);
diff --git a/test/simple/addListener.js b/test/simple/addListener.js
new file mode 100644
index 0000000..51bdbff
--- /dev/null
+++ b/test/simple/addListener.js
@@ -0,0 +1,179 @@
+var simpleEvents = require('nodeunit').testCase;
+var file = '../../lib/eventemitter2';
+var EventEmitter2;
+
+if(typeof require !== 'undefined') {
+  EventEmitter2 = require(file).EventEmitter2;
+}
+else {
+  EventEmitter2 = window.EventEmitter2;
+}
+
+module.exports = simpleEvents({
+
+  '1. Add a single listener on a single event.': function (test) {
+
+    var emitter = new EventEmitter2({ verbose: true });
+
+    emitter.on('test1', function () {
+      test.ok(true, 'The event was raised');
+    });
+
+    test.equal(emitter.listeners('test1').length, 1, 'There are three emitters');
+
+    test.expect(1);
+    test.done();
+
+  },
+  '2. Add two listeners on a single event.': function (test) {
+
+    var emitter = new EventEmitter2({ verbose: true });
+
+    emitter.on('test1', function () {
+      test.ok(true, 'The event was raised');
+    });
+
+    emitter.on('test1', function () {
+      test.ok(true, 'The event was raised');
+    });
+
+    test.equal(emitter.listeners('test1').length, 2, 'There are three emitters');
+
+    test.expect(1);
+    test.done();
+
+  },
+  '3. Add three listeners on a single event.': function (test) {
+
+    var emitter = new EventEmitter2({ verbose: true });
+
+    emitter.on('test1', function () {
+      test.ok(true, 'The event was raised');
+    });
+
+    emitter.on('test1', function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    emitter.on('test1', function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    test.equal(emitter.listeners('test1').length, 3, 'There are three emitters');
+
+    test.expect(1);
+    test.done();
+
+  },
+  '4. Add two listeners to two different events.': function (test) {
+
+    var emitter = new EventEmitter2({ verbose: true });
+
+    emitter.on('test1', function () {
+      test.ok(true, 'The event was raised');
+    });
+
+    emitter.on('test1', function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    emitter.on('test2', function () {
+      test.ok(true, 'The event was raised');
+    });
+
+    emitter.on('test2', function () {
+      test.ok(true, 'The event was raised');
+    });
+
+    test.equal(emitter.listeners('test1').length, 2, 'There are two emitters');
+    test.equal(emitter.listeners('test2').length, 2, 'There are two emitters');
+
+    test.expect(2);
+    test.done();
+
+  },
+  '5. Never adding any listeners should yield a listeners array with the length of 0.': function (test) {
+
+    var emitter = new EventEmitter2({ verbose: true });
+
+    emitter.on('test1', function () {
+      test.ok(true, 'The event was raised');
+    });
+
+    test.equal(emitter.listeners('test2').length, 0, 'There are no emitters');
+
+    test.expect(1);
+    test.done();
+  },
+
+  '6. the listener added should be the right listener.': function (test) {
+
+    var emitter = new EventEmitter2({ verbose: true });
+
+    var type = 'somelistenerbar';
+    var f = function () {};
+
+    emitter.on(type, f);
+    test.equal(emitter.listeners(type).length, 1, 'There are is one emitters');
+    test.equal(emitter.listeners(type)[0], f, 'The function should be f');
+
+    test.expect(2);
+    test.done();
+
+  },
+
+  '7. should be able to listen on any event' : function (test) {
+
+    var emitter = new EventEmitter2({ verbose: true });
+
+    var f = function () {
+      test.ok(true, 'the event was fired');
+    };
+
+    emitter.onAny(f);
+    emitter.emit('test23.ns5.ns5', 'someData'); //1
+    emitter.offAny(f);
+    emitter.emit('test21'); //0
+    emitter.onAny(f);
+    emitter.onAny(f);
+    emitter.emit('test23.ns5.ns5', 'someData'); //3
+
+    test.expect(3);
+    test.done();
+
+  },
+
+  '8. should be able to listen on any event (should cause an error)' : function (test) {
+
+    var emitter = new EventEmitter2({ verbose: true });
+
+    var f = function () {
+      test.ok(true, 'the event was fired');
+    };
+    emitter.onAny(f);
+
+    emitter.emit('error');
+
+    test.expect(1);
+    test.done();
+
+  },
+
+  '9. onAny alias' : function (test) {
+    
+    var emitter = new EventEmitter2({ verbose: true });
+
+    var f = function () {
+      test.ok(true, 'the event was fired');
+    };
+    
+    emitter.on(f);
+
+    emitter.emit('foo');
+    emitter.emit('bar');
+
+    test.expect(2);
+    test.done();
+
+  }
+});
diff --git a/test/simple/emit.js b/test/simple/emit.js
new file mode 100644
index 0000000..c52c567
--- /dev/null
+++ b/test/simple/emit.js
@@ -0,0 +1,142 @@
+
+var simpleEvents = require('nodeunit').testCase;
+var file = '../../lib/eventemitter2';
+var EventEmitter2;
+
+if(typeof require !== 'undefined') {
+  EventEmitter2 = require(file).EventEmitter2;
+}
+else {
+  EventEmitter2 = window.EventEmitter2;
+}
+
+module.exports = simpleEvents({
+
+  '1. Add two listeners on a single event and emit the event.': function (test) {
+
+    var emitter = new EventEmitter2({ verbose: true });
+
+    function functionA() { test.ok(true, 'The event was raised'); }
+    function functionB() { test.ok(true, 'The event was raised'); }
+
+    emitter.on('test2', functionA);
+    emitter.on('test2', functionB);
+
+    emitter.emit('test2');
+
+    test.expect(2);
+    test.done();
+
+  },  
+  '2. Add two listeners on a single event and emit the event twice.': function (test) {
+
+    var emitter = new EventEmitter2({ verbose: true });
+
+    function functionA() { test.ok(true, 'The event was raised'); }
+    function functionB() { test.ok(true, 'The event was raised'); }
+
+    emitter.on('test2', functionA);
+    emitter.on('test2', functionB);
+
+    emitter.emit('test2');
+    emitter.emit('test2');
+
+    test.expect(4);
+    test.done();
+
+  },
+  '3. Add two listeners on a single event and emit the event with a parameter.': function (test) {
+
+    var emitter = new EventEmitter2({ verbose: true });
+
+    function functionA(value1) {
+      test.ok(true, 'The event was raised');
+      test.equal(typeof value1, 'string', 'The event was raised');
+    }
+  
+    function functionB(value1) {
+      test.ok(true, 'The event was raised');
+      test.equal(typeof value1, 'string', 'The event was raised');
+    }
+
+    emitter.on('test2', functionA);
+    emitter.on('test2', functionB);
+
+    emitter.emit('test2', 'Hello, Node');
+
+    test.expect(4);
+    test.done();
+
+  },
+  '4. Add two listeners on an single event and emit the event twice with a parameter.': function (test) {
+
+    var emitter = new EventEmitter2({ verbose: true });
+
+    function functionA(value1) {
+      test.ok(true, 'The event was raised');
+      test.equal(typeof value1, 'string', 'The event was raised');
+    }
+  
+    function functionB(value1) {
+      test.ok(true, 'The event was raised');
+      test.equal(typeof value1, 'string', 'The event was raised');
+    }
+
+    emitter.on('test2', functionA);
+    emitter.on('test2', functionB);
+
+    emitter.emit('test2', 'Hello, Node1');
+    emitter.emit('test2', 'Hello, Node2');
+
+    test.expect(8);
+    test.done();
+
+  },
+  '5. Add two listeners on an single event and emit the event twice with multiple parameters.': function (test) {
+
+    var emitter = new EventEmitter2({ verbose: true });
+
+    function functionA(value1, value2, value3) {
+      test.ok(true, 'The event was raised');
+      test.equal(typeof value1, 'string', 'The value named "value1" is OK');
+      test.equal(typeof value2, 'string', 'The value named "value2" is OK');
+      test.equal(typeof value3, 'string', 'The value named "value3" is OK');
+    }
+  
+    function functionB(value1, value2, value3) {
+      test.ok(true, 'The event was raised');
+      test.equal(typeof value1, 'string', 'The value named "value1" is OK');
+      test.equal(typeof value2, 'string', 'The value named "value2" is OK');
+      test.equal(typeof value3, 'string', 'The value named "value3" is OK');
+    }
+
+    emitter.on('test2', functionA);
+    emitter.on('test2', functionB);
+
+    emitter.emit('test2', 'Hello, Node1', 'Hello, Node2', 'Hello, Node3');
+    emitter.emit('test2', 'Hello, Node1', 'Hello, Node2', 'Hello, Node3');
+
+    test.expect(16);
+    test.done();
+
+  },
+  '6. Check return values of emit.': function (test) {
+
+    var emitter = new EventEmitter2({ verbose: true });
+
+    function functionA() { test.ok(true, 'The event was raised'); }
+
+    emitter.on('test6', functionA);
+
+    test.ok(emitter.emit('test6'), 'emit should return true after calling a listener');
+    test.ok(!emitter.emit('other'), 'emit should return false when no listener was called');
+
+    emitter.onAny(functionA);
+    test.ok(emitter.emit('other'), 'emit should return true after calling an onAny() listener');
+
+    test.expect(5);
+    test.done();
+  },  
+
+});
+
diff --git a/test/simple/reconfigure.js b/test/simple/reconfigure.js
new file mode 100644
index 0000000..a944fd9
--- /dev/null
+++ b/test/simple/reconfigure.js
@@ -0,0 +1,55 @@
+var simpleEvents = require('nodeunit').testCase;
+var file = '../../lib/eventemitter2';
+var EventEmitter2;
+
+if(typeof require !== 'undefined') {
+  EventEmitter2 = require(file).EventEmitter2;
+}
+else {
+  EventEmitter2 = window.EventEmitter2;
+}
+
+module.exports = simpleEvents({
+
+  'reconfigure1. initialize, removeAllListeners' : function (test) {
+    
+    var emitter,
+        config = {
+          wildcard: true, // should the event emitter use wildcards.
+          delimiter: '::::', // the delimiter used to segment namespaces, defaults to `.`.
+          maxListeners: 20 // the max number of listeners that can be assigned to an event, defaults to 10.
+      };
+
+    emitter = new EventEmitter2(config);
+
+    emitter.removeAllListeners();
+
+    test.equal(emitter._events.maxListeners, config.maxListeners, 'should be ' + config.maxListeners);
+
+    test.equal(emitter._conf.maxListeners, config.maxListeners, 'should be ' + config.maxListeners);
+    test.equal(emitter._conf.delimiter, config.delimiter, 'should be ' + config.delimiter);
+    test.equal(emitter._conf.wildcard, config.wildcard, 'should be ' + config.wildcard);
+
+    test.expect(4);
+    test.done();
+  },
+
+  'reconfigure1. setMaxListeners, removeAllListeners' : function (test) {
+    var emitter,
+        amount = 99;
+
+    emitter = new EventEmitter2();
+
+    emitter.setMaxListeners(amount);
+
+    emitter.removeAllListeners();
+
+    test.equal(emitter._events.maxListeners, amount, 'should be ' + amount);
+
+    test.equal(emitter._conf.maxListeners, amount, 'should be ' + amount);
+
+    test.expect(2);
+    test.done();
+  }
+
+});
diff --git a/test/simple/removeListener.js b/test/simple/removeListener.js
new file mode 100644
index 0000000..0aedafe
--- /dev/null
+++ b/test/simple/removeListener.js
@@ -0,0 +1,196 @@
+
+var simpleEvents= require('nodeunit').testCase;
+var file = '../../lib/eventemitter2';
+var EventEmitter2;
+
+if(typeof require !== 'undefined') {
+  EventEmitter2 = require(file).EventEmitter2;
+}
+else {
+  EventEmitter2 = window.EventEmitter2;
+}
+
+module.exports = simpleEvents({
+
+  'removeListener1. adding 1, removing 1' : function (test) {
+
+    var emitter = new EventEmitter2;
+
+    var type = 'remove',
+        listeners;
+
+    var f = function f() {
+      test.ok(true, 'event was raised');
+    };
+
+    emitter.on(type, f);
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 1, 'should only have 1');
+
+    //remove
+    emitter.removeListener(type, f);
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 0, 'should be 0');
+
+    test.expect(2);
+    test.done();
+  },
+
+  'removeListener2. adding 2, removing 1' : function (test) {
+    
+    var emitter = new EventEmitter2;
+
+    var type = 'remove',
+        listeners;
+
+    var f = function f() {
+      test.ok(true, 'event was raised');
+    };
+
+    emitter.on(type, f);
+    emitter.on(type, f);
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 2, 'should only have 2');
+
+    //remove
+    emitter.removeListener(type, f);
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 1, 'should be 1');
+
+    test.expect(2);
+    test.done();
+  },
+
+  'removeListener3. adding 3, removing 1' : function (test) {
+
+    var emitter = new EventEmitter2;
+
+    var type = 'remove',
+        listeners;
+
+    var f = function f() {
+      test.ok(true, 'event was raised');
+    };
+
+    emitter.on(type, f);
+    emitter.on(type, f);
+    emitter.on(type, f);
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 3, 'should only have 3');
+
+    //remove
+    emitter.removeListener(type, f);
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 2, 'should be 2');
+
+    test.expect(2);
+    test.done();
+  },
+
+  'removeListener4. should error if we don\'t pass in a function' : function (test) {
+    
+    var emitter = new EventEmitter2;
+    var type = 'remove',
+        listeners;
+
+    var f = function f() {
+      test.ok(true, 'event was raised');
+    };
+
+    emitter.on(type, f);
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 1, 'should only have 1');
+
+    //remove
+    test.throws(function () {emitter.removeListener(type, type)}, Error, 'should throw an Error');
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 1, 'should be 1');
+
+    test.expect(3);
+    test.done();
+  },
+
+  'removeListener5. removing a different function, should not remove' : function (test) {
+    
+    var emitter = new EventEmitter2;
+    var type = 'remove',
+        listeners;
+
+    var f = function f() {
+      test.ok(true, 'event was raised');
+    };
+    var g = function g() {
+      test.ok(true, 'event was raised');
+    };
+
+    emitter.on(type, f);
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 1, 'should only have 1');
+
+    //remove
+    emitter.removeListener(type, g);
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 1, 'should be 1');
+
+    test.expect(2);
+    test.done();
+  },
+
+  'removeListener6. removing all functions' : function (test) {
+    
+    var emitter = new EventEmitter2;
+    var type = 'remove',
+        listeners;
+
+    var f = function f() {
+      test.ok(true, 'event was raised');
+    };
+    for (var i = 0; i < 10; i++) {
+      emitter.on(type, f);
+    }
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 10, 'should only have 10');
+
+    emitter.removeListener(type, f);
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 9, 'should be 9');
+    emitter.removeAllListeners(type);
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 0, 'should be 0');
+
+    test.expect(3);
+    test.done();
+  },
+
+  'removeListener7. removing different event, should not remove' : function (test) {
+    
+    var emitter = new EventEmitter2;
+    var type = 'remove',
+        listeners;
+
+    var f = function f() {
+      test.ok(true, 'event was raised');
+    };
+
+    for (var i = 0; i < 10; i++) {
+      emitter.on(type, f);
+    }
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 10, 'should only have 10');
+
+    emitter.removeListener(type+type, f);
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 10, 'should be 10');
+
+    emitter.removeAllListeners(type+type);
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 10, 'should be 10');
+
+    emitter.removeAllListeners(type);
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 0, 'should be 0');
+
+    test.expect(4);
+    test.done();
+  }
+});
diff --git a/test/simple/setMax.js b/test/simple/setMax.js
new file mode 100644
index 0000000..531862d
--- /dev/null
+++ b/test/simple/setMax.js
@@ -0,0 +1,135 @@
+
+var simpleEvents= require('nodeunit').testCase;
+var file = '../../lib/eventemitter2';
+var EventEmitter2;
+
+if(typeof require !== 'undefined') {
+  EventEmitter2 = require(file).EventEmitter2;
+}
+else {
+  EventEmitter2 = window.EventEmitter2;
+}
+
+module.exports = simpleEvents({
+
+  'setMaxListener1. default behavior of 10 listeners.' : function (test) {
+
+    var emitter = new EventEmitter2;
+
+    for (var i = 0; i < 10; i++) {
+      emitter.on('foobar', function () {
+        test.ok(true, 'event was raised');
+      });
+    }
+
+    var listeners = emitter.listeners('foobar');
+    test.equal(listeners.length, 10, 'should only have 10');
+
+    test.expect(1);
+    test.done();
+  },
+
+  'setMaxListener2. If we added more than 10, should not see them' : function (test) {
+
+    var emitter = new EventEmitter2;
+
+    for (var i = 0; i < 10 ; i++) {
+      emitter.on('foobar2', function () {
+        test.ok(true, 'event was raised');
+      });
+    }
+    console.log('should see EE2 complaining:');
+    emitter.on('foobar2', function () {
+      test.ok(true, 'event was raised');
+    });
+
+    var listeners = emitter.listeners('foobar2');
+    test.equal(listeners.length, 11, 'should have 11');
+    test.ok(emitter._events['foobar2'].warned, 'should have been warned');
+
+    test.expect(2);
+    test.done();
+  },
+
+  'setMaxListener3. if we set maxListener to be greater before adding' : function (test) {
+
+    var emitter = new EventEmitter2;
+    var type = 'foobar3';
+
+    // set to 20
+    emitter.setMaxListeners(20);
+
+    for (var i = 0; i < 15 ; i++) {
+      emitter.on(type, function () {
+        test.ok(true, 'event was raised');
+      });
+    }
+
+    var listeners = emitter.listeners(type);
+    test.equal(listeners.length, 15, 'should have 15');
+    test.ok(!(emitter._events[type].warned), 'should not have been set');
+
+    test.expect(2);
+    test.done();
+  },
+
+  'setMaxListener4. should be able to change it right at 10' : function (test) {
+
+    var emitter = new EventEmitter2;
+    var type = 'foobar4';
+
+    for (var i = 0; i < 10 ; i++) {
+      emitter.on(type, function () {
+        test.ok(true, 'event was raised');
+      });
+    }
+
+    emitter.setMaxListeners(9001);
+    emitter.on(type, function () {
+      test.ok(true, 'event was raised');
+    });
+
+    var listeners = emitter.listeners(type);
+    test.equal(listeners.length, 11, 'should have 11');
+    test.ok(!(emitter._events[type].warned), 'should not have been set');
+
+    test.expect(2);
+    test.done();
+  },
+
+  'setMaxListener5. if we set maxListener to be 0 should add endlessly' : function (test) {
+
+    var emitter = new EventEmitter2;    
+    var type = 'foobar';
+
+    // set to 0
+    emitter.setMaxListeners(0);
+
+    for (var i = 0; i < 25 ; i++) {
+      emitter.on(type, function () {
+        test.ok(true, 'event was raised');
+      });
+    }
+
+    var listeners = emitter.listeners(type);
+    test.equal(listeners.length, 25, 'should have 25');
+    test.ok(!(emitter._events[type].warned), 'should not have been set');
+
+    test.expect(2);
+    test.done();
+  },
+  'maxListeners parameter. Passing maxListeners as a parameter should override default.' : function (test) {
+    
+    var emitter = new EventEmitter2({
+      maxListeners: 2
+    });
+
+    console.log(emitter, test.equal, test.ok);
+    emitter.on('a', function () {});
+    emitter.on('a', function () {});
+    emitter.on('a', function () {});    
+    test.ok(emitter._events.a.warned,
+      '.on() should warn when maxListeners is exceeded.');
+    test.done();
+  }
+});
diff --git a/test/simple/ttl.js b/test/simple/ttl.js
new file mode 100644
index 0000000..332e8a7
--- /dev/null
+++ b/test/simple/ttl.js
@@ -0,0 +1,115 @@
+
+var simpleEvents = require('nodeunit').testCase;
+var file = '../../lib/eventemitter2';
+var EventEmitter2;
+
+if(typeof require !== 'undefined') {
+  EventEmitter2 = require(file).EventEmitter2;
+}
+else {
+  EventEmitter2 = window.EventEmitter2;
+}
+
+module.exports = simpleEvents({
+
+  '1. A listener added with `once` should only listen once and then be removed.': function (test) {
+    
+    var emitter = new EventEmitter2();
+
+    emitter.once('test1', function () {
+      test.ok(true, 'The event was raised once');
+    });
+
+    emitter.emit('test1');
+    emitter.emit('test1');
+
+    test.expect(1);
+    test.done();
+
+  },
+  '2. A listener with a TTL of 4 should only listen 4 times.': function (test) {
+
+    var emitter = new EventEmitter2();
+
+    emitter.many('test1', 4, function (value1) {
+      test.ok(true, 'The event was raised 4 times.');
+    });
+
+    emitter.emit('test1', 1);
+    emitter.emit('test1', 2);
+    emitter.emit('test1', 3);
+    emitter.emit('test1', 4);
+    emitter.emit('test1', 5);
+
+    test.expect(4);
+    test.done();
+
+  },
+  '3. A listener with a TTL of 4 should only listen 4 times and pass parameters.': function (test) {
+
+    var emitter = new EventEmitter2();
+
+    emitter.many('test1', 4, function (value1, value2, value3) {
+      test.ok(typeof value1 !== 'undefined', 'got value 1');
+      test.ok(typeof value2 !== 'undefined', 'got value 2');
+      test.ok(typeof value3 !== 'undefined', 'got value 3');
+    });
+
+    emitter.emit('test1', 1, 'A', false);
+    emitter.emit('test1', 2, 'A', false);
+    emitter.emit('test1', 3, 'A', false);
+    emitter.emit('test1', 4, 'A', false);
+    emitter.emit('test1', 5, 'A', false);
+
+    test.done();
+
+  },
+  '4. Remove an event listener by signature.': function (test) {
+
+    var emitter = new EventEmitter2();
+    var count = 0;
+
+    function f1(event) {
+      "event A";
+      test.ok(true, 'The event was raised less than 3 times.');
+    }
+
+    emitter.on('test1', f1);
+    
+    function f2(event) {
+      "event B";
+      test.ok(true, 'The event was raised less than 3 times.');  
+    }    
+    
+    emitter.on('test1', f2);
+
+    function f3(event) {
+      "event C";
+      test.ok(true, 'The event was raised less than 3 times.');
+    }
+
+    emitter.on('test1', f3);
+
+    emitter.removeListener('test1', f2);
+
+    emitter.emit('test1');
+
+    test.expect(2);
+    test.done();
+
+  },
+  '5. `removeListener` and `once`': function(test) {
+
+    var emitter = new EventEmitter2();
+    var functionA = function() { test.ok(true, 'Event was fired'); };
+
+    emitter.once('testA', functionA);
+    emitter.removeListener('testA', functionA);
+
+    emitter.emit('testA');
+
+    test.expect(0);
+    test.done();
+  }
+  
+});
diff --git a/test/wildcardEvents/addListener.js b/test/wildcardEvents/addListener.js
new file mode 100644
index 0000000..308093a
--- /dev/null
+++ b/test/wildcardEvents/addListener.js
@@ -0,0 +1,338 @@
+
+var simpleEvents = require('nodeunit').testCase;
+var file = '../../lib/eventemitter2';
+
+var EventEmitter2;
+
+if(typeof require !== 'undefined') {
+  EventEmitter2 = require(file).EventEmitter2;
+}
+else {
+  EventEmitter2 = window.EventEmitter2;
+}
+
+module.exports = simpleEvents({
+
+  '1. Add a single listener on a single event.': function (test) {
+    
+    var emitter = new EventEmitter2({ 
+      wildcard: true
+    });
+
+    var type = 'some.listener.bar';
+
+    emitter.on(type, function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    test.equal(emitter.listeners(type).length, 1, 'There are three emitters');
+    
+    test.expect(1);
+    test.done();
+
+  },
+  
+  '1a. Add a single listener on a single event (using an array).': function (test) {
+
+    var emitter = new EventEmitter2({ 
+      wildcard: true
+    });
+
+    var type = ['some', 'listener', 'bar'];
+
+    emitter.on(type, function () {
+      test.ok(true, 'The event was raised');
+    });
+
+    test.equal(emitter.listeners(type).length, 1, 'There are three emitters');
+    
+    test.expect(1);
+    test.done();
+
+  },
+
+  '2. Add two listeners on a single event.': function (test) {
+    
+    var emitter = new EventEmitter2({ 
+      wildcard: true
+    });
+
+    var type = 'some.listener.bar';
+    
+    emitter.on(type, function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    emitter.on(type, function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    test.equal(emitter.listeners(type).length, 2, 'There are three emitters');
+    
+    test.expect(1);
+    test.done();
+
+  },
+  
+  '2a. Add two listeners on a single event (using an array).': function (test) {
+    
+    var emitter = new EventEmitter2({ 
+      wildcard: true
+    });
+
+    var type = ['some', 'listener', 'bar'];
+    
+    emitter.on(type, function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    emitter.on(type, function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    test.equal(emitter.listeners(type).length, 2, 'There are three emitters');
+    
+    test.expect(1);
+    test.done();
+
+  },  
+  
+  '3. Add three listeners on a single event.': function (test) {
+
+    var emitter = new EventEmitter2({ 
+      wildcard: true
+    });
+
+    var type = 'some.listener.bar';
+    
+    emitter.on(type, function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    emitter.on(type, function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    emitter.on(type, function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    test.equal(emitter.listeners(type).length, 3, 'There are three emitters');
+    
+    test.expect(1);
+    test.done();
+
+  },
+  
+  '4. Add two listeners to two different events.': function (test) {
+
+    var emitter = new EventEmitter2({ 
+      wildcard: true
+    });
+
+    var type = 'some.listener.bar';
+    
+    emitter.on(type, function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    emitter.on(type, function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    emitter.on('test2', function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    emitter.on('test2', function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    test.equal(emitter.listeners(type).length, 2, 'There are two emitters');
+    test.equal(emitter.listeners('test2').length, 2, 'There are two emitters');
+    
+    test.expect(2);
+    test.done();
+  },
+
+  '5. Never adding any listeners should yield a listeners array with the length of 0.': function (test) {
+
+    var emitter = new EventEmitter2({ 
+      wildcard: true
+    });
+
+    var type = 'some.listener.bar';
+    
+    emitter.on(type, function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    test.equal(emitter.listeners('test2').length, 0, 'There are no emitters');
+    
+    test.expect(1);
+    test.done();
+  },
+
+  '6. the listener added should be the right listener.': function (test) {
+
+    var emitter = new EventEmitter2({ 
+      wildcard: true
+    });
+
+    var type = 'some.listener.bar';
+    var f = function () {};
+    
+    emitter.on(type, f);
+    test.equal(emitter.listeners(type).length, 1, 'There are is one emitters');
+    test.equal(emitter.listeners(type)[0], f, 'The function should be f');
+    
+    test.expect(2);
+    test.done();
+
+  },
+  
+  '7. Listeners on `*`, `*.*`, `*.test` with emissions from `foo.test` and `other.emit`': function (test) {
+
+    var emitter = new EventEmitter2({ 
+      wildcard: true
+    });
+
+    var f = function () {
+      test.ok(true, 'the event was fired')
+    };
+
+    emitter.on('*.test', f);
+    emitter.on('*.*', f);
+    emitter.on('*', f);
+
+    emitter.emit('other.emit');    
+    emitter.emit('foo.test');
+    
+    test.expect(3);
+    test.done();
+  },
+  
+  '8. Listeners on `*`, `*.*`, foo.test with emissions from `*`, `*.*` and `foo.test`': function (test) {
+
+    var emitter = new EventEmitter2({ 
+      wildcard: true
+    });
+
+    var f = function () {
+      test.ok(true, 'the event was fired')
+    };
+
+    emitter.on('foo.test', f);
+    emitter.on('*.*', f);
+    emitter.on('*', f);
+
+    emitter.emit('*.*');    
+    emitter.emit('foo.test');
+    emitter.emit('*')
+    
+    test.expect(5);
+    test.done();
+  },
+
+  '9. Listeners on `*`. (using an array)': function (test) {
+
+    var emitter = new EventEmitter2({ 
+      wildcard: true
+    });
+
+    var f = function () {
+      test.ok(true, 'the event was fired')
+    };
+    
+    emitter.on(['*'], f);
+    emitter.emit('*')
+    
+    test.expect(1);
+    test.done();
+  },
+
+  '10. actual event name': function(test) {
+
+    var emitter = new EventEmitter2({ 
+      wildcard: true
+    });
+
+    emitter.on('foo', function() {
+      emitter.emit('bar'); // changes the current event, passes the old one in as a parameter.
+    });
+    
+    emitter.on('*', function() {
+       console.log(this.event);
+    });
+
+    emitter.emit('foo');
+    
+    test.done();
+  },
+  
+  '11. Listeners with multi-level wildcards': function (test) {
+
+    var emitter = new EventEmitter2({ 
+      wildcard: true
+    });
+
+    var i = 0;
+    var f = function (n) {
+      return function() {
+        //console.log('Event', n, 'fired by', this.event);
+        test.ok(true, 'the event was fired');
+      };
+    };
+
+    emitter.on('**.test', f(i++));     // 0: 0 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1
+    emitter.on('**.bar.**', f(i++));   // 1: 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 1 + 1
+    emitter.on('**.*', f(i++));        // 2: 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1
+    emitter.on('*.**', f(i++));        // 3: 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1
+    emitter.on('**', f(i++));          // 4: 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1
+    emitter.on('other.**', f(i++));    // 5: 1 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 1 + 1
+    emitter.on('foo.**.test', f(i++)); // 6: 0 + 1 + 0 + 0 + 1 + 0 + 1 + 1 + 1 + 1
+    emitter.on('test.**', f(i++));     // 7: 0 + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 1 + 1
+    // Add forbidden patterns for safety purpose.
+    emitter.on('**.**', f(i++));
+    emitter.on('a.b.**.**', f(i++));
+    emitter.on('**.**.a.b', f(i++));
+    emitter.on('a.b.**.**.a.b', f(i++));
+
+    emitter.emit('other.emit');   // 4  
+    emitter.emit('foo.bar.test'); // 6
+    emitter.emit('foo.bar.test.bar.foo.test.foo'); // 4
+    emitter.emit('bar.bar.bar.bar.bar.bar'); // 4
+    emitter.emit('**.*'); // 8
+    emitter.emit('test'); // 5
+    emitter.emit('foo.test'); // 5
+    emitter.emit('foo.**.*'); // 6
+    emitter.emit('**.test'); // 8
+    emitter.emit('**.test.**'); // 8
+    //emitter.emit('*.**.test.**.a'); // 0
+    
+    test.expect(58);
+    test.done();
+  },
+
+  '12. Check return values of emit for wildcard emitter.': function (test) {
+
+    var emitter = new EventEmitter2({ 
+      wildcard: true
+    });
+
+    emitter.on('foo.*', function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    emitter.onAny(function () {
+      test.ok(true, 'The event was raised');
+    });
+
+    test.ok(emitter.emit('foo.blah'), 'emit should return true after calling a listener');
+    test.ok(emitter.emit('bar'), 'emit should return true after calling a listener');
+
+    test.expect(5);
+    test.done();
+  }
+
+});
diff --git a/test/wildcardEvents/all.js b/test/wildcardEvents/all.js
new file mode 100644
index 0000000..63bf8fb
--- /dev/null
+++ b/test/wildcardEvents/all.js
@@ -0,0 +1,248 @@
+var basicEvents = require('nodeunit').testCase;
+
+var EventEmitter2;
+
+if(typeof require !== 'undefined') {
+  EventEmitter2 = require('../../lib/eventemitter2').EventEmitter2;
+}
+else {
+  EventEmitter2 = window.EventEmitter2;
+}
+
+function setHelper (emitter, test, testName){
+  var eventNames = [
+    testName, 
+    testName + '.*', 
+    testName + '.ns1', 
+    testName + '.ns1.ns2', 
+    testName + '.ns2.*'
+  ];
+
+  for (var i = 0; i < eventNames.length; i++) {
+    emitter.on(eventNames[i], function () { 
+        test.ok(true, eventNames[i] + 'has fired');
+    });
+  }
+
+  return eventNames;
+};
+
+module.exports = basicEvents({
+
+  '1. An event can be namespaced.': function (test) {
+    
+    var emitter = new EventEmitter2({ 
+      wildcard: true,
+      verbose: true
+    });
+
+    emitter.on('test1.ns1', function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    emitter.emit('test1.ns1');
+    
+    test.expect(1);
+    test.done();
+
+  },
+  '2. An event can be namespaced and accept values.': function (test) {
+    
+    var emitter = new EventEmitter2({ 
+      wildcard: true,
+      verbose: true
+    });
+
+    emitter.on('test2.ns1', function(value1) {
+      test.ok(true, 'The event was raised');
+      test.ok(typeof value1 !== 'undefined', 'The event was raised with the value `' + value1 + '`.');
+    });
+    
+    emitter.emit('test2.ns1', 1);
+    
+    test.expect(2);
+    test.done();    
+
+  },
+  '3. A namespaced event can be raised multiple times and accept values.': function (test) {
+
+    var emitter = new EventEmitter2({ 
+      wildcard: true,
+      verbose: true
+    });
+
+    emitter.on('test3.ns1', function (value1, value2, value3) {
+       test.ok(true, 'The event was raised');
+       test.ok(arguments.length === 3, 'The event was raised with the correct number of arguments');
+       test.ok(value1 === 1 || value1 === 4, 'The event was raised with the value `' + value1 + '`.');
+       test.ok(value2 === 2 || value2 === 5, 'The event was raised with the value `' + value2 + '`.');
+       test.ok(value3 === 3 || value3 === 6, 'The event was raised with the value `' + value3 + '`.');            
+    });
+    
+    emitter.emit('test3.ns1', 1, 2, 3);
+    emitter.emit('test3.ns1', 4, 5, 6);
+    
+    test.expect(10);
+    test.done();
+  },    
+  '4. A listener should support wild cards.': function (test) {
+    
+    var emitter = new EventEmitter2({ 
+      wildcard: true,
+      verbose: true
+    });
+
+    emitter.on('test4.*', function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    emitter.emit('test4.ns1');
+    
+    test.expect(1);
+    test.done();
+
+  },
+  '5. Emitting an event should support wildcards.': function (test) {
+    
+    var emitter = new EventEmitter2({ 
+      wildcard: true,
+      verbose: true
+    });
+
+    emitter.on('test5A.test5B', function () {
+      test.ok(true, 'The event was raised');
+    });
+
+    emitter.emit('test5A.*');
+
+    test.expect(1);
+    test.done();
+
+  },
+  '6. A listener should support complex wild cards.': function (test) {
+    
+    var emitter = new EventEmitter2({ 
+      wildcard: true,
+      verbose: true
+    });
+
+    emitter.on('test10.*.foo', function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    emitter.emit('test10.ns1.foo');
+    
+    test.expect(1);
+    test.done();    
+
+  },
+  '7. Emitting an event should support complex wildcards.': function (test) {
+    
+    var emitter = new EventEmitter2({ 
+      wildcard: true,
+      verbose: true
+    });
+
+    emitter.on('test11.ns1.foo', function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    emitter.emit('test11.*.foo');
+    
+    test.expect(1);
+    test.done();    
+
+  },
+  '8. Emitting an event should support complex wildcards multiple times, a valid listener should accept values.': function (test) {
+    
+    var emitter = new EventEmitter2({ 
+      wildcard: true,
+      verbose: true
+    });
+
+    emitter.on('test12.ns1.ns2', function (value1, value2, value3) {
+      test.ok(true, 'The event was raised');
+      test.ok(arguments.length === 3, 'The event was raised with the correct number of arguments');
+      test.ok(value1 === 1 || value1 === 4, 'The event was raised with the value `' + value1 + '`.');
+      test.ok(value2 === 2 || value2 === 5, 'The event was raised with the value `' + value1 + '`.');
+      test.ok(value3 === 3 || value3 === 6, 'The event was raised with the value `' + value1 + '`.');            
+    });
+    
+    emitter.emit('test12.*.ns2', 1, 2, 3);
+    emitter.emit('test12.*.ns2', 4, 5, 6);
+    
+    test.expect(10);
+    test.done();
+    
+  },
+  '9. List all the listeners for a particular event.': function(test) {
+
+    var emitter = new EventEmitter2({ 
+      wildcard: true,
+      verbose: true
+    });
+
+    emitter.on('test13', function (event) {
+      test.ok(true,'raised one');
+    });
+
+    emitter.on('test13', function (event) {
+      test.ok(true,'raised two');
+    });
+
+    var listeners = emitter.listeners('test13');
+
+    test.ok(listeners.length === 2, 'The event `test13` should have 2 listeners');
+    test.expect(1);
+    test.done();
+
+  },
+  '10. should be able to listen on any event' : function (test) {
+    
+    var emitter = new EventEmitter2({ 
+      wildcard: true,
+      verbose: true
+    });
+
+    var fn = function (foo, bar) {
+      test.equal(this.event, 'test23.ns5.ns5')
+      test.equal(foo, 'foo');
+      test.equal(bar, 1);
+      test.ok(true, 'raised test23.ns5.ns5');
+    }
+    
+    emitter.onAny(fn);
+    emitter.emit('test23.ns5.ns5', 'foo', 1);
+    test.expect(4);
+    test.done();
+
+  },
+  
+  '11. No warning should be raised if we set maxListener to be greater before adding' : function (test) {
+
+    var emitter = new EventEmitter2({ 
+      wildcard: true,
+      verbose: true
+    });
+
+    var type = 'test29.*';
+
+    // set to 20
+    emitter.setMaxListeners(20);
+
+    for (var i = 0; i < 15 ; i++) {
+      emitter.on(type, function () {
+        test.ok(true, 'event was raised');
+      });
+    }
+
+    var listeners = emitter.listeners(type);
+    test.equal(listeners.length, 15, 'should have 15');
+    test.ok(!(emitter.listenerTree[ 'test29' ]['*']._listeners.warned), 'should not have been set');
+
+    test.expect(2);
+    test.done();
+  }
+
+ 
+});
diff --git a/test/wildcardEvents/customDelimiter.js b/test/wildcardEvents/customDelimiter.js
new file mode 100644
index 0000000..ee0c6f1
--- /dev/null
+++ b/test/wildcardEvents/customDelimiter.js
@@ -0,0 +1,250 @@
+
+var simpleEvents = require('nodeunit').testCase;
+var file = '../../lib/eventemitter2';
+
+var EventEmitter2;
+
+if(typeof require !== 'undefined') {
+  EventEmitter2 = require(file).EventEmitter2;
+}
+else {
+  EventEmitter2 = window.EventEmitter2;
+}
+
+module.exports = simpleEvents({
+
+  '1. Add a single listener on a single event.': function (test) {
+    
+    var emitter = new EventEmitter2({ 
+      wildcard: true,
+      delimiter: '::'
+    });
+
+    var type = 'some::listener::bar';
+    
+    emitter.on(type, function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    test.equal(emitter.listeners(type).length, 1, 'There are three emitters');
+    
+    test.expect(1);
+    test.done();
+
+  },
+
+  '2. Add two listeners on a single event.': function (test) {
+    
+    var emitter = new EventEmitter2({ 
+      wildcard: true,
+      delimiter: '::'
+    });
+
+    var type = 'some::listener::bar';
+    
+    emitter.on(type, function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    emitter.on(type, function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    test.equal(emitter.listeners(type).length, 2, 'There are three emitters');
+    
+    test.expect(1);
+    test.done();
+
+  },
+  '3. Add three listeners on a single event.': function (test) {
+    
+    var emitter = new EventEmitter2({ 
+      wildcard: true,
+      delimiter: '::'
+    });
+
+    var type = 'some::listener::bar';
+    
+    emitter.on(type, function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    emitter.on(type, function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    emitter.on(type, function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    test.equal(emitter.listeners(type).length, 3, 'There are three emitters');
+    
+    test.expect(1);
+    test.done();
+
+  },
+  '4. Add two listeners to two different events.': function (test) {
+
+    var emitter = new EventEmitter2({ 
+      wildcard: true,
+      delimiter: '::'
+    });
+    
+    var type = 'some::listener::bar';
+    
+    emitter.on(type, function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    emitter.on(type, function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    emitter.on('test2', function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    emitter.on('test2', function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    test.equal(emitter.listeners(type).length, 2, 'There are two emitters');
+    test.equal(emitter.listeners('test2').length, 2, 'There are two emitters');
+    
+    test.expect(2);
+    test.done();
+  },
+
+  '5. Never adding any listeners should yield a listeners array with the length of 0.': function (test) {
+    
+    var emitter = new EventEmitter2({ 
+      wildcard: true,
+      delimiter: '::'
+    });
+
+    var type = 'some::listener::bar';
+    
+    emitter.on(type, function () {
+      test.ok(true, 'The event was raised');
+    });
+    
+    test.equal(emitter.listeners('test2').length, 0, 'There are no emitters');
+    
+    test.expect(1);
+    test.done();
+  },
+
+  '6. the listener added should be the right listener.': function (test) {
+    
+    var emitter = new EventEmitter2({ 
+      wildcard: true,
+      delimiter: '::'
+    });
+
+    var type = 'some::listener::bar';
+    var f = function () {};
+    
+    emitter.on(type, f);
+    test.equal(emitter.listeners(type).length, 1, 'There are is one emitters');
+    test.equal(emitter.listeners(type)[0], f, 'The function should be f');
+    
+    test.expect(2);
+    test.done();
+
+  },
+  
+  '7. Listeners on *, *::*, *::test with emissions from foo::test and other::emit': function (test) {
+
+    var emitter = new EventEmitter2({ 
+      wildcard: true,
+      delimiter: '::'
+    });
+
+    var f = function () {
+      test.ok(true, 'the event was fired')
+    };
+
+    emitter.on('*::test', f);
+    emitter.on('*::*', f);
+    emitter.on('*', f);
+
+    emitter.emit('other::emit');    
+    emitter.emit('foo::test');
+    
+    test.expect(3);
+    test.done();
+  },
+  
+  '8. Listeners on *, *::*, foo.test with emissions from *, *::* and foo.test': function (test) {
+
+    var emitter = new EventEmitter2({ 
+      wildcard: true,
+      delimiter: '::'
+    });
+
+    var f = function () {
+      test.ok(true, 'the event was fired')
+    };
+
+    emitter.on('foo::test', f);
+    emitter.on('*::*', f);
+    emitter.on('*', f);
+
+    emitter.emit('*::*');    
+    emitter.emit('foo::test');
+    emitter.emit('*')
+    
+    test.expect(5);
+    test.done();
+  },
+  
+  '9. Listeners on **, **::*, **::test with emissions from foo::test and other::emit': function (test) {
+
+    var emitter = new EventEmitter2({ 
+      wildcard: true,
+      delimiter: '::'
+    });
+
+    var f = function () {
+      test.ok(true, 'the event was fired');
+    };
+
+    emitter.on('**::test', f);
+    emitter.on('**::*', f);
+    emitter.on('**', f);
+
+    emitter.emit('other::emit'); // 2
+    emitter.emit('foo::test');   // 3
+    
+    test.expect(5);
+    test.done();
+  },
+  
+  '10. Listeners on **, **::*, foo.test with emissions from **, **::* and foo.test': function (test) {
+    
+    var emitter = new EventEmitter2({ 
+      wildcard: true,
+      delimiter: '::'
+    });
+
+    var i = 0;
+    var f = function (n) {
+      return function() {
+        //console.log(n, this.event);
+        test.ok(true, 'the event was fired');
+      };
+    };
+
+    emitter.on('foo::test', f(i++));
+    emitter.on('**::*', f(i++));
+    emitter.on('**', f(i++));
+
+    emitter.emit('**::*'); // 3   
+    emitter.emit('foo::test'); // 3
+    emitter.emit('**'); // 3
+    
+    test.expect(9);
+    test.done();
+  }
+
+});
diff --git a/test/wildcardEvents/k1.js b/test/wildcardEvents/k1.js
new file mode 100644
index 0000000..5b6ef8c
--- /dev/null
+++ b/test/wildcardEvents/k1.js
@@ -0,0 +1,56 @@
+
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var common = require('../common');
+var assert = require('assert');
+var EventEmitter = require('../../lib/eventemitter2').EventEmitter2;
+
+var e = new EventEmitter({wildcard: true});
+var countWildcard = 0;
+var counMultiLevelWildcard = 0;
+var countAny = 0;
+
+e.on('foo', function() {
+  e.emit('bar', 'bar');
+});
+e.on('*', function(name) {
+  ++countWildcard;
+  console.log(this.event, name);
+  assert.equal(this.event, name);
+});
+e.on('**', function(name) {
+  ++counMultiLevelWildcard;
+  console.log(this.event, name);
+  assert.equal(this.event, name);
+});
+e.onAny(function(name) {
+  ++countAny;
+  assert.equal(this.event, name);
+});
+
+e.emit('foo', 'foo');
+
+process.on('exit', function() {
+  assert.equal(countWildcard, 2);
+  assert.equal(counMultiLevelWildcard, 2);
+  assert.equal(countAny, 2);
+});
diff --git a/test/wildcardEvents/options.js b/test/wildcardEvents/options.js
new file mode 100644
index 0000000..445aa4b
--- /dev/null
+++ b/test/wildcardEvents/options.js
@@ -0,0 +1,72 @@
+var basicEvents = require('nodeunit').testCase;
+var lib = '../../lib/eventemitter2';
+
+var EventEmitter2;
+
+if(typeof require !== 'undefined') {
+  EventEmitter2 = require(lib).EventEmitter2;
+}
+else {
+  EventEmitter2 = window.EventEmitter2;
+}
+
+function setHelper (emitter, test, testName){
+  var eventNames = [
+    testName, 
+    testName + '.*', 
+    testName + '.ns1', 
+    testName + '.ns1.ns2', 
+    testName + '.ns2.*',
+    testName + '.**',
+    testName = '.ns2.**'
+  ];
+
+  for (var i = 0; i < eventNames.length; i++) {
+    emitter.on(eventNames[i], function () { 
+        test.ok(true, eventNames[i] + 'has fired');
+    });
+  }
+
+  return eventNames;
+}
+
+module.exports = basicEvents({
+
+  'intialize 1. Configuration Flags Test.': function (test) {
+
+    var emitter = new EventEmitter2({ 
+      wildcard: true,
+      verbose: true
+    });
+
+    var emitterDefault = new EventEmitter2({
+    });
+
+    test.ok(!emitterDefault.wildcard, 'default .wildcard should be false');
+    test.ok(emitter.wildcard, '.wildcard should be true when set');
+    
+    test.expect(2);
+    test.done();
+
+  },
+  'initialize 2. creating a wildcard EE should have listenerTree.': function (test) {
+
+    var emitter = new EventEmitter2({ 
+      wildcard: true,
+      verbose: true
+    });
+
+    var emitterDefault = new EventEmitter2({
+    });
+
+    test.ok(emitter.listenerTree, 'listenerTree should exist');
+    test.equal(typeof emitter.listenerTree, 'object', 'listenerTree should be an Object');
+
+    test.ok(!emitterDefault.listenerTree, 'listenerTree should not exist');
+    // check the tree to be empty?
+    
+    test.expect(3);
+    test.done();
+
+  },
+});
diff --git a/test/wildcardEvents/removeListener.js b/test/wildcardEvents/removeListener.js
new file mode 100644
index 0000000..459d5ea
--- /dev/null
+++ b/test/wildcardEvents/removeListener.js
@@ -0,0 +1,348 @@
+var simpleEvents= require('nodeunit').testCase;
+var file = '../../lib/eventemitter2';
+
+var EventEmitter2;
+
+if(typeof require !== 'undefined') {
+  EventEmitter2 = require(file).EventEmitter2;
+}
+else {
+  EventEmitter2 = window.EventEmitter2;
+}
+
+module.exports = simpleEvents({
+
+  '1. add a single event and then remove the event.' : function (test) {
+    
+    var emitter = new EventEmitter2({
+      wildcard : true,
+      verbose : true
+    });
+
+    var type = 'remove.foo.bar',
+        listeners;
+
+    var f = function () {
+      test.ok(true, 'event was raised');
+    };
+
+    emitter.on(type, f);
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 1, 'should only have 1');
+
+    //remove
+    emitter.removeListener(type, f);
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 0, 'should be 0');
+
+    test.expect(2);
+    test.done();
+  },
+
+  '2. Add two events and then remove only one of those events.' : function (test) {
+
+    var emitter = new EventEmitter2({
+      wildcard : true,
+      verbose : true
+    });
+
+    var type = 'remove.foo.bar',
+        listeners;
+
+    var f = function f() {
+      test.ok(true, 'event was raised');
+    };
+
+    emitter.on(type, f);
+    emitter.on(type, f);
+    
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 2, 'should only have 2');
+
+    emitter.removeListener(type, f);
+
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 1, 'should be 1');
+
+    test.expect(2);
+    test.done();
+  },
+
+  '3. Add three events and remove only one of the events that was added.' : function (test) {
+
+    var emitter = new EventEmitter2({
+      wildcard : true,
+      verbose : true
+    });
+
+    var type = 'remove.foo.bar',
+        listeners;
+
+    var f = function () {
+      test.ok(true, 'event was raised');
+    };
+
+    emitter.on(type, f);
+    emitter.on(type, f);
+    emitter.on(type, f);
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 3, 'should only have 3');
+
+    //remove
+    emitter.removeListener(type, f);
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 2, 'should be 2');
+
+    test.expect(2);
+    test.done();
+  },
+
+  '4. Should error if we don\'t pass a function to the emit method.' : function (test) {
+
+    var emitter = new EventEmitter2({
+      wildcard : true,
+      verbose : true
+    });
+
+    var type = 'remove.foo.bar',
+        listeners;
+
+    var f = function () {
+      test.ok(true, 'event was raised');
+    };
+
+    emitter.on(type, f);
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 1, 'should only have 1');
+
+    //remove
+    test.throws(function () {emitter.removeListener(type, type)}, Error, 'should throw an Error');
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 1, 'should be 1');
+
+    test.expect(3);
+    test.done();
+  },
+
+  '5. Removing one listener should not affect another listener.' : function (test) {
+
+    var emitter = new EventEmitter2({
+      wildcard : true,
+      verbose : true
+    });
+
+    var type = 'remove.foo.bar',
+        listeners;
+
+    var f = function () {
+      test.ok(true, 'event was raised');
+    };
+    var g = function () {
+      test.ok(true, 'event was raised');
+    };
+
+    emitter.on(type, f);
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 1, 'should only have 1');
+
+    //remove
+    emitter.removeListener(type, g);
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 1, 'should be 1');
+
+    test.expect(2);
+    test.done();
+  },
+
+  '6. Remove all listener functions.' : function (test) {
+
+    var emitter = new EventEmitter2({
+      wildcard : true,
+      verbose : true
+    });
+
+    var type = 'remove.foo.bar',
+        listeners;
+
+    var f = function () {
+      test.ok(true, 'event was raised');
+    };
+    for (var i = 0; i < 10; i++) {
+      emitter.on(type, f);
+    }
+
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 10, 'should only have 10');
+
+    emitter.removeListener(type, f);
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 9, 'should be 9');
+    emitter.removeAllListeners(type);
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 0, 'should be 0');
+
+    test.expect(3);
+    test.done();
+  },
+
+  '7. Removing listeners for one event should not affect another event\'s listeners.' : function (test) {
+
+    var emitter = new EventEmitter2({
+      wildcard : true,
+      verbose : true
+    });
+
+    var type = 'remove.foo.bar';
+    
+    var listeners;
+    
+    var f = function () {
+      test.ok(true, 'event was raised');
+    };
+
+    for (var i = 0; i < 10; i++) {
+      emitter.on(type, f);
+    }
+
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 10, 'should only have 10');
+
+    emitter.removeListener(type+type, f);
+
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 10, 'should be 10');
+
+    emitter.removeAllListeners(type+type);
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 10, 'should be 10');
+    
+    emitter.removeAllListeners(type+'.'+type);
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 10, 'should be 10');
+
+    emitter.removeAllListeners(type);
+    listeners = emitter.listeners(type);
+    test.equal(listeners.length, 0, 'should be 0');
+
+    test.expect(5);
+    test.done();
+  },
+
+  '8. Its ok to listen on wildcard, so it is ok to remove it.' : function (test) {
+
+    var emitter = new EventEmitter2({
+      wildcard : true,
+      verbose : true
+    });
+
+    var type1 = '*.wild.card',
+        type2 = 'just.another.event',
+        listeners;
+
+    var f = function () {
+      test.ok(true, 'event was raised');
+    };
+
+    emitter.on(type2, f);
+    emitter.on(type1, f);
+
+    //remove
+    emitter.removeListener(type1, f);
+    listeners = emitter.listeners(type1);
+    test.equal(listeners.length, 0, 'should be 0');
+
+    test.expect(1);
+    test.done();
+  },
+
+  '9. And (8) should not depend on order of listening.' : function (test) {
+
+    var emitter = new EventEmitter2({
+      wildcard : true,
+      verbose : true
+    });
+
+    var type1 = '*.wild.card',
+        type2 = 'just.another.event',
+        listeners;
+
+    var f = function () {
+      test.ok(true, 'event was raised');
+    };
+
+    emitter.on(type1, f);
+    emitter.on(type2, f);
+
+    //remove
+    emitter.removeListener(type1, f);
+    listeners = emitter.listeners(type1);
+    test.equal(listeners.length, 0, 'should be 0');
+
+    test.expect(1);
+    test.done();
+  },
+
+  '10. Reporting many listeners on wildcard all should removed.' : function (test) {
+
+    var emitter = new EventEmitter2({
+      wildcard : true,
+      verbose : true
+    });
+
+    var type1 = '*.wild.card',
+        type2 = 'exact.wild.card',
+        listeners;
+
+    var f = function () {
+      test.ok(true, 'event was raised');
+    };
+
+    emitter.on(type1, f);
+    emitter.on(type2, f);
+
+    // check number of listeners by wild card
+    listeners = emitter.listeners(type1);
+    test.equal(listeners.length, 2, 'should only have 2');
+
+    // remove by wild card should remove both
+    emitter.removeListener(type1, f);
+    listeners = emitter.listeners(type1);
+    test.equal(listeners.length, 0, 'should be 0');
+
+    test.expect(2);
+    test.done();
+  },
+
+  '11. Add some listeners with wildcards and remove only the wildcard' : function (test) {
+    var emitter = new EventEmitter2({
+      wildcard : true,
+      verbose : true
+    });
+
+    var count = 0;
+    var goodCallback = function () {
+      count += 1;
+    };
+    var badCallback = function () {
+      count += 1;
+    };
+
+    // So that foo.bar.listeners is an Array
+    emitter.on("foo.bar.baz", goodCallback);
+    emitter.on("foo.bar.baz", goodCallback);
+
+    // Add and remove one with wildcard
+    emitter.on("foo.*.*", badCallback);
+    var returnValue = emitter.off("foo.*.*", badCallback);
+
+    emitter.emit("foo.bar.baz");
+
+    test.equal(count, 2, 'should call only good callbacks');
+    test.equal(returnValue, emitter, 'should allow chaining');
+
+    test.expect(2);
+    test.done();
+  }
+
+
+});
diff --git a/test/wildcardEvents/ttl.js b/test/wildcardEvents/ttl.js
new file mode 100644
index 0000000..11205dc
--- /dev/null
+++ b/test/wildcardEvents/ttl.js
@@ -0,0 +1,223 @@
+var simpleEvents = require('nodeunit').testCase;
+var file = '../../lib/eventemitter2';
+
+var EventEmitter2;
+
+if(typeof require !== 'undefined') {
+  EventEmitter2 = require(file).EventEmitter2;
+}
+else {
+  EventEmitter2 = window.EventEmitter2;
+}
+
+module.exports = simpleEvents({
+
+  '1. A listener added with `once` should only listen once and then be removed.': function (test) {
+
+    var emitter = new EventEmitter2({
+      wildcard : true,
+      verbose : true
+    });
+
+    var type = 'test1.foo.bar';
+    
+    emitter.once(type, function () {
+      test.ok(true, 'The event was raised once');
+    });
+
+    emitter.emit(type);
+    emitter.emit(type);
+
+    test.expect(1);
+    test.done();
+
+  },
+  '2. A listener with a TTL of 4 should only listen 4 times.': function (test) {
+
+    var emitter = new EventEmitter2({
+      wildcard : true,
+      verbose : true
+    });
+
+    var type = 'test1.foo.bar';
+
+    emitter.many(type, 4, function (value1) {
+      test.ok(true, 'The event was raised 4 times.');
+    });
+
+    emitter.emit(type, 1);
+    emitter.emit(type, 2);
+    emitter.emit(type, 3);
+    emitter.emit(type, 4);
+    emitter.emit(type, 5);
+
+    test.expect(4);
+    test.done();
+
+  },
+  '3. A listener with a TTL of 4 should only listen 4 times and pass parameters.': function (test) {
+
+    var emitter = new EventEmitter2({
+      wildcard : true,
+      verbose : true
+    });
+
+    var type = 'test1.foo.bar';
+
+    emitter.many(type, 4, function (value1, value2, value3) {
+      test.ok(typeof value1 !== 'undefined', 'got value 1');
+      test.ok(typeof value2 !== 'undefined', 'got value 2');
+      test.ok(typeof value3 !== 'undefined', 'got value 3');
+    });
+
+    emitter.emit(type, 1, 'A', false);
+    emitter.emit(type, 2, 'A', false);
+    emitter.emit(type, 3, 'A', false);
+    emitter.emit(type, 4, 'A', false);
+    emitter.emit(type, 5, 'A', false);
+
+    test.done();
+
+  },
+  '4. Remove an event listener by signature.': function (test) {
+
+    var emitter = new EventEmitter2({
+      wildcard : true,
+      verbose : true
+    });
+
+    var type = 'test1.foo.bar';
+    var count = 0;
+
+    function f1(event) {
+      "event A";
+      test.ok(true, 'The event was raised less than 3 times.');
+    }
+
+    emitter.on(type, f1);
+    
+    function f2(event) {
+      "event B";
+      test.ok(true, 'The event was raised less than 3 times.');  
+    }    
+    
+    emitter.on(type, f2);
+
+    function f3(event) {
+      "event C";
+      test.ok(true, 'The event was raised less than 3 times.');
+    }
+
+    emitter.on(type, f3);
+
+    emitter.removeListener(type, f2);
+
+    emitter.emit(type);
+
+    test.expect(2);
+    test.done();
+
+  },
+  '5. `removeListener` and `once`': function(test) {
+ 
+     var emitter = new EventEmitter2({
+      wildcard : true,
+      verbose : true
+    });
+   
+    var type = 'test1.foo.bar';
+    var functionA = function() { test.ok(true, 'Event was fired'); };
+
+    emitter.once(type, functionA);
+    emitter.removeListener(type, functionA);
+
+    emitter.emit(type);
+
+    test.expect(0);
+    test.done();
+  },
+
+  '6. Listening with a wildcard on once' : function (test) {
+
+    var emitter = new EventEmitter2({
+      wildcard : true,
+      verbose : true
+    });
+
+    var type = 'test1.foo.*';
+    var functionA = function() { test.ok(true, 'Event was fired'); };
+
+    emitter.once(type, functionA);
+    emitter.on(type,functionA);
+
+    emitter.emit(type); //2
+    emitter.emit(type); //1
+
+    test.expect(3);
+    test.done();
+  },
+
+  '7. Emitting with a wildcard targeted at once' : function (test) {
+
+    var emitter = new EventEmitter2({
+      wildcard : true,
+      verbose : true
+    });
+
+    var type = 'test1.foo.bar';
+    var type2 = 'test1.foo.*';
+    var functionA = function() { test.ok(true, 'Event was fired'); };
+
+    emitter.once(type, functionA);
+    emitter.emit(type2);
+    emitter.emit(type2);
+
+    test.expect(1);
+    test.done();
+  },
+  
+  '8. Emitting with a multi-level wildcard on once': function(test) {
+
+    var emitter = new EventEmitter2({
+      wildcard : true,
+      verbose : true
+    });
+
+    var i = 0;
+    var type = 'test1.**';
+    var functionA = function(n) {
+      return function() {
+        console.log(n, this.event);
+        test.ok(true, 'Event was fired');
+      };
+    }
+
+    emitter.once(type, functionA(i++));
+    emitter.on(type, functionA(i++));
+    emitter.emit(type); //2
+    emitter.emit(type); //1
+
+    test.expect(3);
+    test.done();
+  },
+
+  '9. Emitting with a multi-level wildcard targeted at once' : function (test) {
+
+    var emitter = new EventEmitter2({
+      wildcard : true,
+      verbose : true
+    });
+  
+    var type = 'test1.foo.bar';
+    var type2 = 'test1.**';
+    var functionA = function() { test.ok(true, 'Event was fired'); };
+
+    emitter.once(type, functionA);
+    emitter.emit(type2);
+    emitter.emit(type2);
+
+    test.expect(1);
+    test.done();
+  }
+  
+});

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-eventemitter2.git



More information about the Pkg-javascript-commits mailing list