var path = require("path"),
  fs = require("fs"),
  _ = require("lodash"),
  acorn = require("acorn"),
  clc = require("cli-color"),
  walk = require("acorn/dist/walk");

var isMatched = function(tags, f) {
  // Filter by tag (or tag list):
  //
  // Parse the syntax tree of each included test and search for it() calls
  // which have description strings containing the @tag we're looking for.
  // Example:
  //
  //  it("should function correctly @basic")
  //
  // Match each f in files against the tag list we have in the array tags.
  //
  var foundTags = false;
  var pass = false;
  var filename = path.resolve(f.filename);
  var root;
  try {
    root = acorn.parse(fs.readFileSync(filename), {
      ecmaVersion: 6
    });
  } catch (err) {
    console.log(clc.redBright("Syntax error in parsing " + filename));
    throw err;
  }

  walk.findNodeAt(root, null, null, function (nodeType, node) {
    if (!pass && nodeType === "CallExpression" && node.callee.name === "it" && node.arguments[0].value === f.name) {
      var name = node.arguments[0].value;
      var matchedTags = 0;
      var nodeTags = name.split(" ");

      // check if each of tags exists in this test case
      if (tags.every(function (wantedTag) {
        return nodeTags.indexOf("@" + wantedTag) > -1;
      })) {
        pass = true;
      }
    }
  });

  return pass;
};

module.exports = function(files, tags) {
  // Tidy up tag input. If we have a comma-delimited list, tokenize and clean it up
  if (typeof tags === "string") {
    tags = tags.trim();

    if (tags.indexOf(",") > -1) {
      tags = tags.trim().split(",").map(function (tag) {
        return tag.trim();
      });
    } else {
      tags = [tags];
    }
  }

  // If tags are empty or malformed, ignore them
  if (!_.isArray(tags) || tags.length === 0) {
    console.log("Mocha tag filter input tags are empty, returning all tests.");
    return files;
  }

  console.log("Using mocha tag filter with tags: ", tags);
  return files.filter(isMatched.bind({}, tags));
};

@@ -1,1394 +1,62 @@
 var 
-path = require(%22path%22),%0A  fs = require(%22fs%22),%0A  _ = require(%22lodash%22),%0A  acorn = require(%22acorn%22),%0A  clc = require(%22cli-color%22),%0A  walk = require(%22acorn/dist/walk%22);%0A%0Avar isMatched = function(tags, f) %7B%0A  // Filter by tag (or tag list):%0A  //%0A  // Parse the syntax tree of each included test and search for it() calls%0A  // which have description strings containing the @tag we're looking for.%0A  // Example:%0A  //%0A  //  it(%22should function correctly @basic%22)%0A  //%0A  // Match each f in files against the tag list we have in the array tags.%0A  //%0A  var foundTags = false;%0A  var pass = false;%0A  var filename = path.resolve(f.filename);%0A  var root;%0A  try %7B%0A    root = acorn.parse(fs.readFileSync(filename), %7B%0A      ecmaVersion: 6%0A    %7D);%0A  %7D catch (err) %7B%0A    console.log(clc.redBright(%22Syntax error in parsing %22 + filename));%0A    throw err;%0A  %7D%0A%0A  walk.findNodeAt(root, null, null, function (nodeType, node) %7B%0A    if (!pass && nodeType === %22CallExpression%22 && node.callee.name === %22it%22 && node.arguments%5B0%5D.value === f.name) %7B%0A      var name = node.arguments%5B0%5D.value;%0A      var matchedTags = 0;%0A      var nodeTags = name.split(%22 %22);%0A%0A      // check if each of tags exists in this test case%0A      if (tags.every(function (wantedTag) %7B%0A        return nodeTags.indexOf(%22@%22 + wantedTag) %3E -1;%0A      %7D)) %7B%0A        pass = true;%0A      %7D%0A    %7D%0A  %7D);%0A%0A  return pass;%0A%7D;%0A%0Amodule.exports = function(file
+_ = require(%22lodash%22);%0A%0Amodule.exports = function(test
 s, t
@@ -565,20 +565,20 @@
  return 
-file
+test
 s;%0A  %7D%0A%0A
@@ -649,12 +649,12 @@
 urn 
-file
+test
 s.fi
@@ -662,32 +662,133 @@
 ter(
-isMatched.bind(%7B%7D, tags)
+function(test) %7B%0A    return tags.every(function(wantedTag) %7B%0A      return test.name.indexOf('@' + wantedTag) %3E -1;%0A    %7D)%0A  %7D
 );%0A%7D

use locator name to filter on tag(s)