Beispiel #1
0
        public void AddUpdateRemoveConfigurableFactory()
        {
            using (var wpf = new WpfProxy())
                using (var list = new EnvironmentListProxy(wpf)) {
                    list.Service = GetInterpreterOptionsService();

                    var before = wpf.Invoke(() => new HashSet <string>(
                                                list.Environments.Select(ev => (string)ev.InterpreterPath),
                                                StringComparer.OrdinalIgnoreCase
                                                ));

                    var configurable = list.Service.KnownProviders.OfType <ConfigurablePythonInterpreterFactoryProvider>().FirstOrDefault();
                    Assert.IsNotNull(configurable, "No configurable provider available");
                    var fact = configurable.SetOptions(new InterpreterFactoryCreationOptions {
                        Id = Guid.NewGuid(),
                        LanguageVersionString = "2.7",
                        // The actual file doesn't matter, except to test that it
                        // is added
                        InterpreterPath = TestData.GetPath("HelloWorld\\HelloWorld.pyproj")
                    });

                    try {
                        var afterAdd = wpf.Invoke(() => new HashSet <string>(
                                                      list.Environments.Select(ev => (string)ev.InterpreterPath),
                                                      StringComparer.OrdinalIgnoreCase
                                                      ));

                        Assert.AreNotEqual(before.Count, afterAdd.Count, "Did not add a new environment");
                        AssertUtil.ContainsExactly(
                            afterAdd.Except(before),
                            TestData.GetPath("HelloWorld\\HelloWorld.pyproj")
                            );

                        configurable.SetOptions(new InterpreterFactoryCreationOptions {
                            Id = fact.Id,
                            LanguageVersion = fact.Configuration.Version,
                            InterpreterPath = TestData.GetPath("HelloWorld2\\HelloWorld.pyproj")
                        });

                        var afterUpdate = wpf.Invoke(() => new HashSet <string>(
                                                         list.Environments.Select(ev => (string)ev.InterpreterPath),
                                                         StringComparer.OrdinalIgnoreCase
                                                         ));

                        Assert.AreEqual(afterAdd.Count, afterUpdate.Count, "Should not add/remove an environment");
                        AssertUtil.ContainsExactly(
                            afterUpdate.Except(before),
                            TestData.GetPath("HelloWorld2\\HelloWorld.pyproj")
                            );
                    } finally {
                        configurable.RemoveInterpreter(fact.Id);
                    }

                    var afterRemove = wpf.Invoke(() => new HashSet <string>(
                                                     list.Environments.Select(ev => (string)ev.InterpreterPath),
                                                     StringComparer.OrdinalIgnoreCase
                                                     ));
                    AssertUtil.ContainsExactly(afterRemove, before);
                }
        }
Beispiel #2
0
 public void Dispose()
 {
     if (_window != null)
     {
         _proxy.Invoke(() => _window.Dispose());
     }
 }
