private async Task UpdateTestCasesAsync(IEnumerable <string> paths, bool notify) { var analyzer = await _project.GetAnalyzerAsync(); if (analyzer == null) { return; } var testCaseData = await analyzer.SendExtensionCommandAsync( TestAnalyzer.Name, TestAnalyzer.GetTestCasesCommand, string.Join(";", paths) ); if (testCaseData == null) { return; } var testCaseGroups = TestAnalyzer.GetTestCases(testCaseData).GroupBy(tc => tc.Filename); bool anythingToNotify = false; foreach (var testCases in testCaseGroups) { var path = testCases.Key; if (testCases.Any()) { if (!TryGetContainer(path, out TestContainer existing) || !existing.TestCases.SequenceEqual(testCases)) { // we have a new entry or some of the tests changed int version = (existing?.Version ?? 0) + 1; lock (_containersLock) { _containers[path] = new TestContainer( _discoverer, path, _project, version, Architecture, testCases.ToArray() ); } anythingToNotify = true; } } else if (RemoveContainer(path)) { // Raise containers changed event... anythingToNotify = true; } } if (notify && anythingToNotify) { ContainersChanged(); } }
public async void AnalysisComplete(object sender, AnalysisCompleteEventArgs e) { var testCaseData = await _project.Analyzer.SendExtensionCommandAsync( TestAnalyzer.Name, TestAnalyzer.GetTestCasesCommand, e.Path ); if (testCaseData == null) { return; } var testCases = TestAnalyzer.GetTestCases(testCaseData); if (testCases.Length != 0) { TestContainer existing; bool changed = true; if (_containers.TryGetValue(e.Path, out existing)) { // we have an existing entry, let's see if any of the tests actually changed. if (existing.TestCases.Length == testCases.Length) { changed = false; for (int i = 0; i < existing.TestCases.Length; i++) { if (!existing.TestCases[i].Equals(testCases[i])) { changed = true; break; } } } } if (changed) { // we have a new entry or some of the tests changed int version = (existing?.Version ?? 0) + 1; _containers[e.Path] = new TestContainer( _discoverer, e.Path, _project, version, Architecture, testCases ); ContainersChanged(); } } else if (_containers.Remove(e.Path)) { // Raise containers changed event... ContainersChanged(); } }
public string GetCurrentTest(string filePath, int line, int lineCharOffset) { var project = PathToProject(filePath); if (project != null && _discoverer.IsProjectKnown(project)) { var buildEngine = new MSBuild.ProjectCollection(); string projectPath; if (project.TryGetProjectPath(out projectPath)) { var proj = buildEngine.LoadProject(projectPath); #if FALSE var provider = new MSBuildProjectInterpreterFactoryProvider(_interpreterService, proj); try { provider.DiscoverInterpreters(); } catch (InvalidDataException) { // This exception can be safely ignored here. } var factory = provider.ActiveInterpreter; var parser = Parser.CreateParser( new StreamReader(filePath), factory.GetLanguageVersion() ); var ast = parser.ParseFile(); var walker = new FunctionFinder(ast, line, lineCharOffset); ast.Walk(walker); var projHome = Path.GetFullPath(Path.Combine(proj.DirectoryPath, proj.GetPropertyValue(PythonConstants.ProjectHomeSetting) ?? ".")); if (walker.ClassName != null && walker.FunctionName != null) { return(TestAnalyzer.MakeFullyQualifiedTestName( CommonUtils.CreateFriendlyFilePath(projHome, filePath), walker.ClassName, walker.FunctionName )); } #endif } } return(null); }
private void AddModule(TestAnalyzer analyzer, string moduleName, string code, string moduleFile = null) { using (var source = new StringReader(code)) { analyzer.AddModule( moduleName, TestData.GetPath("Fob\\" + (moduleFile ?? moduleName.Replace('.', '\\') + ".py")), source ); } }
public void DiscoverTests(IEnumerable<string> sources, IDiscoveryContext discoveryContext, IMessageLogger logger, ITestCaseDiscoverySink discoverySink) { ValidateArg.NotNull(sources, "sources"); ValidateArg.NotNull(discoverySink, "discoverySink"); var buildEngine = new MSBuild.ProjectCollection(); try { // Load all the test containers passed in (.pyproj msbuild files) foreach (string source in sources) { buildEngine.LoadProject(source); } foreach (var proj in buildEngine.LoadedProjects) { using (var provider = new MSBuildProjectInterpreterFactoryProvider(_interpreterService, proj)) { try { provider.DiscoverInterpreters(); } catch (InvalidDataException) { // This exception can be safely ignored here. } var factory = provider.ActiveInterpreter; if (factory == _interpreterService.NoInterpretersValue) { if (logger != null) { logger.SendMessage(TestMessageLevel.Warning, "No interpreters available for project " + proj.FullPath); } continue; } var projectHome = Path.GetFullPath(Path.Combine(proj.DirectoryPath, proj.GetPropertyValue(PythonConstants.ProjectHomeSetting) ?? ".")); // Do the analysis even if the database is not up to date. At // worst, we'll get no results. using (var analyzer = new TestAnalyzer( factory, proj.FullPath, projectHome, TestExecutor.ExecutorUri )) { // Provide all files to the test analyzer foreach (var item in proj.GetItems("Compile")) { string fileAbsolutePath = CommonUtils.GetAbsoluteFilePath(projectHome, item.EvaluatedInclude); string fullName; try { fullName = ModulePath.FromFullPath(fileAbsolutePath).ModuleName; } catch (ArgumentException) { if (logger != null) { logger.SendMessage(TestMessageLevel.Warning, "File has an invalid module name: " + fileAbsolutePath); } continue; } try { using (var reader = new StreamReader(fileAbsolutePath)) { analyzer.AddModule(fullName, fileAbsolutePath, reader); } } catch (FileNotFoundException) { // user deleted file, we send the test update, but the project // isn't saved. #if DEBUG } catch (Exception ex) { if (logger != null) { logger.SendMessage(TestMessageLevel.Warning, "Failed to discover tests in " + fileAbsolutePath); logger.SendMessage(TestMessageLevel.Informational, ex.ToString()); } } #else } catch (Exception) { if (logger != null) { logger.SendMessage(TestMessageLevel.Warning, "Failed to discover tests in " + fileAbsolutePath); } } #endif }
public void DiscoverTests(IEnumerable <string> sources, IDiscoveryContext discoveryContext, IMessageLogger logger, ITestCaseDiscoverySink discoverySink) { ValidateArg.NotNull(sources, "sources"); ValidateArg.NotNull(discoverySink, "discoverySink"); var buildEngine = new MSBuild.ProjectCollection(); try { // Load all the test containers passed in (.pyproj msbuild files) foreach (string source in sources) { buildEngine.LoadProject(source); } foreach (var proj in buildEngine.LoadedProjects) { using (var provider = new MSBuildProjectInterpreterFactoryProvider(_interpreterService, proj)) { try { provider.DiscoverInterpreters(); } catch (InvalidDataException) { // This exception can be safely ignored here. } var factory = provider.ActiveInterpreter; if (factory == _interpreterService.NoInterpretersValue) { if (logger != null) { logger.SendMessage(TestMessageLevel.Warning, "No interpreters available for project " + proj.FullPath); } continue; } var projectHome = Path.GetFullPath(Path.Combine(proj.DirectoryPath, proj.GetPropertyValue(PythonConstants.ProjectHomeSetting) ?? ".")); // Do the analysis even if the database is not up to date. At // worst, we'll get no results. using (var analyzer = new TestAnalyzer( factory, proj.FullPath, projectHome, TestExecutor.ExecutorUri )) { // Provide all files to the test analyzer foreach (var item in proj.GetItems("Compile")) { string fileAbsolutePath = CommonUtils.GetAbsoluteFilePath(projectHome, item.EvaluatedInclude); string fullName; try { fullName = ModulePath.FromFullPath(fileAbsolutePath).ModuleName; } catch (ArgumentException) { if (logger != null) { logger.SendMessage(TestMessageLevel.Warning, "File has an invalid module name: " + fileAbsolutePath); } continue; } try { using (var reader = new StreamReader(fileAbsolutePath)) { analyzer.AddModule(fullName, fileAbsolutePath, reader); } } catch (FileNotFoundException) { // user deleted file, we send the test update, but the project // isn't saved. #if DEBUG } catch (Exception ex) { if (logger != null) { logger.SendMessage(TestMessageLevel.Warning, "Failed to discover tests in " + fileAbsolutePath); logger.SendMessage(TestMessageLevel.Informational, ex.ToString()); } } #else } catch (Exception) { if (logger != null) { logger.SendMessage(TestMessageLevel.Warning, "Failed to discover tests in " + fileAbsolutePath); } } #endif }
private async Task <bool> UpdateTestCasesAsync(string path, bool notify) { var testCaseData = await _project.Analyzer.SendExtensionCommandAsync( TestAnalyzer.Name, TestAnalyzer.GetTestCasesCommand, path ); if (testCaseData == null) { return(false); } var testCases = TestAnalyzer.GetTestCases(testCaseData); if (testCases.Length != 0) { TestContainer existing; bool changed = true; if (_containers.TryGetValue(path, out existing)) { // we have an existing entry, let's see if any of the tests actually changed. if (existing.TestCases.Length == testCases.Length) { changed = false; for (int i = 0; i < existing.TestCases.Length; i++) { if (!existing.TestCases[i].Equals(testCases[i])) { changed = true; break; } } } } if (changed) { // we have a new entry or some of the tests changed int version = (existing?.Version ?? 0) + 1; _containers[path] = new TestContainer( _discoverer, path, _project, version, Architecture, testCases ); if (notify) { ContainersChanged(); } return(true); } } else if (_containers.Remove(path)) { // Raise containers changed event... if (notify) { ContainersChanged(); } return(true); } return(false); }