private void ApplySourceFilter(CppSourceFile cppSourceFile, Defines definesHandler) { foreach( var filter in _sourceFilters ) { filter.Filter(cppSourceFile, definesHandler); } }
public string FilterQuotedString(string input) { ISourceFilter filter = new QuotedStringsFilter(); CppSourceFile cppSourceFile = new CppSourceFile(){SourceCode = input}; filter.Filter(cppSourceFile, null); return cppSourceFile.SourceCode; }
/// <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); }
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 }
/// <summary> /// Applies the quoted strings filter action on the supplied sourceCode string /// </summary> /// <param name="cppSourceFile">CppSourceFile object containing the source file information</param> /// <param name="definesHandler">not used for this filter</param> public void Filter(CppSourceFile cppSourceFile, Defines definesHandler) { /* * It is important not to the change order of the filters. */ cppSourceFile.SourceCode = stringLiteralsRegex.Replace(cppSourceFile.SourceCode, new MatchEvaluator(ComputeReplacement)); cppSourceFile.SourceCode = quotedStringsRegex.Replace(cppSourceFile.SourceCode, ""); }
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 }
private void GetIutest(IList<ProjectInfo> projects, ITestCaseDiscoverySink discoverySink) { if (projects == null) return; foreach( ProjectInfo project in projects ) { foreach( string sourceFile in project.CppSourceFiles ) { try { using (var reader = new StreamReader(sourceFile)) { try { CppSourceFile cppSourceFile = new CppSourceFile() { FileName = sourceFile, SourceCode = reader.ReadToEnd() }; ApplySourceFilter(cppSourceFile, new Defines(project.DefinesHandler)); } catch (Exception e) { Logger.Error("Exception: \"{0}\", {1}", sourceFile, e.Message); Logger.Error(e.StackTrace); } } } catch (Exception e) { Logger.Error("Exception: \"{0}\", {1}", sourceFile, e.Message); Logger.Error(e.StackTrace); } } } }
/// <summary> /// Filters any single line comments from the source code /// </summary> /// <param name="cppSourceFile">CppSourceFile object containing the source file information</param> /// <param name="definesHandler">not used for this filter</param> public void Filter(CppSourceFile cppSourceFile, Defines definesHandler) { Utility.Code.Require(cppSourceFile, "cppSourceFile"); cppSourceFile.SourceCode = singleLineCommentRegex.Replace(cppSourceFile.SourceCode, ""); }
//Options: Case insensitive; Exact spacing; Dot matches line breaks; ^$ don't match at line breaks; Numbered capture // //Match the regex below and capture its match into backreference number 1 «(\r\n?|\n)» // Match this alternative (attempting the next alternative only if this one fails) «\r\n?» // Match the carriage return character «\r» // Match the line feed character «\n?» // Between zero and one times, as many times as possible, giving back as needed (greedy) «?» // Or match this alternative (the entire group fails if this one fails to match) «\n» // Match the line feed character «\n» #region ISourceFilter /// <summary> /// Applies the quoted strings filter action on the supplied sourceCode string /// </summary> /// <param name="cppSourceFile">CppSourceFile object containing the source file information</param> /// <param name="definesHandler">not used for this filter</param> public void Filter(CppSourceFile cppSourceFile, Defines definesHandler) { Utility.Code.Require(cppSourceFile, "cppSourceFile"); cppSourceFile.SourceCode = stringLiteralsRegex.Replace(cppSourceFile.SourceCode, ComputeReplacement); }
/// <summary> /// Discovers Boost Test from the provided C++ source file. Notifies test discovery via the provided discoverySink. /// </summary> /// <param name="cppSourceFile">The C++ source file to scan for Boost Tests</param> /// <param name="source">The associated test source EXE</param> /// <param name="discoverySink">The discoverySink to which identified tests will be notified to</param> 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, List<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(); // serge: BOOST multiline test macros are supported now /* * Currently the below is not able to handle BOOST UTF signatures spread over multiple lines. */ switch (desiredMacro) { case Constants.TypedefListIdentifier: case Constants.TypedefMplListIdentifier: case Constants.TypedefBoostMplListIdentifier: { var dataTypes = new List<string>(); int i; for (i = 1; i < splitMacro.Length - 2; ++i) { dataTypes.Add(splitMacro[i].Trim()); } templateLists.Add(splitMacro[i].Trim(), dataTypes); break; } case Constants.TestCaseTemplateIdentifier: { int newLineNumber = ScrollLines(sourceInfo.LineNumber, code, ref line); if (sourceInfo.LineNumber != newLineNumber) { // recalc splitMacro splitMacro = SplitMacro(line); sourceInfo.LineNumber = newLineNumber; } string listName = splitMacro[3].Trim(); //third parameter is the corresponding boost::mpl::list name if (templateLists.ContainsKey(listName)) { foreach (var dataType in templateLists[listName]) { string testCaseName = splitMacro[1].Trim(); //first parameter is the test case name string testCaseNameWithDataType = testCaseName + "<" + dataType + ">"; var testCase = TestCaseUtils.CreateTestCase(source, sourceInfo, suite, testCaseNameWithDataType); TestCaseUtils.AddTestCase(testCase, discoverySink); } } break; } case Constants.FixtureTestSuiteIdentifier: case Constants.AutoTestSuiteIdentifier: { int newLineNumber = ScrollLines(sourceInfo.LineNumber, code, ref line); if (sourceInfo.LineNumber != newLineNumber) { // recalc splitMacro splitMacro = SplitMacro(line); sourceInfo.LineNumber = newLineNumber; } suite.Push(splitMacro[1].Trim()); break; } case Constants.FixtureTestCaseIdentifier: case Constants.AutoTestCaseIdentifier: { int newLineNumber = ScrollLines(sourceInfo.LineNumber, code, ref line); if (sourceInfo.LineNumber != newLineNumber) { // recalc splitMacro splitMacro = SplitMacro(line); sourceInfo.LineNumber = newLineNumber; } string testCaseName = splitMacro[1].Trim(); var testCase = TestCaseUtils.CreateTestCase(source, sourceInfo, suite, testCaseName); TestCaseUtils.AddTestCase(testCase, discoverySink); break; } case Constants.AutoTestSuiteEndIdentifier: { suite.Pop(); break; } default: break; } } }
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) ) { /* * it is important that the pre-processor defines at project level are not modified * because every source file in the project has to have the same starting point. */ //call to cpy ctor Defines definitions = new Defines(projectInfo.DefinesHandler); ApplySourceFilter(cppSourceFile, definitions); DiscoverBoostTests(cppSourceFile, source, discoverySink); } } catch (Exception ex) { Logger.Error( "Exception raised while discovering tests from \"{0}\" of project \"{1}\", ({2})", sourceFile, projectInfo.ProjectExe, ex.Message); Logger.Error(ex.StackTrace); } } } 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"); } }
// (/\*(?:.+?)\*/) // // Options: Case insensitive; Exact spacing; Dot matches line breaks; ^$ don't match at line breaks; Numbered capture // // Match the regex below and capture its match into backreference number 1 «(/\*(?:.+?)\*/)» // Match the character “/” literally «/» // Match the character “*” literally «\*» // Match the regular expression below «(?:.+?)» // Match any single character «.+?» // Between one and unlimited times, as few times as possible, expanding as needed (lazy) «+?» // Match the character “*” literally «\*» // Match the character “/” literally «/» #region ISourceFilter /// <summary> /// Filters any multiline comments from the source code. /// </summary> /// <param name="cppSourceFile">CppSourceFile object containing the source file information</param> /// <param name="definesHandler">not used for this filter</param> public void Filter(CppSourceFile cppSourceFile, Defines definesHandler) { Utility.Code.Require(cppSourceFile, "cppSourceFile"); cppSourceFile.SourceCode = multiLineCommentRegex.Replace(cppSourceFile.SourceCode, ComputeMultiLineCommentReplacement); }
/// <summary> /// Filters any multiline comments from the source code. /// </summary> /// <param name="cppSourceFile">CppSourceFile object containing the source file information</param> /// <param name="definesHandler">not used for this filter</param> public void Filter(CppSourceFile cppSourceFile, Defines definesHandler) { cppSourceFile.SourceCode = multiLineCommentRegex.Replace(cppSourceFile.SourceCode, ComputeMultiLineCommentReplacement); }
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"); } }
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 }
/// <summary> /// Applies the filter action onto the source code /// </summary> /// <param name="cppSourceFile">source file information</param> /// <param name="definesHandler">pre-processor defines</param> public void Filter(CppSourceFile cppSourceFile, Defines definesHandler) { _conditionalInclusionsMachine.Apply(cppSourceFile, definesHandler); }
/// <summary> /// Filters any single line comments from the source code /// </summary> /// <param name="cppSourceFile">CppSourceFile object containing the source file information</param> /// <param name="definesHandler">not used for this filter</param> public void Filter(CppSourceFile cppSourceFile, Defines definesHandler) { cppSourceFile.SourceCode = singleLineCommentRegex.Replace(cppSourceFile.SourceCode, ""); }
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; } } }