Beispiel #3
0
        public void PipExtension()
        {
            var service = MakeEmptyVEnv();

            using (var wpf = new WpfProxy())
                using (var list = new EnvironmentListProxy(wpf)) {
                    list.CreatePipExtension = true;
                    list.Service            = service;

                    var environment = list.Environments.Single();
                    var pip         = (PipExtensionProvider)list.GetExtensionOrAssert <PipExtensionProvider>(environment);

                    Assert.IsFalse(pip.IsPipInstalled().GetAwaiter().GetResult(), "venv should not install pip");
                    var task = wpf.Invoke(() => pip.InstallPip().ContinueWith <bool>(LogException));
                    Assert.IsTrue(task.Wait(TimeSpan.FromSeconds(120.0)), "pip install timed out");
                    Assert.IsTrue(task.Result, "pip install failed");
                    Assert.IsTrue(pip.IsPipInstalled().GetAwaiter().GetResult(), "pip was not installed");

                    var packages = pip.GetInstalledPackagesAsync().GetAwaiter().GetResult();
                    AssertUtil.ContainsExactly(packages.Select(pv => pv.Name), "pip", "setuptools");

                    task = wpf.Invoke(() => pip.InstallPackage("ptvsd", true).ContinueWith <bool>(LogException));
                    Assert.IsTrue(task.Wait(TimeSpan.FromSeconds(60.0)), "pip install ptvsd timed out");
                    Assert.IsTrue(task.Result, "pip install ptvsd failed");
                    packages = pip.GetInstalledPackagesAsync().GetAwaiter().GetResult();
                    AssertUtil.ContainsAtLeast(packages.Select(pv => pv.Name), "ptvsd");

                    task = wpf.Invoke(() => pip.UninstallPackage("ptvsd").ContinueWith <bool>(LogException));
                    Assert.IsTrue(task.Wait(TimeSpan.FromSeconds(60.0)), "pip uninstall ptvsd timed out");
                    Assert.IsTrue(task.Result, "pip uninstall ptvsd failed");
                    packages = pip.GetInstalledPackagesAsync().GetAwaiter().GetResult();
                    AssertUtil.DoesntContain(packages.Select(pv => pv.Name), "ptvsd");
                }
        }
Beispiel #4
0
        public void AddFactories()
        {
            var mockService = new MockInterpreterOptionsService();

            using (var wpf = new WpfProxy())
                using (var list = wpf.Invoke(() => new EnvironmentListProxy(wpf))) {
                    var provider = new MockPythonInterpreterFactoryProvider("Test Provider 1",
                                                                            new MockPythonInterpreterFactory(Guid.NewGuid(), "Test Factory 1", MockInterpreterConfiguration(new Version(2, 7))),
                                                                            new MockPythonInterpreterFactory(Guid.NewGuid(), "Test Factory 2", MockInterpreterConfiguration(new Version(3, 0))),
                                                                            new MockPythonInterpreterFactory(Guid.NewGuid(), "Test Factory 3", MockInterpreterConfiguration(new Version(3, 3)))
                                                                            );

                    list.Service = mockService;

                    Assert.AreEqual(0, list.Environments.Count);

                    mockService.AddProvider(provider);
                    Assert.AreEqual(3, list.Environments.Count);
                    provider.AddFactory(new MockPythonInterpreterFactory(Guid.NewGuid(), "Test Factory 4", MockInterpreterConfiguration(new Version(2, 7))));
                    Assert.AreEqual(4, list.Environments.Count);
                    provider.AddFactory(new MockPythonInterpreterFactory(Guid.NewGuid(), "Test Factory 5", MockInterpreterConfiguration(new Version(3, 0))));
                    Assert.AreEqual(5, list.Environments.Count);
                    provider.AddFactory(new MockPythonInterpreterFactory(Guid.NewGuid(), "Test Factory 6", MockInterpreterConfiguration(new Version(3, 3))));
                    Assert.AreEqual(6, list.Environments.Count);
                }
        }
Beispiel #5
0
        public void HasInterpreters()
        {
            var mockService = new MockInterpreterOptionsService();

            mockService.AddProvider(new MockPythonInterpreterFactoryProvider("Test Provider 1",
                                                                             new MockPythonInterpreterFactory(Guid.NewGuid(), "Test Factory 1", MockInterpreterConfiguration(new Version(2, 7))),
                                                                             new MockPythonInterpreterFactory(Guid.NewGuid(), "Test Factory 2", MockInterpreterConfiguration(new Version(3, 0))),
                                                                             new MockPythonInterpreterFactory(Guid.NewGuid(), "Test Factory 3", MockInterpreterConfiguration(new Version(3, 3)))
                                                                             ));
            mockService.AddProvider(new MockPythonInterpreterFactoryProvider("Test Provider 2",
                                                                             new MockPythonInterpreterFactory(Guid.NewGuid(), "Test Factory 4", MockInterpreterConfiguration(new Version(2, 7))),
                                                                             new MockPythonInterpreterFactory(Guid.NewGuid(), "Test Factory 5", MockInterpreterConfiguration(new Version(3, 0))),
                                                                             new MockPythonInterpreterFactory(Guid.NewGuid(), "Test Factory 6", MockInterpreterConfiguration(new Version(3, 3)))
                                                                             ));

            using (var wpf = new WpfProxy())
                using (var list = new EnvironmentListProxy(wpf)) {
                    list.Service = mockService;
                    var environments = list.Environments;

                    Assert.AreEqual(6, environments.Count);
                    AssertUtil.ContainsExactly(
                        wpf.Invoke(() => environments.Select(ev => ev.Description).ToList()),
                        Enumerable.Range(1, 6).Select(i => string.Format("Test Factory {0}", i))
                        );
                }
        }
