/// <summary>
 /// Applies the filter actions created in the _sourceFilters object onto the source code
 /// </summary>
 /// <param name="cppSourceFile">source code related information</param>
 /// <param name="definesHandler">reference to the defines instances handling the pre-processor defines</param>
 private void ApplySourceFilter(CppSourceFile cppSourceFile, Defines definesHandler)
 {
     foreach (var sourceFilter in _sourceFilters)
     {
         sourceFilter.Filter(cppSourceFile, definesHandler);
     }
 }
        public void ConditionalInclusionsComplexExpressionEvaluationFail()
        {
            #region setup

            var definesHandler = new Defines(); //no defines supplied

            var filter = new ConditionalInclusionsFilter(new ExpressionEvaluation());

            const string nameSpace = "BoostTestAdapterNunit.Resources.SourceFiltering.";
            const string unfilteredSourceCodeResourceName = "ConditionalInclusionsComplexEvaluationFail.cpp";

            string sourceCodeOriginal = TestHelper.ReadEmbeddedResource(nameSpace + unfilteredSourceCodeResourceName);
            string sourceCodeExpected = sourceCodeOriginal;

            var cppSourceFile = new CppSourceFile()
            {
                FileName   = nameSpace + unfilteredSourceCodeResourceName,
                SourceCode = sourceCodeOriginal
            };

            #endregion

            #region excercise

            filter.Filter(cppSourceFile, definesHandler);

            #endregion

            #region verify

            Assert.AreEqual(sourceCodeExpected, cppSourceFile.SourceCode); //no filtering should be done due to inability to evaluate an expression

            #endregion
        }
        public void ConditionalInclusionsComplexExpressionEvaluationSuccess()
        {
            #region setup

            var definesHandler = new Defines();

            var expectedNonSubstitutionTokens = new HashSet <string>()
            {
                "VERSION",
                "HALF",
                "THIRD",
                "DEBUG",
                "SIN",
                "MAX",
                "CUBE",
                "fPRINT",
                "ASSERT",
            };

            var expectedSubtitutionTokens = new Dictionary <string, object>()
            {
                { "LEVEL", "19" },
                { "EVER", ";;" },
                { "BIG", "(512)" },
                { "PRINT", "cout << #x" },
            };

            var filter = new ConditionalInclusionsFilter(new ExpressionEvaluation());

            const string nameSpace = "BoostTestAdapterNunit.Resources.SourceFiltering.";
            const string unfilteredSourceCodeResourceName = "ConditionalInclusionsComplexEvaluationSuccess_UnfilteredSourceCode.cpp";
            const string filteredSourceCodeResourceName   = "ConditionalInclusionsComplexEvaluationSuccess_FilteredSourceCode.cpp";

            string sourceCodeOriginal = TestHelper.ReadEmbeddedResource(nameSpace + unfilteredSourceCodeResourceName);

            string sourceCodeExpected = TestHelper.ReadEmbeddedResource(nameSpace + filteredSourceCodeResourceName);

            var cppSourceFile = new CppSourceFile()
            {
                FileName   = nameSpace + unfilteredSourceCodeResourceName,
                SourceCode = sourceCodeOriginal
            };

            #endregion

            #region excercise

            filter.Filter(cppSourceFile, definesHandler);

            #endregion

            #region verify

            Assert.AreEqual(sourceCodeExpected, cppSourceFile.SourceCode);
            Assert.AreEqual(expectedNonSubstitutionTokens, definesHandler.NonSubstitutionTokens);
            Assert.AreEqual(expectedSubtitutionTokens, definesHandler.SubstitutionTokens);

            #endregion
        }
        private void GetBoostTests(IDictionary <string, ProjectInfo> solutionInfo, ITestCaseDiscoverySink discoverySink)
        {
            if (solutionInfo != null)
            {
                foreach (KeyValuePair <string, ProjectInfo> info in solutionInfo)
                {
                    string      source      = info.Key;
                    ProjectInfo projectInfo = info.Value;

                    foreach (var sourceFile in projectInfo.CppSourceFiles)
                    {
                        try
                        {
                            using (var sr = new StreamReader(sourceFile))
                            {
                                try
                                {
                                    var cppSourceFile = new CppSourceFile()
                                    {
                                        FileName   = sourceFile,
                                        SourceCode = sr.ReadToEnd()
                                    };

                                    // Filter out any false positives and quickly reject files which do not contain any Boost Unit Test eye-catchers
                                    if (ShouldConsiderSourceFile(cppSourceFile.SourceCode))
                                    {
                                        Defines definitions = GetDefines(projectInfo);

                                        ApplySourceFilter(cppSourceFile, definitions);
                                        DiscoverBoostTests(cppSourceFile, source, discoverySink);
                                    }
                                }
                                catch (Exception ex)
                                {
                                    Logger.Exception(
                                        ex,
                                        "Exception raised while discovering tests from \"{0}\" of project \"{1}\", ({2})",
                                        sourceFile,
                                        projectInfo.ProjectExe,
                                        ex.Message
                                        );
                                }
                            }
                        }
                        catch
                        {
                            Logger.Error("Unable to open file \"{0}\" of project \"{1}\".", sourceFile, projectInfo.ProjectExe);
                        }
                    }
                }
            }
            else
            {
                Logger.Error("the solutionInfo object was found to be null whilst");
            }
        }
