Repository: mochajs/mocha

Problem statement:
require('mocha').beforeEach does not run outer lifecycle hooks when running inner testcases marked by `it.only`
This code associated with this writeup is available here: https://gist.github.com/cowboyd/f5611829c7a3ad084642

given the following mocha code:

``` javascript
var beforeEach = require('mocha').beforeEach;
describe("the outer context", function () {
  beforeEach(function() {
    this.didRunBeforeEach = true;
  });
  describe("the inner context", function() {
    it("runs its parent beforeEach", function() {
      expect(this.didRunBeforeEach).to.equal(true);
    });
  }) ;
});
```

because `"the inner context"` is nested inside `"the outer context"`,
it should run the outer context's `beforeEach` hook. It does do this
under normal circumstances:

``` javascript
~/C/E/mocha-demo ❯❯❯ npm t

> mocha-demo@1.0.0 test /Users/cowboyd/Code/Ember/mocha-demo
> mocha index.js



  the outer context
    the inner context
      ✓ runs its parent beforeEach


  1 passing (7ms)
```

But if we configure the inner context to
use `it.only` to select only the single test-case:

``` javascript
var beforeEach = require('mocha').beforeEach;
describe("the outer context", function () {
  beforeEach(function() {
    this.didRunBeforeEach = true;
  });
  describe("the inner context", function() {
    it.only("runs its parent beforeEach", function() {
      expect(this.didRunBeforeEach).to.equal(true);
    });
  }) ;
});
```

Then it fails with the following error:

```
~/C/E/mocha-demo ❯❯❯ npm t                                                                                                                                                                                                                  ⏎

> mocha-demo@1.0.0 test /Users/cowboyd/Code/Ember/mocha-demo
> mocha index.js


  1) runs its parent beforeEach

  0 passing (9ms)
  1 failing

  1)  runs its parent beforeEach:
     AssertionError: expected undefined to equal true
      at Context.<anonymous> (index.js:15:40)



npm ERR! Test failed.  See above for more details.
```

Which indicates that the hook is either not being run.
¯



Hints:
After further investigation, this only happens when using the [Require](http://mochajs.org/#require) interface. If using the global BDD interface, this is not an issue.

Also, it appears to be a problem with the `require`d `beforEach`. When using the `require`'d `it` and `describe`, but the global `beforeEach`, everything works as expected.


Patch:
diff --git a/lib/interfaces/bdd.js b/lib/interfaces/bdd.js
--- a/lib/interfaces/bdd.js
+++ b/lib/interfaces/bdd.js
@@ -77,7 +77,7 @@ module.exports = function(suite) {
      * acting as a thunk.
      */
 
-    context.it = context.specify = function(title, fn) {
+    var it = context.it = context.specify = function(title, fn) {
       var suite = suites[0];
       if (suite.pending) {
         fn = null;
@@ -93,7 +93,7 @@ module.exports = function(suite) {
      */
 
     context.it.only = function(title, fn) {
-      var test = context.it(title, fn);
+      var test = it(title, fn);
       var reString = '^' + escapeRe(test.fullTitle()) + '$';
       mocha.grep(new RegExp(reString));
       return test;


Test patch:
diff --git a/test/acceptance/misc/only/bdd-require.js b/test/acceptance/misc/only/bdd-require.js
new file mode 100644
--- /dev/null
+++ b/test/acceptance/misc/only/bdd-require.js
@@ -0,0 +1,18 @@
+/*jshint node: true */
+
+var mocha = require('../../../../lib/mocha');
+
+var beforeEach = mocha.beforeEach;
+var it = mocha.it;
+var describe = mocha.describe;
+
+describe('it.only via require("mocha")', function() {
+  beforeEach(function() {
+    this.didRunBeforeEach = true;
+  });
+  describe("nested within a describe/context", function() {
+    it.only('should run all enclosing beforeEach hooks', function() {
+      require('assert').equal(this.didRunBeforeEach, true);
+    });
+  });
+});