Beispiel #6
0
        public void InstalledFactories()
        {
            using (var wpf = new WpfProxy())
                using (var list = new EnvironmentListProxy(wpf)) {
                    list.Service = GetInterpreterOptionsService();

                    var expected = new HashSet <string>(
                        PythonPaths.Versions
                        .Where(v => !v.IsIronPython)
                        .Select(v => v.InterpreterPath),
                        StringComparer.OrdinalIgnoreCase
                        );
                    var actual = wpf.Invoke(() => new HashSet <string>(
                                                list.Environments.Select(ev => (string)ev.InterpreterPath),
                                                StringComparer.OrdinalIgnoreCase
                                                ));

                    Console.WriteLine("Expected - Actual: " + string.Join(", ", expected.Except(actual).OrderBy(s => s)));
                    Console.WriteLine("Actual - Expected: " + string.Join(", ", actual.Except(expected).OrderBy(s => s)));

                    AssertUtil.ContainsExactly(
                        expected,
                        actual
                        );
                }
        }
Beispiel #7
0
        public void HasInterpreters()
        {
            var sp          = new MockServiceProvider();
            var mockService = new MockInterpreterOptionsService();

            mockService.AddProvider(new MockPythonInterpreterFactoryProvider("Test Provider 1",
                                                                             new MockPythonInterpreterFactory(MockInterpreterConfiguration("Test Factory 1", new Version(2, 7))),
                                                                             new MockPythonInterpreterFactory(MockInterpreterConfiguration("Test Factory 2", new Version(3, 0))),
                                                                             new MockPythonInterpreterFactory(MockInterpreterConfiguration("Test Factory 3", new Version(3, 3)))
                                                                             ));
            mockService.AddProvider(new MockPythonInterpreterFactoryProvider("Test Provider 2",
                                                                             new MockPythonInterpreterFactory(MockInterpreterConfiguration("Test Factory 4", new Version(2, 7))),
                                                                             new MockPythonInterpreterFactory(MockInterpreterConfiguration("Test Factory 5", new Version(3, 0))),
                                                                             new MockPythonInterpreterFactory(MockInterpreterConfiguration("Test Factory 6", new Version(3, 3))),
                                                                             new MockPythonInterpreterFactory(MockInterpreterConfiguration("Test Factory 7", new Version(3, 3), InterpreterUIMode.Hidden))
                                                                             ));

            using (var wpf = new WpfProxy())
                using (var list = new EnvironmentListProxy(wpf)) {
                    list.Service      = mockService;
                    list.Interpreters = mockService;
                    var environments = list.Environments;

                    Assert.AreEqual(6, environments.Count);
                    AssertUtil.ContainsExactly(
                        wpf.Invoke(() => environments.Select(ev => ev.Description).ToList()),
                        "Test Factory 1 2.7",
                        "Test Factory 2 3.0",
                        "Test Factory 3 3.3",
                        "Test Factory 4 2.7",
                        "Test Factory 5 3.0",
                        "Test Factory 6 3.3"
                        );
                }
        }
