Example #1
0
        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"
                    );
            }
        }
Example #2
0
        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
                        );
                }
            }
        }
Example #3
0
        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");
            }
        }
Example #5
0
        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());
                }
            }
        }
Example #6
0
        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());
                }
            }
        }
Example #7
0
        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"
                        );
                }
        }
Example #9
0
        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();
                }
            }
        }
Example #10
0
        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();
                }
            }
        }