public async Task LoadAndUnloadModule() { var factories = new[] { InterpreterFactoryCreator.CreateAnalysisInterpreterFactory(new Version(3, 3)) }; var services = PythonToolsTestUtilities.CreateMockServiceProvider().GetEditorServices(); using (var analyzer = await VsProjectAnalyzer.CreateForTestsAsync(services, factories[0])) { var m1Path = TestData.GetPath("TestData\\SimpleImport\\module1.py"); var m2Path = TestData.GetPath("TestData\\SimpleImport\\module2.py"); var entry1 = await analyzer.AnalyzeFileAsync(m1Path); var entry2 = await analyzer.AnalyzeFileAsync(m2Path); var cancel = CancellationTokens.After60s; analyzer.WaitForCompleteAnalysis(_ => !cancel.IsCancellationRequested); cancel.ThrowIfCancellationRequested(); var loc = new Microsoft.PythonTools.Parsing.SourceLocation(0, 1, 1); AssertUtil.ContainsExactly( analyzer.GetEntriesThatImportModuleAsync("module1", true).Result.Select(m => m.moduleName), "module2" ); AssertUtil.ContainsExactly( analyzer.GetValueDescriptions(entry2, "x", loc), "int" ); await analyzer.UnloadFileAsync(entry1); analyzer.WaitForCompleteAnalysis(_ => true); // Even though module1 has been unloaded, we still know that // module2 imports it. AssertUtil.ContainsExactly( analyzer.GetEntriesThatImportModuleAsync("module1", true).Result.Select(m => m.moduleName), "module2" ); AssertUtil.ContainsExactly( analyzer.GetValueDescriptions(entry2, "x", loc) ); await analyzer.AnalyzeFileAsync(m1Path); analyzer.WaitForCompleteAnalysis(_ => true); AssertUtil.ContainsExactly( analyzer.GetEntriesThatImportModuleAsync("module1", true).Result.Select(m => m.moduleName), "module2" ); AssertUtil.ContainsExactly( analyzer.GetValueDescriptions(entry2, "x", loc), "int" ); } }
private static async Task CodeFormattingTest(string input, object selection, string expected, object expectedSelection, CodeFormattingOptions options, bool formatSelected = true) { var fact = InterpreterFactoryCreator.CreateAnalysisInterpreterFactory(new Version(2, 7)); var editorTestToolset = new EditorTestToolset().WithPythonToolsService(); var services = editorTestToolset.GetPythonEditorServices(); editorTestToolset.GetService <IPythonToolsOptionsService>().ImportFrom(options); using (var analyzer = await VsProjectAnalyzer.CreateForTestsAsync(services, fact)) { var analysisStartedTask = EventTaskSources.VsProjectAnalyzer.AnalysisStarted.Create(analyzer); var buffer = editorTestToolset.CreatePythonTextBuffer(input, analyzer); var view = editorTestToolset.CreateTextView(buffer); await analysisStartedTask; var bi = services.GetBufferInfo(buffer); var entry = await analyzer.AnalyzeFileAsync(bi.Filename); Assert.AreEqual(entry, bi.TrySetAnalysisEntry(entry, null), "Failed to set analysis entry"); entry.GetOrCreateBufferParser(services).AddBuffer(buffer); if (formatSelected) { var selectionSpan = new SnapshotSpan( buffer.CurrentSnapshot, ExtractMethodTests.GetSelectionSpan(input, selection) ); await editorTestToolset.UIThread.InvokeTask(async() => { view.Selection.Select(selectionSpan, false); await EditFilter.GetOrCreate(services, view).FormatSelectionAsync(); }); } else { await editorTestToolset.UIThread.InvokeTask(async() => { await EditFilter.GetOrCreate(services, view).FormatDocumentAsync(); }); } Assert.AreEqual(expected, view.TextBuffer.CurrentSnapshot.GetText()); if (expectedSelection != null) { Assert.AreEqual( ExtractMethodTests.GetSelectionSpan(expected, expectedSelection), view.Selection.StreamSelectionSpan.SnapshotSpan.Span ); } } }
private static async Task <VsProjectAnalyzer> CreateAnalyzerAsync(PythonVersion version) { version.AssertInstalled(); var factory = new MockPythonInterpreterFactory(version.Configuration); var sp = new MockServiceProvider(); var services = new Microsoft.PythonTools.Editor.PythonEditorServices(sp); var interpreters = new MockInterpreterOptionsService(); interpreters.AddProvider(new MockPythonInterpreterFactoryProvider("Test Provider", factory)); services.InterpreterRegistryService = interpreters; services.InterpreterOptionsService = interpreters; return(await VsProjectAnalyzer.CreateForTestsAsync( services, factory )); }
public async Task AnalyzeBadEgg() { var factories = new[] { InterpreterFactoryCreator.CreateAnalysisInterpreterFactory(new Version(3, 4)) }; var services = PythonToolsTestUtilities.CreateMockServiceProvider().GetEditorServices(); using (var analyzer = await VsProjectAnalyzer.CreateForTestsAsync(services, factories[0])) { await analyzer.SetSearchPathsAsync(new[] { TestData.GetPath(@"TestData\BadEgg.egg") }); analyzer.WaitForCompleteAnalysis(_ => true); // Analysis result must contain the module for the filename inside the egg that is a valid identifier, // and no entries for the other filename which is not. var moduleNames = (await analyzer.GetModulesAsync(null, null)).Select(x => x.Name); AssertUtil.Contains(moduleNames, "module"); AssertUtil.DoesntContain(moduleNames, "42"); } }
private async Task ExtractMethodTest(string input, Func <Span> extract, TestResult expected, string scopeName = null, string targetName = "g", Version version = null, params string[] parameters) { var fact = InterpreterFactoryCreator.CreateAnalysisInterpreterFactory(version ?? new Version(2, 7)); var editorTestToolset = new EditorTestToolset().WithPythonToolsService(); var services = editorTestToolset.GetPythonEditorServices(); using (var analyzer = await VsProjectAnalyzer.CreateForTestsAsync(services, fact)) { var analysisStartedTask = EventTaskSources.VsProjectAnalyzer.AnalysisStarted.Create(analyzer); var buffer = editorTestToolset.CreatePythonTextBuffer(input, Path.Combine(TestData.GetTempPath(), "fob.py"), analyzer); var view = editorTestToolset.CreateTextView(buffer); await analysisStartedTask; var bi = services.GetBufferInfo(buffer); bi.ParseImmediately = true; var entry = await analyzer.AnalyzeFileAsync(bi.DocumentUri, bi.Filename); Assert.AreEqual(entry, bi.TrySetAnalysisEntry(entry, null)); var bp = entry.GetOrCreateBufferParser(services); bp.AddBuffer(buffer); await bp.EnsureCodeSyncedAsync(bi.Buffer, true); ExtractMethodTestInput extractInput = new ExtractMethodTestInput(true, scopeName, targetName, parameters ?? new string[0]); await editorTestToolset.UIThread.InvokeTask(() => { view.Selection.Select(new SnapshotSpan(view.TextBuffer.CurrentSnapshot, extract()), false); return(new Microsoft.PythonTools.Refactoring.MethodExtractor(services, view).ExtractMethod(extractInput)); }); if (expected.IsError) { Assert.AreEqual(expected.Text, extractInput.FailureReason); Assert.AreEqual(input, view.TextBuffer.CurrentSnapshot.GetText()); } else { Assert.AreEqual(null, extractInput.FailureReason); Assert.AreEqual(expected.Text, view.TextBuffer.CurrentSnapshot.GetText()); } } }
private async Task ExtractMethodTest(string input, Func <Span> extract, TestResult expected, string scopeName = null, string targetName = "g", Version version = null, params string[] parameters) { var fact = InterpreterFactoryCreator.CreateAnalysisInterpreterFactory(version ?? new Version(2, 7)); var services = PythonToolsTestUtilities.CreateMockServiceProvider().GetEditorServices(); using (var analyzer = await VsProjectAnalyzer.CreateForTestsAsync(services, fact)) { var buffer = new MockTextBuffer(input, PythonCoreConstants.ContentType, Path.Combine(TestData.GetTempPath(), "fob.py")); var view = new MockTextView(buffer); buffer.Properties.AddProperty(typeof(VsProjectAnalyzer), analyzer); var bi = services.GetBufferInfo(buffer); bi.ParseImmediately = true; var entry = await analyzer.AnalyzeFileAsync(bi.DocumentUri); Assert.AreEqual(entry, bi.TrySetAnalysisEntry(entry, null)); var bp = entry.GetOrCreateBufferParser(services); bp.AddBuffer(buffer); await bp.EnsureCodeSyncedAsync(bi.Buffer, true); var extractInput = new ExtractMethodTestInput(true, scopeName, targetName, parameters ?? new string[0]); view.Selection.Select( new SnapshotSpan(view.TextBuffer.CurrentSnapshot, extract()), false ); await new Microsoft.PythonTools.Refactoring.MethodExtractor(services, view).ExtractMethod(extractInput); if (expected.IsError) { Assert.AreEqual(expected.Text, extractInput.FailureReason); Assert.AreEqual(input, view.TextBuffer.CurrentSnapshot.GetText()); } else { Assert.AreEqual(null, extractInput.FailureReason); Assert.AreEqual(expected.Text, view.TextBuffer.CurrentSnapshot.GetText()); } } }
private static async Task CodeFormattingTest(string input, object selection, string expected, object expectedSelection, CodeFormattingOptions options, bool selectResult = true) { var fact = InterpreterFactoryCreator.CreateAnalysisInterpreterFactory(new Version(2, 7)); var services = PythonToolsTestUtilities.CreateMockServiceProvider().GetEditorServices(); using (var analyzer = await VsProjectAnalyzer.CreateForTestsAsync(services, fact)) { var buffer = new MockTextBuffer(input, PythonCoreConstants.ContentType, Path.Combine(TestData.GetTempPath(), "fob.py")); buffer.AddProperty(typeof(VsProjectAnalyzer), analyzer); var view = new MockTextView(buffer); var bi = services.GetBufferInfo(buffer); var entry = await analyzer.AnalyzeFileAsync(bi.Filename); Assert.AreEqual(entry, bi.TrySetAnalysisEntry(entry, null), "Failed to set analysis entry"); entry.GetOrCreateBufferParser(services).AddBuffer(buffer); var selectionSpan = new SnapshotSpan( buffer.CurrentSnapshot, ExtractMethodTests.GetSelectionSpan(input, selection) ); view.Selection.Select(selectionSpan, false); await analyzer.FormatCodeAsync( selectionSpan, view, options, selectResult ); Assert.AreEqual(expected, view.TextBuffer.CurrentSnapshot.GetText()); if (expectedSelection != null) { Assert.AreEqual( ExtractMethodTests.GetSelectionSpan(expected, expectedSelection), view.Selection.StreamSelectionSpan.SnapshotSpan.Span ); } } }
public async Task LoadAndUnloadModule() { var services = PythonToolsTestUtilities.CreateMockServiceProvider().GetEditorServices(); using (var are = new AutoResetEvent(false)) using (var analyzer = await VsProjectAnalyzer.CreateForTestsAsync(services, InterpreterFactoryCreator.CreateAnalysisInterpreterFactory(new Version(3, 6)))) { var m1Path = TestData.GetPath("TestData\\SimpleImport\\module1.py"); var m2Path = TestData.GetPath("TestData\\SimpleImport\\module2.py"); var toAnalyze = new HashSet <string>(StringComparer.OrdinalIgnoreCase) { m1Path, m2Path }; analyzer.AnalysisComplete += (s, e) => { lock (toAnalyze) { toAnalyze.Remove(e.Path); } are.Set(); }; var entry1 = await analyzer.AnalyzeFileAsync(m1Path); var entry2 = await analyzer.AnalyzeFileAsync(m2Path); WaitForEmptySet(are, toAnalyze, CancellationTokens.After60s); var loc = new Microsoft.PythonTools.SourceLocation(1, 1); AssertUtil.ContainsExactly( analyzer.GetEntriesThatImportModuleAsync("module1", true).Result.Select(m => m.moduleName), "module2" ); AssertUtil.ContainsExactly( analyzer.GetValueDescriptions(entry2, "x", loc), "int" ); toAnalyze.Add(m2Path); await analyzer.UnloadFileAsync(entry1); WaitForEmptySet(are, toAnalyze, CancellationTokens.After15s); // Even though module1 has been unloaded, we still know that // module2 imports it. AssertUtil.ContainsExactly( analyzer.GetEntriesThatImportModuleAsync("module1", true).Result.Select(m => m.moduleName), "module2" ); AssertUtil.ContainsExactly( analyzer.GetValueDescriptions(entry2, "x", loc) ); toAnalyze.Add(m1Path); toAnalyze.Add(m2Path); await analyzer.AnalyzeFileAsync(m1Path); WaitForEmptySet(are, toAnalyze, CancellationTokens.After5s); AssertUtil.ContainsExactly( analyzer.GetEntriesThatImportModuleAsync("module1", true).Result.Select(m => m.moduleName), "module2" ); AssertUtil.ContainsExactly( analyzer.GetValueDescriptions(entry2, "x", loc), "int" ); } }
public PythonEditor( string content = null, PythonLanguageVersion version = PythonLanguageVersion.V27, MockVs vs = null, IPythonInterpreterFactory factory = null, VsProjectAnalyzer analyzer = null, string filename = null, bool?inProcAnalyzer = null ) { if (vs == null) { _disposeVS = true; vs = new MockVs(); } MockVsTextView view = null; try { AdvancedEditorOptions advancedOptions = null; vs.InvokeSync(() => { advancedOptions = vs.GetPyService().AdvancedOptions; advancedOptions.AutoListMembers = true; advancedOptions.AutoListIdentifiers = false; }); AdvancedOptions = advancedOptions; if (factory == null) { vs.InvokeSync(() => { factory = vs.ComponentModel.GetService <IInterpreterRegistryService>() .Interpreters .FirstOrDefault(c => c.GetLanguageVersion() == version && c.Configuration.Id.StartsWith("Global|PythonCore")); if (factory != null) { Console.WriteLine($"Using interpreter {factory.Configuration.InterpreterPath}"); } }); if (factory == null) { _disposeFactory = true; factory = InterpreterFactoryCreator.CreateAnalysisInterpreterFactory(version.ToVersion()); Console.WriteLine("Using analysis-only interpreter"); } } if (analyzer == null) { _disposeAnalyzer = true; analyzer = vs.InvokeTask(() => VsProjectAnalyzer.CreateForTestsAsync(vs.ComponentModel.GetService <PythonEditorServices>(), factory, inProcAnalyzer ?? Debugger.IsAttached), 10000); } Uri uri; if (string.IsNullOrEmpty(filename)) { filename = Path.ChangeExtension(Path.GetRandomFileName(), ".py"); } if (Path.IsPathRooted(filename)) { uri = new Uri(filename); } else { var d = Path.GetRandomFileName(); uri = new Uri($"python://test/{d}/{filename}"); filename = $"_:\\PYTHON\\{d}\\{filename}"; } var cancel = CancellationTokens.After60s; view = vs.CreateTextView(PythonCoreConstants.ContentType, content ?? "", v => { v.TextView.TextBuffer.Properties[BufferParser.ParseImmediately] = true; v.TextView.TextBuffer.Properties[IntellisenseController.SuppressErrorLists] = IntellisenseController.SuppressErrorLists; v.TextView.TextBuffer.Properties[VsProjectAnalyzer._testAnalyzer] = analyzer; v.TextView.TextBuffer.Properties[VsProjectAnalyzer._testFilename] = filename; v.TextView.TextBuffer.Properties[VsProjectAnalyzer._testDocumentUri] = uri; }, filename); var services = vs.ComponentModel.GetService <PythonEditorServices>(); var bi = services.GetBufferInfo(view.TextView.TextBuffer); var entry = bi.GetAnalysisEntryAsync(cancel).WaitAndUnwrapExceptions(); Assert.IsNotNull(entry, "failed to get analysis entry"); if (!string.IsNullOrEmpty(content) && !cancel.IsCancellationRequested && !entry.IsAnalyzed) { var task = entry.Analyzer.WaitForNextCompleteAnalysis(); var bp = entry.TryGetBufferParser(); while (bp == null) { Thread.Sleep(50); cancel.ThrowIfCancellationRequested(); bp = entry.TryGetBufferParser(); } try { bp.EnsureCodeSyncedAsync(bi.Buffer, true).Wait(cancel); task.Wait(cancel); } catch (AggregateException ex) when(ex.InnerException != null) { throw ex.InnerException; } catch (OperationCanceledException) { } } if (cancel.IsCancellationRequested) { Assert.Fail("Timed out waiting for code analysis"); } vs.ThrowPendingException(); View = view; view = null; Analyzer = analyzer; analyzer = null; Factory = factory; factory = null; VS = vs; vs = null; } finally { if (view != null) { view.Dispose(); } if (analyzer != null && _disposeAnalyzer) { analyzer.Dispose(); } if (factory != null && _disposeFactory) { var disp = factory as IDisposable; if (disp != null) { disp.Dispose(); } } if (vs != null && _disposeVS) { vs.Dispose(); } } }
public PythonEditor( string content = null, PythonLanguageVersion version = PythonLanguageVersion.V27, MockVs vs = null, IPythonInterpreterFactory factory = null, VsProjectAnalyzer analyzer = null, string filename = null, bool?inProcAnalyzer = null ) { if (vs == null) { _disposeVS = true; vs = new MockVs(); } MockVsTextView view = null; try { AdvancedEditorOptions advancedOptions = null; vs.InvokeSync(() => { advancedOptions = vs.GetPyService().AdvancedOptions; advancedOptions.AutoListMembers = true; advancedOptions.AutoListIdentifiers = false; }); AdvancedOptions = advancedOptions; if (factory == null) { vs.InvokeSync(() => { factory = vs.ComponentModel.GetService <IInterpreterRegistryService>() .Interpreters .FirstOrDefault(c => c.GetLanguageVersion() == version && c.Configuration.Id.StartsWith("Global|PythonCore")); if (factory != null) { Console.WriteLine($"Using interpreter {factory.Configuration.InterpreterPath}"); } }); if (factory == null) { _disposeFactory = true; factory = InterpreterFactoryCreator.CreateAnalysisInterpreterFactory(version.ToVersion()); Console.WriteLine("Using analysis-only interpreter"); } } if (analyzer == null) { _disposeAnalyzer = true; analyzer = vs.InvokeTask(() => VsProjectAnalyzer.CreateForTestsAsync(vs.ComponentModel.GetService <PythonEditorServices>(), factory, inProcAnalyzer ?? Debugger.IsAttached)); } if (string.IsNullOrEmpty(filename)) { do { filename = PathUtils.GetAbsoluteFilePath(TestData.GetTempPath(), Path.GetRandomFileName()) + ".py"; } while (File.Exists(filename)); } var cancel = CancellationTokens.After60s; using (var mre = new ManualResetEventSlim()) { view = vs.CreateTextView(PythonCoreConstants.ContentType, content ?? "", v => { v.TextView.TextBuffer.Properties[BufferParser.ParseImmediately] = true; v.TextView.TextBuffer.Properties[IntellisenseController.SuppressErrorLists] = IntellisenseController.SuppressErrorLists; v.TextView.TextBuffer.Properties[VsProjectAnalyzer._testAnalyzer] = analyzer; v.TextView.TextBuffer.Properties[VsProjectAnalyzer._testFilename] = filename; }, filename); var entry = analyzer.GetAnalysisEntryFromPath(filename); while (entry == null && !cancel.IsCancellationRequested) { Thread.Sleep(50); entry = analyzer.GetAnalysisEntryFromPath(filename); } if (!string.IsNullOrEmpty(content) && !cancel.IsCancellationRequested && !entry.IsAnalyzed) { EventHandler evt = (s, e) => mre.SetIfNotDisposed(); try { entry.AnalysisComplete += evt; while (!mre.Wait(50, cancel) && !vs.HasPendingException && !entry.IsAnalyzed) { if (!analyzer.IsAnalyzing && !entry.IsAnalyzed) { var bp = entry.TryGetBufferParser(); Assert.IsNotNull(bp, "No buffer parser was ever created"); var bi = PythonTextBufferInfo.TryGetForBuffer(view.TextView.TextBuffer); Assert.IsNotNull(bi, "No BufferInfo was ever created"); bi.LastSentSnapshot = null; bp.EnsureCodeSyncedAsync(view.TextView.TextBuffer).WaitAndUnwrapExceptions(); } } } catch (OperationCanceledException) { } finally { entry.AnalysisComplete -= evt; } } if (cancel.IsCancellationRequested) { Assert.Fail("Timed out waiting for code analysis"); } vs.ThrowPendingException(); } View = view; view = null; Analyzer = analyzer; analyzer = null; Factory = factory; factory = null; VS = vs; vs = null; } finally { if (view != null) { view.Dispose(); } if (analyzer != null && _disposeAnalyzer) { analyzer.Dispose(); } if (factory != null && _disposeFactory) { var disp = factory as IDisposable; if (disp != null) { disp.Dispose(); } } if (vs != null && _disposeVS) { vs.Dispose(); } } }