Beispiel #8
0
        public void NonDefaultInterpreter()
        {
            var mockProvider = new MockPythonInterpreterFactoryProvider("Test Provider 1",
                                                                        new MockPythonInterpreterFactory(MockInterpreterConfiguration("Test Factory 1", new Version(2, 7))),
                                                                        new MockPythonInterpreterFactory(MockInterpreterConfiguration("Test Factory 2", new Version(3, 0), InterpreterUIMode.CannotBeDefault)),
                                                                        new MockPythonInterpreterFactory(MockInterpreterConfiguration("Test Factory 3", new Version(3, 3), InterpreterUIMode.CannotBeAutoDefault))
                                                                        );

            using (var wpf = new WpfProxy())
                using (var list = new EnvironmentListProxy(wpf)) {
                    var container    = CreateCompositionContainer();
                    var service      = container.GetExportedValue <IInterpreterOptionsService>();
                    var interpreters = container.GetExportedValue <IInterpreterRegistryService>();
                    var oldDefault   = service.DefaultInterpreter;
                    var oldProviders = ((InterpreterRegistryService)interpreters).SetProviders(new[] {
                        new Lazy <IPythonInterpreterFactoryProvider, Dictionary <string, object> >(
                            () => mockProvider,
                            new Dictionary <string, object>()
                        {
                            { "InterpreterFactoryId", "Mock" }
                        }
                            )
                    });
                    try {
                        list.Service      = service;
                        list.Interpreters = interpreters;
                        var environments = list.Environments;

                        AssertUtil.AreEqual(
                            wpf.Invoke(() => environments.Select(ev => ev.Description).ToList()),
                            "Test Factory 1", "Test Factory 2", "Test Factory 3"
                            );
                        // TF 1 and 3 can be set as default
                        AssertUtil.AreEqual(
                            wpf.Invoke(() => environments.Select(ev => ev.CanBeDefault).ToList()),
                            true, false, true
                            );
                    } finally {
                        ((InterpreterRegistryService)interpreters).SetProviders(oldProviders);
                        service.DefaultInterpreter = oldDefault;
                    }
                }
        }
Beispiel #9
0
        public void LoadUnloadProjectFactories()
        {
            var service      = new MockInterpreterOptionsService();
            var mockProvider = new MockPythonInterpreterFactoryProvider("Test Provider");

            mockProvider.AddFactory(new MockPythonInterpreterFactory(Guid.NewGuid(), "Test Environment", MockInterpreterConfiguration(new Version(2, 7))));
            service.AddProvider(mockProvider);

            var loaded = new LoadedProjectInterpreterFactoryProvider();

            service.AddProvider(loaded);
            using (var wpf = new WpfProxy())
                using (var list = new EnvironmentListProxy(wpf)) {
                    list.Service = service;

                    // List only contains one entry
                    AssertUtil.ContainsExactly(
                        wpf.Invoke(() => list.Environments.Select(ev => ev.Description).ToList()),
                        "Test Environment"
                        );

                    var project = new MockPythonInterpreterFactoryProvider("Fake Project");
                    project.AddFactory(new MockPythonInterpreterFactory(Guid.NewGuid(), "Fake Environment", MockInterpreterConfiguration(new Version(2, 7))));

                    loaded.ProjectLoaded(project, null);

                    // List now contains two entries
                    AssertUtil.ContainsExactly(
                        wpf.Invoke(() => list.Environments.Select(ev => ev.Description).ToList()),
                        "Test Environment",
                        "Fake Environment"
                        );

                    loaded.ProjectUnloaded(project);

                    // List only has one entry again
                    AssertUtil.ContainsExactly(
                        wpf.Invoke(() => list.Environments.Select(ev => ev.Description).ToList()),
                        "Test Environment"
                        );
                }
        }