Пример #5
0
        public string FilterQuotedString(string input)
        {
            ISourceFilter filter        = new QuotedStringsFilter();
            CppSourceFile cppSourceFile = new CppSourceFile()
            {
                SourceCode = input
            };

            filter.Filter(cppSourceFile, null);
            return(cppSourceFile.SourceCode);
        }
Пример #6
0
        /// <summary>
        /// Given 2 strings, filters the left-hand string and checks whether the filtered output matches that of the right-hand string.
        /// </summary>
        /// <param name="filter">The source filter to apply</param>
        /// <param name="defines">The preprocessor definitions which are to be used by the source filter</param>
        /// <param name="lhs">The left-hand string whose value will be filtered</param>
        /// <param name="rhs">The right-hand string whose value is used to compare the filtered result</param>
        protected void FilterAndCompare(ISourceFilter filter, Defines defines, string lhs, string rhs)
        {
            var cppSourceFile = new CppSourceFile()
            {
                SourceCode = lhs
            };

            filter.Filter(cppSourceFile, defines);

            Assert.AreEqual(cppSourceFile.SourceCode, rhs);
        }
Пример #7
0
        public void Apply(CppSourceFile cppSourceFile, Defines definesHandler)
        {
            Utility.Code.Require(cppSourceFile, "cppSourceFile");

            DefinesHandler = definesHandler;

            string[] sourceLines = LinefeedRegex.Split(cppSourceFile.SourceCode);

            _parserState.Clear();
            AddState(ParserState.NormalState);  //initial state

            SourceLineType sourceLineType;
            string         expression;
            string         subtitutionText;
            int            lineNumber = 0;

            try
            {
                for (; lineNumber < sourceLines.Length; lineNumber++)
                {
                    Inspect(sourceLines[lineNumber], out sourceLineType, out expression, out subtitutionText);

                    _conditionalInclusionsMachineState.Process(ref sourceLines[lineNumber], sourceLineType, expression,
                                                               subtitutionText);
                }

                /*
                 * Once the parsing is complete we just check that the parserState is back to Normal State.
                 * If not it is either because we parsed bad code (i.e. the code structure was not consistent to start with)
                 * or we've got a problem (programmatically) with our state engine
                 */

                //sanity check
                if (_parserState.Peek() != ParserState.NormalState)
                {
                    Logger.Error("The conditionals filter state machine failed to return to normal state. The source file \"{0}\" will not be filtered for conditionals.", cppSourceFile.FileName);

                    //the source code for the specific file is left unfiltered in case the state machine did not return to a normal state.
                }
                else
                {
                    //State machine returned to normal state so we can apply the filtering done by the conditional inclusions machine
                    cppSourceFile.SourceCode = string.Join(Environment.NewLine, sourceLines);
                }
            }
            catch (Exception ex)
            {
                Logger.Error(
                    "The conditionals filter encountered error: {0} whilst processing line number {1} of source file \"{2}\". The source file will not be filtered for conditionals",
                    ex.Message, lineNumber + 1, cppSourceFile.FileName);
            }
        }
        public void ConditionalInclusionsIfTests()
        {
            #region setup

            var definesHandler = new Defines();

            definesHandler.Define("DEBUG", "");
            definesHandler.Define("NDEBUG", "");
            definesHandler.Define("DEBUGGER", "");

            var expectedPreprocessorDefines = new HashSet <string>()
            {
                "DEBUG",
                "NDEBUG",
                "DEBUGGER",
                "DLEVEL"
            };

            var filter = new ConditionalInclusionsFilter(new ExpressionEvaluation());

            const string nameSpace = "BoostTestAdapterNunit.Resources.SourceFiltering.";
            const string unfilteredSourceCodeResourceName = "ConditionalInclusionsIfTests_UnFilteredSourceCode.cpp";
            const string filteredSourceCodeResourceName   = "ConditionalInclusionsIfTests_FilteredSourceCode.cpp";

            string sourceCodeOriginal = TestHelper.ReadEmbeddedResource(nameSpace + unfilteredSourceCodeResourceName);
            string sourceCodeExpected = TestHelper.ReadEmbeddedResource(nameSpace + filteredSourceCodeResourceName);

            var cppSourceFile = new CppSourceFile()
            {
                FileName   = nameSpace + unfilteredSourceCodeResourceName,
                SourceCode = sourceCodeOriginal
            };

            #endregion

            #region excercise

            filter.Filter(cppSourceFile, definesHandler);

            #endregion

            #region verify

            Assert.AreEqual(sourceCodeExpected, cppSourceFile.SourceCode);
            Assert.AreEqual(expectedPreprocessorDefines, definesHandler.NonSubstitutionTokens);
            Assert.AreEqual(0, definesHandler.SubstitutionTokens.Count);

            #endregion
        }
        public void Apply(CppSourceFile cppSourceFile, Defines definesHandler)
        {
            Utility.Code.Require(cppSourceFile, "cppSourceFile");

            DefinesHandler = definesHandler;

            string[] sourceLines = LinefeedRegex.Split(cppSourceFile.SourceCode);

            _parserState.Clear();
            AddState(ParserState.NormalState);  //initial state

            SourceLineType sourceLineType;
            string expression;
            string subtitutionText;
            int lineNumber = 0;

            try
            {
                for (; lineNumber < sourceLines.Length; lineNumber++)
                {
                    Inspect(sourceLines[lineNumber], out sourceLineType, out expression, out subtitutionText);

                    _conditionalInclusionsMachineState.Process(ref sourceLines[lineNumber], sourceLineType, expression,
                        subtitutionText);
                }

                /*
                 * Once the parsing is complete we just check that the parserState is back to Normal State.
                 * If not it is either because we parsed bad code (i.e. the code structure was not consistent to start with)
                 * or we've got a problem (programmatically) with our state engine
                 */

                //sanity check
                if (_parserState.Peek() != ParserState.NormalState)
                {
                    Logger.Error("The conditionals filter state machine failed to return to normal state. The source file \"{0}\" will not be filtered for conditionals.", cppSourceFile.FileName);

                    //the source code for the specific file is left unfiltered in case the state machine did not return to a normal state.
                }
                else
                {
                    //State machine returned to normal state so we can apply the filtering done by the conditional inclusions machine
                    cppSourceFile.SourceCode = string.Join(Environment.NewLine, sourceLines);
                }
            }
            catch (Exception ex)
            {
                Logger.Error(
                        "The conditionals filter encountered error: {0} whilst processing line number {1} of source file \"{2}\". The source file will not be filtered for conditionals",
                        ex.Message, lineNumber + 1, cppSourceFile.FileName);
            }
        }
        private static void DiscoverBoostTests(CppSourceFile cppSourceFile, string source, ITestCaseDiscoverySink discoverySink)
        {
            string[] code = cppSourceFile.SourceCode.TrimEnd(new[] { ' ', '\n', '\r' }).Split('\n');

            SourceFileInfo sourceInfo = new SourceFileInfo(cppSourceFile.FileName, 0);

            QualifiedNameBuilder suite = new QualifiedNameBuilder();

            // Push the equivalent of the Master Test Suite
            suite.Push(QualifiedNameBuilder.DefaultMasterTestSuiteName);

            var templateLists = new Dictionary <string, IEnumerable <string> >();

            for (sourceInfo.LineNumber = 1; sourceInfo.LineNumber <= code.Length; ++sourceInfo.LineNumber)
            {
                string line = code[sourceInfo.LineNumber - 1];

                string[] splitMacro   = SplitMacro(line);
                string   desiredMacro = splitMacro[0].Trim();

                switch (desiredMacro)
                {
                case Constants.TypedefListIdentifier:
                case Constants.TypedefMplListIdentifier:
                case Constants.TypedefBoostMplListIdentifier:
                {
                    var templateList = ParseTemplateList(splitMacro);
                    templateLists.Add(templateList.Key, templateList.Value);
                    break;
                }

                case Constants.TestCaseTemplateIdentifier:
                {
                    var templateTest = ParseTemplateTestCase(splitMacro, templateLists, sourceInfo, code, ref line);

                    foreach (string testCaseDataType in templateTest.Value)
                    {
                        string testCaseNameWithDataType = templateTest.Key + '<' + testCaseDataType + '>';
                        var    testCase = TestCaseUtils.CreateTestCase(source, sourceInfo, suite, testCaseNameWithDataType);
                        TestCaseUtils.AddTestCase(testCase, discoverySink);
                    }
                    break;
                }

                case Constants.FixtureTestSuiteIdentifier:
                case Constants.AutoTestSuiteIdentifier:
                {
                    string suiteName = ParseBeginTestSuite(splitMacro, sourceInfo, code, ref line);
                    suite.Push(suiteName);
                    break;
                }

                case Constants.FixtureTestCaseIdentifier:
                case Constants.AutoTestCaseIdentifier:
                case Constants.DataTestCaseIdentifier:
                {
                    string testCaseName = ParseTestCase(splitMacro, sourceInfo, code, ref line);
                    var    testCase     = TestCaseUtils.CreateTestCase(source, sourceInfo, suite, testCaseName);
                    TestCaseUtils.AddTestCase(testCase, discoverySink);
                    break;
                }

                case Constants.FixtureDataTestCaseIdentifier:
                {
                    string testCaseName = ParseDataTestCaseF(splitMacro, sourceInfo, code, ref line);
                    var    testCase     = TestCaseUtils.CreateTestCase(source, sourceInfo, suite, testCaseName);
                    TestCaseUtils.AddTestCase(testCase, discoverySink);
                    break;
                }

                case Constants.AutoTestSuiteEndIdentifier:
                {
                    suite.Pop();
                    break;
                }

                default:
                    break;
                }
            }
        }