public void SearchRespectsAccessLevelCriteria()
 {
     var codeSearcher = new CodeSearcher();
     string keywords = "usage type";
     SimpleSearchCriteria searchCriteria = new SimpleSearchCriteria()
     {
         AccessLevels = new SortedSet<AccessLevel>() { AccessLevel.Private },
         SearchByAccessLevel = true,
         SearchTerms = new SortedSet<string>(keywords.Split(' '))
     };
     List<CodeSearchResult> codeSearchResults = codeSearcher.Search(searchCriteria);
     Assert.AreEqual(2, codeSearchResults.Count, "Invalid results number");
     var methodSearchResult = codeSearchResults.Find(el =>
                                                         el.ProgramElement.ProgramElementType == ProgramElementType.Method &&
                                                         (el.ProgramElement.Name == "UsageTypeCriteriaToString"));
     if(methodSearchResult == null)
     {
         Assert.Fail("Failed to find relevant search result for search: " + keywords);
     }
     var method = methodSearchResult.ProgramElement as MethodElement;
     Assert.AreEqual(method.AccessLevel, AccessLevel.Private, "Method access level differs!");
     Assert.AreEqual(method.Arguments, "StringBuilder stringBuilder bool searchByUsageType", "Method arguments differs!");
     Assert.NotNull(method.Body, "Method body is null!");
     //Assert.True(method.ClassId != null && method.ClassId != Guid.Empty, "Class id is invalid!");
     //Assert.AreEqual(method.ClassName, "SimpleSearchCriteria", "Method class name differs!");
     Assert.AreEqual(method.DefinitionLineNumber, 96, "Method definition line number differs!");
     Assert.True(method.FullFilePath.EndsWith("\\TestFiles\\MethodElementTestFiles\\Searcher.cs".ToLowerInvariant()), "Method full file path is invalid!");
     Assert.AreEqual(method.Name, "UsageTypeCriteriaToString", "Method name differs!");
     Assert.AreEqual(method.ProgramElementType, ProgramElementType.Method, "Program element type differs!");
     Assert.AreEqual(method.ReturnType, "void", "Method return type differs!");
     Assert.False(String.IsNullOrWhiteSpace(method.RawSource), "Method snippet is invalid!");
 }
 public void MethodIncludesDocCommentsInSearch()
 {
     var codeSearcher = new CodeSearcher();
     var keywords = "Retrieves a stream for saving an image";
     var codeSearchResults = codeSearcher.Search(keywords);
     Assert.Greater(codeSearchResults.Count, 1, "Invalid results number");
     var methodSearchResult = codeSearchResults.Find(el => el.ProgramElement.ProgramElementType == ProgramElementType.Method && el.ProgramElement.Name == "FetchOutputStream");
     if (methodSearchResult == null)
     {
         Assert.Fail("Failed to find relevant search result for search: " + keywords);
     }
 }
		public void SearchReturnsElementsWithNumbersInNames()
		{
            var codeSearcher = new CodeSearcher();
			string keywords = "problem";
			List<CodeSearchResult> codeSearchResults = codeSearcher.Search(keywords);
			Assert.AreEqual(codeSearchResults.Count, 5, "Invalid results number");
			var classSearchResult = codeSearchResults.Find(el => el.ProgramElement.ProgramElementType == ProgramElementType.Class && el.ProgramElement.Name == "Problem0010Resolver");
			if(classSearchResult == null)
			{
				Assert.Fail("Failed to find relevant search result for search: " + keywords);
			}
			var classElement = classSearchResult.ProgramElement as ClassElement;
			Assert.AreEqual(classElement.AccessLevel, AccessLevel.Public, "Class access level differs!");
			Assert.AreEqual(classElement.ExtendedClasses, "IResolver", "Class extended classes differs!");
			Assert.AreEqual(classElement.DefinitionLineNumber, 8, "Class definition line number differs!");
            Assert.True(classElement.FullFilePath.EndsWith("\\TestFiles\\NamesWithNumbersTestFiles\\Problem0010Resolver.cs".ToLowerInvariant()), "Class full file path is invalid!");
			Assert.AreEqual(classElement.Name, "Problem0010Resolver", "Class name differs!");
			Assert.AreEqual(classElement.ProgramElementType, ProgramElementType.Class, "Program element type differs!");
			Assert.AreEqual(classElement.ImplementedInterfaces, String.Empty, "Class implemented interfaces differs!");
			Assert.False(String.IsNullOrWhiteSpace(classElement.RawSource), "Class snippet is invalid!");

			var constructorSearchResult = codeSearchResults.Find(el => el.ProgramElement.ProgramElementType == ProgramElementType.Method && el.ProgramElement.Name == "Problem0010Resolver");
			if(constructorSearchResult == null)
			{
				Assert.Fail("Failed to find relevant search result for search: " + keywords);
			}
			var constructorElement = constructorSearchResult.ProgramElement as MethodElement;
			//Assert.AreEqual(constructorElement.AccessLevel, AccessLevel.Public, "Constructor access level differs!");
			Assert.IsTrue(constructorElement.IsConstructor, "IResolver", "Constructor extended classes differs!");
			Assert.AreEqual(constructorElement.DefinitionLineNumber, 10, "Constructor definition line number differs!");
            Assert.True(constructorElement.FullFilePath.EndsWith("\\TestFiles\\NamesWithNumbersTestFiles\\Problem0010Resolver.cs".ToLowerInvariant()), "Constructor full file path is invalid!");
			Assert.AreEqual(constructorElement.Name, "Problem0010Resolver", "Constructor name differs!");
			Assert.AreEqual(constructorElement.ProgramElementType, ProgramElementType.Method, "Program element type differs!");
			Assert.AreEqual(constructorElement.ReturnType, String.Empty, "Constructor should have an empty return type!");
			Assert.AreEqual(constructorElement.Modifiers, String.Empty, "Constructor modifiers differs!");
			Assert.AreEqual(constructorElement.Arguments, "long max", "Constructor modifiers differs!");
			Assert.False(String.IsNullOrWhiteSpace(constructorElement.RawSource), "Constructor snippet is invalid!");
		}
 public void MethodElementReturnedFromSearchContainsAllFields()
 {
     var codeSearcher = new CodeSearcher();
     string keywords = "fetch output stream";
     List<CodeSearchResult> codeSearchResults = codeSearcher.Search(keywords);
     Assert.AreEqual(codeSearchResults.Count, 7, "Invalid results number");
     var methodSearchResult = codeSearchResults.Find(el => el.ProgramElement.ProgramElementType == ProgramElementType.Method && el.ProgramElement.Name == "FetchOutputStream");
     if(methodSearchResult == null)
     {
         Assert.Fail("Failed to find relevant search result for search: " + keywords);
     }
     var method = methodSearchResult.ProgramElement as MethodElement;
     Assert.AreEqual(method.AccessLevel, AccessLevel.Public, "Method access level differs!");
     Assert.AreEqual(method.Arguments, "A B string fileName Image image", "Method arguments differs!");
     Assert.NotNull(method.Body, "Method body is null!");
     Assert.True(method.ClassId != null && method.ClassId != Guid.Empty, "Class id is invalid!");
     Assert.AreEqual(method.ClassName, "ImageCapture", "Method class name differs!");
     Assert.AreEqual(method.DefinitionLineNumber, 83, "Method definition line number differs!");
     Assert.True(method.FullFilePath.EndsWith("\\TestFiles\\MethodElementTestFiles\\ImageCapture.cs".ToLowerInvariant()), "Method full file path is invalid!");
     Assert.AreEqual(method.Name, "FetchOutputStream", "Method name differs!");
     Assert.AreEqual(method.ProgramElementType, ProgramElementType.Method, "Program element type differs!");
     Assert.AreEqual(method.ReturnType, "void", "Method return type differs!");
     Assert.False(String.IsNullOrWhiteSpace(method.RawSource), "Method snippet is invalid!");
 }
 public void MethodSearchRespectsFileExtensionsCriteria()
 {
     var codeSearcher = new CodeSearcher();
     var keywords = "main";
     var searchCriteria = new SimpleSearchCriteria()
         {
             SearchTerms = new SortedSet<string>(keywords.Split(' ')),
             SearchByFileExtension = true,
             FileExtensions = new SortedSet<string> {"cpp"}
         };
     var codeSearchResults = codeSearcher.Search(searchCriteria);
     Assert.AreEqual(2, codeSearchResults.Count, "Invalid results number");
     var methodSearchResult = codeSearchResults.Find(el => el.ProgramElement.ProgramElementType == ProgramElementType.Method && el.ProgramElement.Name == "main");
     if (methodSearchResult == null)
     {
         Assert.Fail("Failed to find relevant search result for search: " + keywords);
     }
     //var method = methodSearchResult.Element as MethodElement;
     //Assert.AreEqual(method.AccessLevel, AccessLevel.Public, "Method access level differs!");
     //Assert.AreEqual(method.Arguments, String.Empty, "Method arguments differs!");
     //Assert.NotNull(method.Body, "Method body is null!");
     //Assert.True(method.ClassId != null && method.ClassId != Guid.Empty, "Class id is invalid!");
     //Assert.AreEqual(method.ClassName, "SimpleSearchCriteria", "Method class name differs!");
     //Assert.AreEqual(method.DefinitionLineNumber, 31, "Method definition line number differs!");
     //Assert.True(method.FullFilePath.EndsWith("\\TestFiles\\MethodElementTestFiles\\Searcher.cs"), "Method full file path is invalid!");
     //Assert.AreEqual(method.Name, "ToQueryString", "Method name differs!");
     //Assert.AreEqual(method.ProgramElementType, ProgramElementType.Method, "Program element type differs!");
     //Assert.AreEqual(method.ReturnType, "void", "Method return type differs!");
     //Assert.False(String.IsNullOrWhiteSpace(method.RawSource), "Method snippet is invalid!");
 }
 public void SearchWorksNormallyForTermsWhichEndsWithSpace()
 {
     try
     {
         var codeSearcher = new CodeSearcher();
         string keywords = "  usage ";
         List<CodeSearchResult> codeSearchResults = codeSearcher.Search(keywords);
     }
     catch(Exception ex)
     {
         Assert.Fail(ex.Message);
     }
 }
 public void TestNoteSandoSearch()
 {
     string keywords = "-test sando search";
     var expectedLowestRank = 10;
     Predicate<CodeSearchResult> predicate = el => el.ProgramElement.ProgramElementType == ProgramElementType.Class && (el.ProgramElement.Name == "SelfSearchTest");
     var codeSearcher = new CodeSearcher();
     List<CodeSearchResult> codeSearchResults = codeSearcher.Search(keywords);
     var methodSearchResult = codeSearchResults.Find(predicate);
     if (methodSearchResult != null)
     {
         Assert.Fail("Should not find anything that matches for this test: " + keywords);
     }
 }
        public void SearchIsUsingStemming()
        {
            var codeSearcher = new CodeSearcher();
            string keywords = "name";
            List<CodeSearchResult> codeSearchResults = codeSearcher.Search(keywords);
            Assert.AreEqual(codeSearchResults.Count, 9, "Invalid results number");
            var classSearchResult = codeSearchResults.Find(el => el.ProgramElement.ProgramElementType == ProgramElementType.Class && el.ProgramElement.Name == "FileNameTemplate");
            if(classSearchResult == null)
            {
                Assert.Fail("Failed to find relevant search result for search: " + keywords);
            }
            var classElement = classSearchResult.ProgramElement as ClassElement;
            Assert.AreEqual(classElement.AccessLevel, AccessLevel.Public, "Class access level differs!");
            Assert.AreEqual(classElement.ExtendedClasses, String.Empty, "Class extended classes differs!");
            Assert.AreEqual(classElement.DefinitionLineNumber, 10, "Class definition line number differs!");
            Assert.True(classElement.FullFilePath.EndsWith("\\TestFiles\\StemmingTestFiles\\FileNameTemplate.cs".ToLowerInvariant()), "Class full file path is invalid!");
            Assert.AreEqual(classElement.Name, "FileNameTemplate", "Class name differs!");
            Assert.AreEqual(classElement.ProgramElementType, ProgramElementType.Class, "Program element type differs!");
            Assert.AreEqual(classElement.ImplementedInterfaces, String.Empty, "Class implemented interfaces differs!");
            Assert.False(String.IsNullOrWhiteSpace(classElement.RawSource), "Class snippet is invalid!");

            var methodSearchResult = codeSearchResults.Find(el => el.ProgramElement.ProgramElementType == ProgramElementType.Method && el.ProgramElement.Name == "Parse");
            if(methodSearchResult == null)
            {
                Assert.Fail("Failed to find relevant search result for search: " + keywords);
            }
            var methodElement = methodSearchResult.ProgramElement as MethodElement;
            Assert.AreEqual(methodElement.AccessLevel, AccessLevel.Public, "Method access level differs!");
            Assert.AreEqual(methodElement.Arguments, "string extension", "Method arguments differs!");
            Assert.NotNull(methodElement.Body, "Method body is null!");
            Assert.True(methodElement.ClassId != null && methodElement.ClassId != Guid.Empty, "Class id is invalid!");
            Assert.AreEqual(methodElement.ClassName, "FileNameTemplate", "Method class name differs!");
            Assert.AreEqual(methodElement.DefinitionLineNumber, 17, "Method definition line number differs!");
            Assert.True(methodElement.FullFilePath.EndsWith("\\TestFiles\\StemmingTestFiles\\FileNameTemplate.cs".ToLowerInvariant()), "Method full file path is invalid!");
            Assert.AreEqual(methodElement.Name, "Parse", "Method name differs!");
            Assert.AreEqual(methodElement.ProgramElementType, ProgramElementType.Method, "Program element type differs!");
            Assert.AreEqual(methodElement.ReturnType, "ImagePairNames", "Method return type differs!");
            Assert.False(String.IsNullOrWhiteSpace(methodElement.RawSource), "Method snippet is invalid!");

            methodSearchResult = codeSearchResults.Find(el => el.ProgramElement.ProgramElementType == ProgramElementType.Method && el.ProgramElement.Name == "TryAddTemplatePrompt");
            if(methodSearchResult == null)
            {
                Assert.Fail("Failed to find relevant search result for search: " + keywords);
            }
            methodElement = methodSearchResult.ProgramElement as MethodElement;
            Assert.AreEqual(methodElement.AccessLevel, AccessLevel.Private, "Method access level differs!");
            Assert.AreEqual(methodElement.Arguments, "ImagePairNames startNames", "Method arguments differs!");
            Assert.NotNull(methodElement.Body, "Method body is null!");
            Assert.True(methodElement.ClassId != null && methodElement.ClassId != Guid.Empty, "Class id is invalid!");
            Assert.AreEqual(methodElement.ClassName, "FileNameTemplate", "Method class name differs!");
            Assert.AreEqual(methodElement.DefinitionLineNumber, 53, "Method definition line number differs!");
            Assert.True(methodElement.FullFilePath.EndsWith("\\TestFiles\\StemmingTestFiles\\FileNameTemplate.cs".ToLowerInvariant()), "Method full file path is invalid!");
            Assert.AreEqual(methodElement.Name, "TryAddTemplatePrompt", "Method name differs!");
            Assert.AreEqual(methodElement.ProgramElementType, ProgramElementType.Method, "Program element type differs!");
            //Assert.AreEqual(methodElement.ReturnType, "ImagePairNames", "Method return type differs!");
            Assert.False(String.IsNullOrWhiteSpace(methodElement.RawSource), "Method snippet is invalid!");

            var fieldSearchResult = codeSearchResults.Find(el => el.ProgramElement.ProgramElementType == ProgramElementType.Field && el.ProgramElement.Name == "fileName");
            if(fieldSearchResult == null)
            {
                Assert.Fail("Failed to find relevant search result for search: " + keywords);
            }
            var fieldElement = fieldSearchResult.ProgramElement as FieldElement;
            Assert.AreEqual(fieldElement.AccessLevel, AccessLevel.Private, "Field access level differs!");
            Assert.True(fieldElement.ClassId != null && methodElement.ClassId != Guid.Empty, "Class id is invalid!");
            Assert.AreEqual(fieldElement.ClassName, "FileNameTemplate", "Field class name differs!");
            Assert.AreEqual(fieldElement.DefinitionLineNumber, 12, "Field definition line number differs!");
            Assert.True(fieldElement.FullFilePath.EndsWith("\\TestFiles\\StemmingTestFiles\\FileNameTemplate.cs".ToLowerInvariant()), "Field full file path is invalid!");
            Assert.AreEqual(fieldElement.Name, "fileName", "Field name differs!");
            Assert.AreEqual(fieldElement.ProgramElementType, ProgramElementType.Field, "Program element type differs!");
            Assert.AreEqual(fieldElement.FieldType, "string", "Field return type differs!");
            Assert.False(String.IsNullOrWhiteSpace(methodElement.RawSource), "Field snippet is invalid!");
        }
        public void Search(String searchString, SimpleSearchCriteria searchCriteria, bool interactive = true)
        {
            if (!EnsureSolutionOpen())
                return;

            try
            {
                var codeSearcher = new CodeSearcher();
                if (String.IsNullOrEmpty(searchString))
                    return;

                var solutionKey = ServiceLocator.ResolveOptional<SolutionKey>(); //no opened solution
                if (solutionKey == null)
                {
                    this.UpdateMessage("Sando searches only the currently open Solution.  Please open a Solution and try again.");

                }
                else
                {

                    searchString = ExtensionPointsRepository.Instance.GetQueryRewriterImplementation().RewriteQuery(searchString);

                    //PreRetrievalMetrics preMetrics = new PreRetrievalMetrics(ServiceLocator.Resolve<DocumentIndexer>().Reader, ServiceLocator.Resolve<Analyzer>());
                    //LogEvents.PreSearch(this, preMetrics.MaxIdf(searchString), preMetrics.AvgIdf(searchString), preMetrics.AvgSqc(searchString), preMetrics.AvgVar(searchString));
                    LogEvents.PreSearchQueryAnalysis(this, QueryMetrics.ExamineQuery(searchString).ToString(), QueryMetrics.DiceCoefficient(QueryMetrics.SavedQuery, searchString));
                    QueryMetrics.SavedQuery = searchString;

                    var results = codeSearcher.Search(searchCriteria, true).AsQueryable();
                    var resultsReorderer = ExtensionPointsRepository.Instance.GetResultsReordererImplementation();
                    results = resultsReorderer.ReorderSearchResults(results);

                    var returnString = new StringBuilder();

                    if (searchCriteria.IsQueryReformed())
                    {
                        returnString.Append(searchCriteria.GetQueryReformExplanation());
                    }

                    if (!results.Any())
                    {
                        returnString.Append("No results found. ");
                    }
                    else
                    {
                        returnString.Append(results.Count() + " results returned. ");
                    }

                    if (null != this.SearchResultUpdated)
                    {
                        this.SearchResultUpdated(searchString, results);
                    }

                    this.UpdateMessage(returnString.ToString());

                    if (null != this.RecommendedQueriesUpdated)
                    {
                        this.RecommendedQueriesUpdated(searchCriteria.GetRecommendedQueries());
                    }

                    LogEvents.PostSearch(this, results.Count(), searchCriteria.NumberOfSearchResultsReturned,
                        PostRetrievalMetrics.AvgScore(results.ToList()), PostRetrievalMetrics.StdDevScore(results.ToList()));

                }

            }
            catch (Exception e)
            {
                this.UpdateMessage("Sando is experiencing difficulties. See log file for details.");
                LogEvents.UISandoSearchingError(this, e);
            }
        }