Beispiel #10
0
        public async Task AddUpdateRemoveConfigurableFactoryThroughUI()
        {
            using (var wpf = new WpfProxy())
                using (var list = new EnvironmentListProxy(wpf)) {
                    list.Service = GetInterpreterOptionsService();

                    var before = wpf.Invoke(() => new HashSet <Guid>(list.Environments.Where(ev => ev.Factory != null).Select(ev => ev.Factory.Id)));

                    var configurable = list.Service.KnownProviders.OfType <ConfigurablePythonInterpreterFactoryProvider>().FirstOrDefault();
                    Assert.IsNotNull(configurable, "No configurable provider available");

                    await list.Execute(ApplicationCommands.New, null);

                    var afterAdd = wpf.Invoke(() => new HashSet <Guid>(list.Environments.Where(ev => ev.Factory != null).Select(ev => ev.Factory.Id)));

                    var difference = new HashSet <Guid>(afterAdd);
                    difference.ExceptWith(before);

                    Console.WriteLine("Added {0}", AssertUtil.MakeText(difference));
                    Assert.AreEqual(1, difference.Count, "Did not add a new environment");
                    var newEnv = list.Service.Interpreters.Single(f => difference.Contains(f.Id));

                    Assert.IsTrue(configurable.IsConfigurable(newEnv), "Did not add a configurable environment");

                    // To remove the environment, we need to trigger the Remove
                    // command on the ConfigurationExtensionProvider's control
                    var view     = wpf.Invoke(() => list.Environments.First(ev => ev.Factory == newEnv));
                    var extView  = wpf.Invoke(() => view.Extensions.OfType <ConfigurationExtensionProvider>().First().WpfObject);
                    var confView = wpf.Invoke(() => (ConfigurationEnvironmentView)((System.Windows.Controls.Grid)extView.FindName("Subcontext")).DataContext);
                    await wpf.Execute((RoutedCommand)ConfigurationExtension.Remove, extView, confView);

                    var afterRemove = wpf.Invoke(() => new HashSet <Guid>(list.Environments.Where(ev => ev.Factory != null).Select(ev => ev.Factory.Id)));
                    AssertUtil.ContainsExactly(afterRemove, before);
                }
        }
Beispiel #11
0
        public void NonDefaultInterpreter()
        {
            var mockProvider = new MockPythonInterpreterFactoryProvider("Test Provider 1",
                                                                        new MockPythonInterpreterFactory(Guid.NewGuid(), "Test Factory 1", MockInterpreterConfiguration(new Version(2, 7))),
                                                                        new MockPythonInterpreterFactory(Guid.NewGuid(), "Test Factory 2", MockInterpreterConfiguration(new Version(3, 0), InterpreterUIMode.CannotBeDefault)),
                                                                        new MockPythonInterpreterFactory(Guid.NewGuid(), "Test Factory 3", MockInterpreterConfiguration(new Version(3, 3), InterpreterUIMode.CannotBeAutoDefault))
                                                                        );

            using (var wpf = new WpfProxy())
                using (var list = new EnvironmentListProxy(wpf)) {
                    var service      = GetInterpreterOptionsService();
                    var oldDefault   = service.DefaultInterpreter;
                    var oldProviders = ((InterpreterOptionsService)service).SetProviders(new[] { mockProvider });
                    try {
                        list.Service = service;
                        var environments = list.Environments;

                        AssertUtil.AreEqual(
                            wpf.Invoke(() => environments.Select(ev => ev.Description).ToList()),
                            "Test Factory 1", "Test Factory 2", "Test Factory 3"
                            );
                        // TF 1 and 3 can be set as default
                        AssertUtil.AreEqual(
                            wpf.Invoke(() => environments.Select(ev => ev.CanBeDefault).ToList()),
                            true, false, true
                            );

                        // TF 1 should have been selected as the default
                        Assert.AreEqual(
                            "Test Factory 1",
                            wpf.Invoke(() => environments.First(ev => ev.IsDefault).Description)
                            );
                    } finally {
                        ((InterpreterOptionsService)service).SetProviders(oldProviders);
                        service.DefaultInterpreter = oldDefault;
                    }
                }
        }
