Repository: mochajs/mocha

Problem statement:
how to get test data in beforeEach() and afterEach()
I need to get the name of each test in `beforeEach` and the pass/fail status of each finished test in `afterEach`. I looked at using `this.test`, but from there the best thing I found was `this.test.parent`, which is the suite of tests. That's all well and good, but how do I know which of those tests is the one whose before/after block I'm in?



Hints:

Patch:
diff --git a/lib/runner.js b/lib/runner.js
--- a/lib/runner.js
+++ b/lib/runner.js
@@ -234,6 +234,8 @@ Runner.prototype.hook = function(name, fn){
     if (!hook) return fn();
     self.currentRunnable = hook;
 
+    hook.ctx.currentTest = self.test;
+
     self.emit('hook', hook);
 
     hook.on('error', function(err){
@@ -246,6 +248,7 @@ Runner.prototype.hook = function(name, fn){
       if (testError) self.fail(self.test, testError);
       if (err) return self.failHook(hook, err);
       self.emit('hook end', hook);
+      delete hook.ctx.currentTest;
       next(++i);
     });
   }


Test patch:
diff --git a/test/hook.async.js b/test/hook.async.js
--- a/test/hook.async.js
+++ b/test/hook.async.js
@@ -13,18 +13,24 @@ describe('async', function(){
       , 'before all'
       , 'parent before'
       , 'before'
+      , 'before test one'
       , 'one'
       , 'after'
+      , 'after test one passed'
       , 'parent after'
       , 'parent before'
       , 'before'
+      , 'before test two'
       , 'two'
       , 'after'
+      , 'after test two passed'
       , 'parent after'
       , 'parent before'
       , 'before'
+      , 'before test three'
       , 'three'
       , 'after'
+      , 'after test three passed'
       , 'parent after'
       , 'after all'
       , 'root after all']);
@@ -48,8 +54,12 @@ describe('async', function(){
     });
 
     beforeEach(function(done){
+      var ctx = this;
       process.nextTick(function(){
         calls.push('before');
+        if (ctx.currentTest) {
+          calls.push('before test ' + ctx.currentTest.title);
+        }
         done();
       })
     })
@@ -59,7 +69,8 @@ describe('async', function(){
           'root before all'
         , 'before all'
         , 'parent before'
-        , 'before']);
+        , 'before'
+        , 'before test one']);
       calls.push('one');
       process.nextTick(done);
     })
@@ -70,11 +81,14 @@ describe('async', function(){
         , 'before all'
         , 'parent before'
         , 'before'
+        , 'before test one'
         , 'one'
         , 'after'
+        , 'after test one passed'
         , 'parent after'
         , 'parent before'
-        , 'before']);
+        , 'before'
+        , 'before test two']);
       calls.push('two');
     })
 
@@ -84,22 +98,31 @@ describe('async', function(){
         , 'before all'
         , 'parent before'
         , 'before'
+        , 'before test one'
         , 'one'
         , 'after'
+        , 'after test one passed'
         , 'parent after'
         , 'parent before'
         , 'before'
+        , 'before test two'
         , 'two'
         , 'after'
+        , 'after test two passed'
         , 'parent after'
         , 'parent before'
-        , 'before']);
+        , 'before'
+        , 'before test three']);
       calls.push('three');
     })
 
     afterEach(function(done){
+      var ctx = this;
       process.nextTick(function(){
         calls.push('after');
+        if (ctx.currentTest) {
+          calls.push('after test ' + ctx.currentTest.title + ' ' + ctx.currentTest.state);
+        }
         done();
       })
     })
