/**
 * @fileoverview Ensure that no unit test is commented out.
 * @author Kevin Partington
 */
"use strict";

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------

module.exports = {
    meta: {
        docs: {
            description: "forbid commented tests",
            category: "Best Practices"
        },
        schema: []
    },

    create: function (context) {
        const sourceCode = context.getSourceCode(),
            ERROR_MESSAGE = "Unexpected \"{{callee}}\" in comment. Use QUnit.skip outside of a comment.",
            newlineRegExp = /\r\n|\r|\n/g,
            warningRegExp = /\b(QUnit\.test|QUnit\.asyncTest|QUnit\.skip|test|asyncTest)\s*\(/g;

        function getNewlineIndexes(text) {
            const indexes = [];
            let result;

            while ((result = newlineRegExp.exec(text)) !== null) {
                indexes.push(result.index + result[0].length);
            }

            return indexes;
        }

        function reportWarning(node, warning) {
            context.report({
                node: node,
                loc: warning.loc,
                message: ERROR_MESSAGE,
                data: {
                    callee: warning.term
                }
            });
        }

        function checkComment(node) {
            const warnings = [],
                text = sourceCode.getText(node),
                loc = node.loc.start,
                newlineIndexes = getNewlineIndexes(text);

            let lineOffset = 0,
                currentNewlineIndex,
                result;

            while ((result = warningRegExp.exec(text)) !== null) {
                while (newlineIndexes.length && result.index >= newlineIndexes[0]) {
                    ++lineOffset;
                    currentNewlineIndex = newlineIndexes.shift();
                }

                warnings.push({
                    term: result[1],
                    loc: {
                        line: loc.line + lineOffset,
                        column: lineOffset ? result.index - currentNewlineIndex : loc.column + result.index
                    }
                });
            }

            warnings.forEach(function (warning) {
                reportWarning(node, warning);
            });
        }

        return {
            "LineComment": checkComment,
            "BlockComment": checkComment
        };
    }
};

@@ -2418,77 +2418,111 @@
     
-%22LineComment%22: checkComment,%0A            %22BlockComment%22: checkComment
+Program: function () %7B%0A                sourceCode.getAllComments().forEach(checkComment);%0A            %7D
 %0A   

Use sourceCode.getAllComments() in no-commented-tests (fixes #64)