Beispiel #12
0
        public void AddRemoveProjectFactories()
        {
            var service = new MockInterpreterOptionsService();
            var loaded  = new LoadedProjectInterpreterFactoryProvider();

            service.AddProvider(loaded);
            using (var wpf = new WpfProxy())
                using (var list = new EnvironmentListProxy(wpf)) {
                    list.Service = service;

                    // List should be empty
                    AssertUtil.ContainsExactly(list.Environments);

                    var project = new MockPythonInterpreterFactoryProvider("Fake Project");

                    loaded.ProjectLoaded(project, null);

                    // List is still empty
                    AssertUtil.ContainsExactly(list.Environments);

                    project.AddFactory(new MockPythonInterpreterFactory(Guid.NewGuid(), "Fake Environment", MockInterpreterConfiguration(new Version(2, 7))));

                    // List now contains one project
                    AssertUtil.ContainsExactly(
                        wpf.Invoke(() => list.Environments.Select(ev => ev.Description).ToList()),
                        "Fake Environment"
                        );

                    project.RemoveAllFactories();

                    // List is empty again
                    AssertUtil.ContainsExactly(list.Environments);

                    loaded.ProjectUnloaded(project);
                }
        }
Beispiel #13
0
        public void RefreshDBStates()
        {
            using (var fact = new MockPythonInterpreterFactory(
                       Guid.NewGuid(),
                       "Test Factory 1",
                       MockInterpreterConfiguration(
                           PythonPaths.Versions.First().InterpreterPath
                           ),
                       true
                       ))
                using (var wpf = new WpfProxy())
                    using (var list = new EnvironmentListProxy(wpf)) {
                        list.CreateDBExtension = true;

                        var mockService = new MockInterpreterOptionsService();
                        mockService.AddProvider(new MockPythonInterpreterFactoryProvider("Test Provider 1", fact));
                        list.Service = mockService;
                        var view = list.Environments.Single();

                        Assert.IsFalse(wpf.Invoke(() => view.IsRefreshingDB));
                        Assert.IsTrue(list.CanExecute(DBExtension.StartRefreshDB, view));
                        Assert.IsFalse(fact.IsCurrent);
                        Assert.AreEqual(MockPythonInterpreterFactory.NoDatabaseReason, fact.GetIsCurrentReason(null));

                        list.Execute(DBExtension.StartRefreshDB, view).GetAwaiter().GetResult();
                        for (int retries = 10; retries > 0 && !wpf.Invoke(() => view.IsRefreshingDB); --retries)
                        {
                            Thread.Sleep(200);
                        }

                        Assert.IsTrue(wpf.Invoke(() => view.IsRefreshingDB));
                        Assert.IsFalse(list.CanExecute(DBExtension.StartRefreshDB, view));
                        Assert.IsFalse(fact.IsCurrent);
                        Assert.AreEqual(MockPythonInterpreterFactory.GeneratingReason, fact.GetIsCurrentReason(null));

                        fact.EndGenerateCompletionDatabase(AnalyzerStatusUpdater.GetIdentifier(fact), false);
                        for (int retries = 10; retries > 0 && wpf.Invoke(() => view.IsRefreshingDB); --retries)
                        {
                            Thread.Sleep(1000);
                        }

                        Assert.IsFalse(wpf.Invoke(() => view.IsRefreshingDB));
                        Assert.IsTrue(list.CanExecute(DBExtension.StartRefreshDB, view));
                        Assert.IsFalse(fact.IsCurrent);
                        Assert.AreEqual(MockPythonInterpreterFactory.MissingModulesReason, fact.GetIsCurrentReason(null));

                        list.Execute(DBExtension.StartRefreshDB, view).GetAwaiter().GetResult();

                        Assert.IsTrue(wpf.Invoke(() => view.IsRefreshingDB));
                        Assert.IsFalse(list.CanExecute(DBExtension.StartRefreshDB, view));
                        Assert.IsFalse(fact.IsCurrent);
                        Assert.AreEqual(MockPythonInterpreterFactory.GeneratingReason, fact.GetIsCurrentReason(null));

                        fact.EndGenerateCompletionDatabase(AnalyzerStatusUpdater.GetIdentifier(fact), true);
                        for (int retries = 10; retries > 0 && wpf.Invoke(() => view.IsRefreshingDB); --retries)
                        {
                            Thread.Sleep(1000);
                        }

                        Assert.IsFalse(wpf.Invoke(() => view.IsRefreshingDB));
                        Assert.IsTrue(list.CanExecute(DBExtension.StartRefreshDB, view));
                        Assert.IsTrue(fact.IsCurrent);
                        Assert.AreEqual(MockPythonInterpreterFactory.UpToDateReason, fact.GetIsCurrentReason(null));
                        Assert.AreEqual(MockPythonInterpreterFactory.UpToDateReason, fact.GetIsCurrentReason(null));
                    }
        }