diff --git a/test/hook.sync.js b/test/hook.sync.js
--- a/test/hook.sync.js
+++ b/test/hook.sync.js
@@ -13,10 +13,16 @@ describe('serial', function(){
   describe('hooks', function(){
     beforeEach(function(){
       calls.push('before');
+      if (this.currentTest) {
+        calls.push('before test ' + this.currentTest.title);
+      }
     })
 
     it('one', function(){
-      calls.should.eql(['parent before', 'before']);
+      calls.should.eql([
+          'parent before'
+        , 'before'
+        , 'before test one']);
       calls.push('one');
     })
 
@@ -24,11 +30,14 @@ describe('serial', function(){
       calls.should.eql([
           'parent before'
         , 'before'
+        , 'before test one'
         , 'one'
         , 'after'
+        , 'after test one passed'
         , 'parent after'
         , 'parent before'
-        , 'before']);
+        , 'before'
+        , 'before test two']);
       calls.push('two');
     })
 
@@ -36,39 +45,53 @@ describe('serial', function(){
       calls.should.eql([
           'parent before'
         , 'before'
+        , 'before test one'
         , 'one'
         , 'after'
+        , 'after test one passed'
         , 'parent after'
         , 'parent before'
         , 'before'
+        , 'before test two'
         , 'two'
         , 'after'
+        , 'after test two passed'
         , 'parent after'
         , 'parent before'
-        , 'before']);
+        , 'before'
+        , 'before test three']);
       calls.push('three');
     })
 
     afterEach(function(){
       calls.push('after');
+      if (this.currentTest) {
+        calls.push('after test ' + this.currentTest.title + ' ' + this.currentTest.state);
+      }
     })
 
     after(function(){
       calls.should.eql([
           'parent before'
         , 'before'
+        , 'before test one'
         , 'one'
         , 'after'
+        , 'after test one passed'
         , 'parent after'
         , 'parent before'
         , 'before'
+        , 'before test two'
         , 'two'
         , 'after'
+        , 'after test two passed'
         , 'parent after'
         , 'parent before'
         , 'before'
+        , 'before test three'
         , 'three'
         , 'after'
+        , 'after test three passed'
         , 'parent after']);
     })
   })
diff --git a/test/hook.sync.nested.js b/test/hook.sync.nested.js
--- a/test/hook.sync.nested.js
+++ b/test/hook.sync.nested.js
@@ -5,61 +5,94 @@ describe('serial', function(){
 
     beforeEach(function(){
       calls.push('parent before');
+      if (this.currentTest) {
+        calls.push('parent before test ' + this.currentTest.title);
+      }
     })
 
     afterEach(function(){
       calls.push('parent after');
+      if (this.currentTest) {
+        calls.push('parent after test ' + this.currentTest.title + ' ' + this.currentTest.state);
+      }
     });
 
     it('foo', function(){
-      calls.should.eql(['parent before']);
+      calls.should.eql([
+          'parent before'
+        , 'parent before test foo']);
       calls.push('foo');
     })
 
     it('bar', function(){
       calls.should.eql([
           'parent before'
+        , 'parent before test foo'
         , 'foo'
         , 'parent after'
-        , 'parent before']);
+        , 'parent after test foo passed'
+        , 'parent before'
+        , 'parent before test bar']);
     })
 
     describe('hooks', function(){
       beforeEach(function(){
         calls.push('before');
+        if (this.currentTest) {
+          calls.push('before test ' + this.currentTest.title);
+        }
       })
 
       it('one', function(){
         calls.should.eql([
             'parent before'
+          , 'parent before test foo'
           , 'foo'
           , 'parent after'
+          , 'parent after test foo passed'
           , 'parent before'
+          , 'parent before test bar'
           , 'parent after'
+          , 'parent after test bar passed'
           , 'parent before'
-          , 'before']);
+          , 'parent before test one'
+          , 'before'
+          , 'before test one']);
         calls.push('one');
       })
 
       it('two', function(){
         calls.should.eql([
             'parent before'
+          , 'parent before test foo'
           , 'foo'
           , 'parent after'
+          , 'parent after test foo passed'
           , 'parent before'
+          , 'parent before test bar'
           , 'parent after'
+          , 'parent after test bar passed'
           , 'parent before'
+          , 'parent before test one'
           , 'before'
+          , 'before test one'
           , 'one'
           , 'after'
+          , 'after test one passed'
           , 'parent after'
+          , 'parent after test one passed'
           , 'parent before'
-          , 'before']);
+          , 'parent before test two'
+          , 'before'
+          , 'before test two']);
         calls.push('two');
       });
 
       afterEach(function(){
         calls.push('after');
+        if (this.currentTest) {
+          calls.push('after test ' + this.currentTest.title + ' ' + this.currentTest.state);
+        }
       })
     })
   })