Beispiel #14
0
        public void AddUpdateRemoveConfigurableFactory()
        {
            using (var wpf = new WpfProxy())
                using (var list = new EnvironmentListProxy(wpf)) {
                    var container    = CreateCompositionContainer();
                    var service      = container.GetExportedValue <IInterpreterOptionsService>();
                    var interpreters = container.GetExportedValue <IInterpreterRegistryService>();
                    list.Service      = service;
                    list.Interpreters = interpreters;

                    var before = wpf.Invoke(() => new HashSet <string>(
                                                list.Environments.Select(ev => (string)ev.InterpreterPath),
                                                StringComparer.OrdinalIgnoreCase
                                                ));

                    var id   = Guid.NewGuid().ToString();
                    var fact = list.Service.AddConfigurableInterpreter(
                        id,
                        new InterpreterConfiguration(
                            "",
                            "Blah",
                            "",
                            TestData.GetPath("HelloWorld\\HelloWorld.pyproj")
                            )
                        );

                    try {
                        var afterAdd = wpf.Invoke(() => new HashSet <string>(
                                                      list.Environments.Select(ev => (string)ev.InterpreterPath),
                                                      StringComparer.OrdinalIgnoreCase
                                                      ));

                        Assert.AreNotEqual(before.Count, afterAdd.Count, "Did not add a new environment");
                        AssertUtil.ContainsExactly(
                            afterAdd.Except(before),
                            TestData.GetPath("HelloWorld\\HelloWorld.pyproj")
                            );

                        list.Service.AddConfigurableInterpreter(
                            id,
                            new InterpreterConfiguration(
                                "",
                                "test",
                                "",
                                TestData.GetPath("HelloWorld2\\HelloWorld.pyproj")
                                )
                            );

                        var afterUpdate = wpf.Invoke(() => new HashSet <string>(
                                                         list.Environments.Select(ev => (string)ev.InterpreterPath),
                                                         StringComparer.OrdinalIgnoreCase
                                                         ));

                        Assert.AreEqual(afterAdd.Count, afterUpdate.Count, "Should not add/remove an environment");
                        AssertUtil.ContainsExactly(
                            afterUpdate.Except(before),
                            TestData.GetPath("HelloWorld2\\HelloWorld.pyproj")
                            );
                    } finally {
                        list.Service.RemoveConfigurableInterpreter(fact);
                    }

                    var afterRemove = wpf.Invoke(() => new HashSet <string>(
                                                     list.Environments.Select(ev => (string)ev.InterpreterPath),
                                                     StringComparer.OrdinalIgnoreCase
                                                     ));
                    AssertUtil.ContainsExactly(afterRemove, before);
                }
        }