Пример #1
0
        public PullRequestListViewModel(
            IRepositoryHost repositoryHost,
            ILocalRepositoryModel repository,
            IPackageSettings settings)
        {
            this.repositoryHost = repositoryHost;
            this.repository     = repository;
            this.settings       = settings;

            this.listSettings = settings.UIState
                                .GetOrCreateRepositoryState(repository.CloneUrl)
                                .PullRequests;

            openPullRequestCommand = ReactiveCommand.Create();
            openPullRequestCommand.Subscribe(_ =>
            {
                VisualStudio.Services.DefaultExportProvider.GetExportedValue <IVisualStudioBrowser>().OpenUrl(repositoryHost.Address.WebUri);
            });

            States = new List <PullRequestState> {
                new PullRequestState {
                    IsOpen = true, Name = "Open"
                },
                new PullRequestState {
                    IsOpen = false, Name = "Closed"
                },
                new PullRequestState {
                    Name = "All"
                }
            };

            trackingAuthors = new TrackingCollection <IAccount>(Observable.Empty <IAccount>(),
                                                                OrderedComparer <IAccount> .OrderByDescending(x => x.Login).Compare);
            trackingAssignees = new TrackingCollection <IAccount>(Observable.Empty <IAccount>(),
                                                                  OrderedComparer <IAccount> .OrderByDescending(x => x.Login).Compare);
            trackingAuthors.Subscribe();
            trackingAssignees.Subscribe();

            Authors   = trackingAuthors.CreateListenerCollection(EmptyUser, this.WhenAnyValue(x => x.SelectedAuthor));
            Assignees = trackingAssignees.CreateListenerCollection(EmptyUser, this.WhenAnyValue(x => x.SelectedAssignee));

            PullRequests          = new TrackingCollection <IPullRequestModel>();
            pullRequests.Comparer = OrderedComparer <IPullRequestModel> .OrderByDescending(x => x.UpdatedAt).Compare;

            pullRequests.NewerComparer = OrderedComparer <IPullRequestModel> .OrderByDescending(x => x.UpdatedAt).Compare;

            this.WhenAny(x => x.SelectedState, x => x.Value)
            .Where(x => PullRequests != null)
            .Subscribe(s => UpdateFilter(s, SelectedAssignee, SelectedAuthor));

            this.WhenAny(x => x.SelectedAssignee, x => x.Value)
            .Where(x => PullRequests != null && x != EmptyUser && IsLoaded)
            .Subscribe(a => UpdateFilter(SelectedState, a, SelectedAuthor));

            this.WhenAny(x => x.SelectedAuthor, x => x.Value)
            .Where(x => PullRequests != null && x != EmptyUser && IsLoaded)
            .Subscribe(a => UpdateFilter(SelectedState, SelectedAssignee, a));

            SelectedState = States.FirstOrDefault(x => x.Name == listSettings.SelectedState) ?? States[0];
        }
Пример #2
0
        public PullRequestListViewModel(
            IRepositoryHost repositoryHost,
            ILocalRepositoryModel repository,
            IPackageSettings settings)
        {
            this.repositoryHost = repositoryHost;
            this.repository     = repository;
            this.settings       = settings;

            Title = Resources.PullRequestsNavigationItemText;

            this.listSettings = settings.UIState
                                .GetOrCreateRepositoryState(repository.CloneUrl)
                                .PullRequests;

            States = new List <PullRequestState> {
                new PullRequestState {
                    IsOpen = true, Name = "Open"
                },
                new PullRequestState {
                    IsOpen = false, Name = "Closed"
                },
                new PullRequestState {
                    Name = "All"
                }
            };

            trackingAuthors = new TrackingCollection <IAccount>(Observable.Empty <IAccount>(),
                                                                OrderedComparer <IAccount> .OrderByDescending(x => x.Login).Compare);
            trackingAssignees = new TrackingCollection <IAccount>(Observable.Empty <IAccount>(),
                                                                  OrderedComparer <IAccount> .OrderByDescending(x => x.Login).Compare);
            trackingAuthors.Subscribe();
            trackingAssignees.Subscribe();

            Authors   = trackingAuthors.CreateListenerCollection(EmptyUser, this.WhenAnyValue(x => x.SelectedAuthor));
            Assignees = trackingAssignees.CreateListenerCollection(EmptyUser, this.WhenAnyValue(x => x.SelectedAssignee));

            PullRequests          = new TrackingCollection <IPullRequestModel>();
            pullRequests.Comparer = OrderedComparer <IPullRequestModel> .OrderByDescending(x => x.UpdatedAt).Compare;

            pullRequests.NewerComparer = OrderedComparer <IPullRequestModel> .OrderByDescending(x => x.UpdatedAt).Compare;

            this.WhenAny(x => x.SelectedState, x => x.Value)
            .Where(x => PullRequests != null)
            .Subscribe(s => UpdateFilter(s, SelectedAssignee, SelectedAuthor));

            this.WhenAny(x => x.SelectedAssignee, x => x.Value)
            .Where(x => PullRequests != null && x != EmptyUser && IsLoaded)
            .Subscribe(a => UpdateFilter(SelectedState, a, SelectedAuthor));

            this.WhenAny(x => x.SelectedAuthor, x => x.Value)
            .Where(x => PullRequests != null && x != EmptyUser && IsLoaded)
            .Subscribe(a => UpdateFilter(SelectedState, SelectedAssignee, a));

            SelectedState   = States.FirstOrDefault(x => x.Name == listSettings.SelectedState) ?? States[0];
            OpenPullRequest = ReactiveCommand.Create();
            OpenPullRequest.Subscribe(DoOpenPullRequest);
            CreatePullRequest = ReactiveCommand.Create();
            CreatePullRequest.Subscribe(_ => DoCreatePullRequest());
        }
        public PullRequestListViewModel(IRepositoryHost repositoryHost, ISimpleRepositoryModel repository)
        {
            this.repositoryHost = repositoryHost;
            this.repository     = repository;

            openPullRequestCommand = ReactiveCommand.Create();
            openPullRequestCommand.Subscribe(_ =>
            {
                VisualStudio.Services.DefaultExportProvider.GetExportedValue <IVisualStudioBrowser>().OpenUrl(repositoryHost.Address.WebUri);
            });

            States = new List <PullRequestState> {
                new PullRequestState {
                    IsOpen = true, Name = "Open"
                },
                new PullRequestState {
                    IsOpen = false, Name = "Closed"
                },
                new PullRequestState {
                    Name = "All"
                }
            };
            SelectedState = States[0];

            this.WhenAny(x => x.SelectedState, x => x.Value)
            .Where(x => PullRequests != null)
            .Subscribe(s => UpdateFilter(s, SelectedAssignee, SelectedAuthor));

            this.WhenAny(x => x.SelectedAssignee, x => x.Value)
            .Where(x => PullRequests != null)
            .Subscribe(a => UpdateFilter(SelectedState, a, SelectedAuthor));

            this.WhenAny(x => x.SelectedAuthor, x => x.Value)
            .Where(x => PullRequests != null)
            .Subscribe(a => UpdateFilter(SelectedState, SelectedAssignee, a));

            trackingAuthors = new TrackingCollection <IAccount>(Observable.Empty <IAccount>(),
                                                                OrderedComparer <IAccount> .OrderByDescending(x => x.Login).Compare);
            trackingAssignees = new TrackingCollection <IAccount>(Observable.Empty <IAccount>(),
                                                                  OrderedComparer <IAccount> .OrderByDescending(x => x.Login).Compare);
            trackingAuthors.Subscribe();
            trackingAssignees.Subscribe();

            Authors = trackingAuthors.CreateListenerCollection(new List <IAccount> {
                EmptyUser
            });
            Assignees = trackingAssignees.CreateListenerCollection(new List <IAccount> {
                EmptyUser
            });

            PullRequests          = new TrackingCollection <IPullRequestModel>();
            pullRequests.Comparer = OrderedComparer <IPullRequestModel> .OrderByDescending(x => x.UpdatedAt).Compare;

            pullRequests.Filter        = (pr, i, l) => pr.IsOpen;
            pullRequests.NewerComparer = OrderedComparer <IPullRequestModel> .OrderByDescending(x => x.UpdatedAt).Compare;
        }
    static TrackingCollection <Thing> CreateSource()
    {
        var result = new TrackingCollection <Thing>(Observable.Empty <Thing>());

        result.Subscribe();
        result.AddItem(new Thing(1, "item1", DateTimeOffset.MinValue));
        result.AddItem(new Thing(2, "item2", DateTimeOffset.MinValue));
        result.AddItem(new Thing(3, "item3", DateTimeOffset.MinValue));
        return(result);
    }
        public PullRequestListViewModel(
            IRepositoryHost repositoryHost,
            ILocalRepositoryModel repository,
            IPackageSettings settings)
        {
            this.repositoryHost = repositoryHost;
            this.repository = repository;
            this.settings = settings;

            Title = Resources.PullRequestsNavigationItemText;

            this.listSettings = settings.UIState
                .GetOrCreateRepositoryState(repository.CloneUrl)
                .PullRequests;

            openPullRequestCommand = ReactiveCommand.Create();
            openPullRequestCommand.Subscribe(_ =>
            {
                VisualStudio.Services.DefaultExportProvider.GetExportedValue<IVisualStudioBrowser>().OpenUrl(repositoryHost.Address.WebUri);
            });

            States = new List<PullRequestState> {
                new PullRequestState { IsOpen = true, Name = "Open" },
                new PullRequestState { IsOpen = false, Name = "Closed" },
                new PullRequestState { Name = "All" }
            };

            trackingAuthors = new TrackingCollection<IAccount>(Observable.Empty<IAccount>(),
                OrderedComparer<IAccount>.OrderByDescending(x => x.Login).Compare);
            trackingAssignees = new TrackingCollection<IAccount>(Observable.Empty<IAccount>(),
                OrderedComparer<IAccount>.OrderByDescending(x => x.Login).Compare);
            trackingAuthors.Subscribe();
            trackingAssignees.Subscribe();

            Authors = trackingAuthors.CreateListenerCollection(EmptyUser, this.WhenAnyValue(x => x.SelectedAuthor));
            Assignees = trackingAssignees.CreateListenerCollection(EmptyUser, this.WhenAnyValue(x => x.SelectedAssignee));

            PullRequests = new TrackingCollection<IPullRequestModel>();
            pullRequests.Comparer = OrderedComparer<IPullRequestModel>.OrderByDescending(x => x.UpdatedAt).Compare;
            pullRequests.NewerComparer = OrderedComparer<IPullRequestModel>.OrderByDescending(x => x.UpdatedAt).Compare;

            this.WhenAny(x => x.SelectedState, x => x.Value)
                .Where(x => PullRequests != null)
                .Subscribe(s => UpdateFilter(s, SelectedAssignee, SelectedAuthor));

            this.WhenAny(x => x.SelectedAssignee, x => x.Value)
                .Where(x => PullRequests != null && x != EmptyUser && IsLoaded)
                .Subscribe(a => UpdateFilter(SelectedState, a, SelectedAuthor));

            this.WhenAny(x => x.SelectedAuthor, x => x.Value)
                .Where(x => PullRequests != null && x != EmptyUser && IsLoaded)
                .Subscribe(a => UpdateFilter(SelectedState, SelectedAssignee, a));

            SelectedState = States.FirstOrDefault(x => x.Name == listSettings.SelectedState) ?? States[0];
        }
Пример #6
0
        public async Task NonExpiredIndexReturnsCacheAsync()
        {
            var expected = 5;

            var username = "******";
            var reponame = "repo";

            var cache        = new InMemoryBlobCache();
            var apiClient    = Substitute.For <IApiClient>();
            var modelService = CreateTarget(apiClient: apiClient, hostCache: cache);
            var user         = CreateOctokitUser(username);

            apiClient.GetUser().Returns(Observable.Return(user));
            apiClient.GetOrganizations().Returns(Observable.Empty <Organization>());
            var act = modelService.GetAccounts().ToEnumerable().First().First();

            var repo = Substitute.For <LocalRepositoryModel>();

            repo.Name.Returns(reponame);
            repo.CloneUrl.Returns(new UriString("https://github.com/" + username + "/" + reponame));

            var indexKey = string.Format(CultureInfo.InvariantCulture, "{0}|{1}:{2}", CacheIndex.PRPrefix, user.Login, repo.Name);

            var prcache = Enumerable.Range(1, expected)
                          .Select(id => CreatePullRequest(user, id, ItemState.Open, "Cache " + id, DateTimeOffset.UtcNow, DateTimeOffset.UtcNow));

            // seed the cache
            prcache
            .Select(item => new PullRequestCacheItem(item))
            .Select(item => item.Save <PullRequestCacheItem>(cache, indexKey).ToEnumerable().First())
            .SelectMany(item => CacheIndex.AddAndSaveToIndex(cache, indexKey, item).ToEnumerable())
            .ToList();

            var prlive = Observable.Range(1, expected)
                         .Select(id => CreatePullRequest(user, id, ItemState.Open, "Live " + id, DateTimeOffset.UtcNow, DateTimeOffset.UtcNow))
                         .DelaySubscription(TimeSpan.FromMilliseconds(10));

            apiClient.GetPullRequestsForRepository(user.Login, repo.Name).Returns(prlive);

            await modelService.InsertUser(new AccountCacheItem(user));

            ITrackingCollection <IPullRequestModel> col = new TrackingCollection <IPullRequestModel>();

            modelService.GetPullRequests(repo, col);
            col.ProcessingDelay = TimeSpan.Zero;

            col.Subscribe();
            await col.OriginalCompleted.Timeout(TimeSpan.FromMilliseconds(Timeout));;

            Assert.That(expected, Is.EqualTo(col.Count));
            //Assert.Collection(col, col.Select(x => new Action<IPullRequestModel>(t => Assert.That("Cache", StartsWith(x.Title)))).ToArray());
        }
    public void OrderByUpdatedFilter()
    {
        var count = 3;
        var col = new TrackingCollection<Thing>(
            Observable.Never<Thing>(),
            OrderedComparer<Thing>.OrderBy(x => x.UpdatedAt).Compare,
            (item, position, list) => true);
        col.ProcessingDelay = TimeSpan.Zero;

        var list1 = new List<Thing>(Enumerable.Range(1, count).Select(i => GetThing(i, i, count - i, "Run 1")).ToList());
        var list2 = new List<Thing>(Enumerable.Range(1, count).Select(i => GetThing(i, i, i + count, "Run 2")).ToList());

        var evt = new ManualResetEvent(false);
        col.Subscribe(t =>
        {
            if (++count == list1.Count)
                evt.Set();
        }, () => { });

        count = 0;
        // add first items
        foreach (var l in list1)
            col.AddItem(l);

        evt.WaitOne();
        evt.Reset();

        Assert.AreEqual(list1.Count, col.Count);
        list1.Sort(new LambdaComparer<Thing>(OrderedComparer<Thing>.OrderByDescending(x => x.CreatedAt).Compare));
        CollectionAssert.AreEqual(col, list1);

        count = 0;
        // replace items
        foreach (var l in list2)
            col.AddItem(l);

        evt.WaitOne();
        evt.Reset();

        Assert.AreEqual(list2.Count, col.Count);
        CollectionAssert.AreEqual(col, list2);

        col.Dispose();
    }
Пример #8
0
    public void ListeningTwiceWorks()
    {
        var count = 10;
        ITrackingCollection<Thing> col = new TrackingCollection<Thing>();
        col.NewerComparer = OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare;
        col.ProcessingDelay = TimeSpan.Zero;

        var list1 = new List<Thing>(Enumerable.Range(1, count).Select(i => GetThing(i, i, count - i, "Run 1")).ToList());
        var list2 = new List<Thing>(Enumerable.Range(1, count).Select(i => GetThing(i, i, i + count, "Run 2")).ToList());

        var subj = new ReplaySubject<Unit>();
        subj.OnNext(Unit.Default);
        var disp = col.OriginalCompleted.Subscribe(x => subj.OnCompleted());
        col.Listen(list1.ToObservable());
        col.Subscribe();
        subj.Wait();

        disp.Dispose();
        col.Listen(list2.ToObservable());
        subj = new ReplaySubject<Unit>();
        subj.OnNext(Unit.Default);
        disp = col.OriginalCompleted.Subscribe(x => subj.OnCompleted());
        col.Subscribe();
        subj.Wait();
        disp.Dispose();

        CollectionAssert.AreEqual(list2, col);
    }
    public async Task MultipleSortingAndFiltering()
    {
        var expectedTotal = 20;
        var rnd = new Random(214748364);

        var titles1 = Enumerable.Range(1, expectedTotal).Select(x => ((char)('a' + x)).ToString()).ToList();
        var dates1 = Enumerable.Range(1, expectedTotal).Select(x => Now + TimeSpan.FromMinutes(x)).ToList();

        var idstack1 = new Stack<int>(Enumerable.Range(1, expectedTotal).OrderBy(rnd.Next));
        var datestack1 = new Stack<DateTimeOffset>(dates1);
        var titlestack1 = new Stack<string>(titles1.OrderBy(_ => rnd.Next()));

        var titles2 = Enumerable.Range(1, expectedTotal).Select(x => ((char)('c' + x)).ToString()).ToList();
        var dates2 = Enumerable.Range(1, expectedTotal).Select(x => Now + TimeSpan.FromMinutes(x)).ToList();
        var dates2mixed = new List<DateTimeOffset>() {
                dates2[2],  dates2[0],  dates2[1],  dates2[3],  dates2[5],
                dates2[9],  dates2[15], dates2[6],  dates2[7],  dates2[8],
                dates2[13], dates2[10], dates2[16], dates2[11], dates2[12],
                dates2[14], dates2[17], dates2[18], dates2[19], dates2[4],
        };
        var idstack2 = new Stack<int>(Enumerable.Range(1, expectedTotal).OrderBy(rnd.Next));
        var datestack2 = new Stack<DateTimeOffset>(dates2mixed);
        var titlestack2 = new Stack<string>(titles2.OrderBy(_ => rnd.Next()));

        var datestack3 = new Stack<DateTimeOffset>();
        for (int i = 0; i < datestack1.Count; i++)
            datestack3.Push(new DateTimeOffset(Math.Max(dates1[i].Ticks, dates2mixed[i].Ticks), TimeSpan.Zero));

        var list1 = Observable.Defer(() => Enumerable.Range(1, expectedTotal)
            .OrderBy(rnd.Next)
            .Select(x => new Thing(idstack1.Pop(), titlestack1.Pop(), datestack1.Pop()))
            .ToObservable())
            .Replay()
            .RefCount();

        var list2 = Observable.Defer(() => Enumerable.Range(1, expectedTotal)
            .OrderBy(rnd.Next)
            .Select(x => new Thing(idstack2.Pop(), titlestack2.Pop(), datestack2.Pop()))
            .ToObservable())
            .Replay()
            .RefCount();

        ITrackingCollection<Thing> col = new TrackingCollection<Thing>(
            list1.Concat(list2),
            OrderedComparer<Thing>.OrderByDescending(x => x.CreatedAt).Compare,
            (item, idx, list) => idx < 5
        );
        col.NewerComparer = OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare;
        col.Subscribe();

        await col.OriginalCompleted;

        // it's initially sorted by date, so id list should not match
        CollectionAssert.AreNotEqual(list1.Select(x => x.Number).ToEnumerable(), list2.Select(x => x.Number).ToEnumerable());

        var sortlist = col.ToArray();
        Array.Sort(sortlist, new LambdaComparer<Thing>(OrderedComparer<Thing>.OrderByDescending(x => x.CreatedAt).Compare));
        CollectionAssert.AreEqual(sortlist.Take(5), col);

        col.Comparer = OrderedComparer<Thing>.OrderBy(x => x.Number).Compare;
        sortlist = col.ToArray();
        Array.Sort(sortlist, new LambdaComparer<Thing>(OrderedComparer<Thing>.OrderBy(x => x.Number).Compare));
        CollectionAssert.AreEqual(sortlist.Take(5), col);

        col.Comparer = OrderedComparer<Thing>.OrderBy(x => x.CreatedAt).Compare;
        sortlist = col.ToArray();
        Array.Sort(sortlist, new LambdaComparer<Thing>(OrderedComparer<Thing>.OrderBy(x => x.CreatedAt).Compare));
        CollectionAssert.AreEqual(sortlist.Take(5), col);

        col.Comparer = OrderedComparer<Thing>.OrderByDescending(x => x.Title).Compare;
        sortlist = col.ToArray();
        Array.Sort(sortlist, new LambdaComparer<Thing>(OrderedComparer<Thing>.OrderByDescending(x => x.Title).Compare));
        CollectionAssert.AreEqual(sortlist.Take(5), col);

        col.Comparer = OrderedComparer<Thing>.OrderBy(x => x.Title).Compare;
        sortlist = col.ToArray();
        Array.Sort(sortlist, new LambdaComparer<Thing>(OrderedComparer<Thing>.OrderBy(x => x.Title).Compare));
        CollectionAssert.AreEqual(sortlist.Take(5), col);

        col.Dispose();
    }
    public void ChangingSortUpdatesCollection()
    {
        var source = new Subject<Thing>();
        var col = new TrackingCollection<Thing>(
            source,
            OrderedComparer<Thing>.OrderBy(x => x.UpdatedAt).Compare,
            (item, position, list) => item.UpdatedAt < Now + TimeSpan.FromMinutes(10))
            { ProcessingDelay = TimeSpan.Zero };

        var count = 0;
        var evt = new ManualResetEvent(false);
        var list1 = new List<Thing> {
            GetThing(1, 1),
            GetThing(2, 2),
            GetThing(3, 3),
            GetThing(4, 4),
            GetThing(5, 5),
            GetThing(6, 6),
            GetThing(7, 7),
            GetThing(8, 8),
            GetThing(9, 9),
        };

        col.Subscribe(t =>
        {
            if (++count == list1.Count)
                evt.Set();
        }, () => { });


        foreach (var l in list1)
            Add(source, l);
        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(col, list1);

        col.SetComparer(OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare);

        CollectionAssert.AreEqual(col, list1.Reverse<Thing>().ToArray());
        col.Dispose();
    }
Пример #11
0
    public async void AddingBeforeSubscribingWorks()
    {
        ITrackingCollection<Thing> col = new TrackingCollection<Thing>(Observable.Empty<Thing>());
        ReplaySubject<Thing> done = new ReplaySubject<Thing>();
        col.AddItem(GetThing(1));
        col.AddItem(GetThing(2));
        var count = 0;
        done.OnNext(null);
        col.Subscribe(t =>
        {
            done.OnNext(t);
            if (++count == 2)
                done.OnCompleted();
        }, () => {});

        await Observable.Timeout(done, TimeSpan.FromMilliseconds(500));
        Assert.AreEqual(2, col.Count);
    }
    public void SortingTestWithFilterMoves()
    {
        var source = new Subject<Thing>();

        var col = new TrackingCollection<Thing>(
            source,
            OrderedComparer<Thing>.OrderBy(x => x.UpdatedAt).Compare,
            (item, position, list) => (position >= 1 && position <= 2) || (position >= 5 && position <= 7))
            { ProcessingDelay = TimeSpan.Zero };

        var count = 0;
        var expectedCount = 0;
        var evt = new ManualResetEvent(false);

        col.Subscribe(t =>
        {
            if (++count == expectedCount)
                evt.Set();
        }, () => { });

        expectedCount = 9;
        Add(source, GetThing(1, 1));
        Add(source, GetThing(2, 3));
        Add(source, GetThing(3, 5));
        Add(source, GetThing(4, 7));
        Add(source, GetThing(5, 9));
        Add(source, GetThing(6, 11));
        Add(source, GetThing(7, 13));
        Add(source, GetThing(8, 15));
        Add(source, GetThing(9, 17));
        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(col, new List<Thing> {
            GetThing(2, 3),
            GetThing(3, 5),
            GetThing(6, 11),
            GetThing(7, 13),
            GetThing(8, 5),
        });

        expectedCount = 10;
        Add(source, GetThing(7, 4));
        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(col, new List<Thing> {
            GetThing(2, 3),
            GetThing(7, 4),
            GetThing(5, 9),
            GetThing(6, 11),
            GetThing(8, 5),
        });

        expectedCount = 11;
        Add(source, GetThing(9, 2));
        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(col, new List<Thing> {
            GetThing(9, 2),
            GetThing(2, 3),
            GetThing(4, 7),
            GetThing(5, 9),
            GetThing(6, 11),
        });

        col.Dispose();
    }
    public void OnlyTimesEqualOrHigherThan3Minutes()
    {
        var count = 6;

        var list1 = new List<Thing>(Enumerable.Range(1, count).Select(i => GetThing(i, i, count - i, "Run 1")).ToList());

        var col = new TrackingCollection<Thing>(
            Observable.Never<Thing>(),
            OrderedComparer<Thing>.OrderBy(x => x.UpdatedAt).Compare,
            (item, position, list) => item.UpdatedAt >= Now + TimeSpan.FromMinutes(3) && item.UpdatedAt <= Now + TimeSpan.FromMinutes(5));
        col.ProcessingDelay = TimeSpan.Zero;

        var evt = new ManualResetEvent(false);
        col.Subscribe(t =>
        {
            if (++count == list1.Count)
                evt.Set();
        }, () => { });

        count = 0;
        // add first items
        foreach (var l in list1)
            col.AddItem(l);

        evt.WaitOne();
        evt.Reset();

        Assert.AreEqual(3, col.Count);

#if DEBUG
        CollectionAssert.AreEqual(list1.Reverse<Thing>(), col.DebugInternalList);
#endif
        CollectionAssert.AreEqual(col, new List<Thing>() { list1[2], list1[1], list1[0] });
        col.Dispose();
    }
Пример #14
0
 TrackingCollection<Thing> CreateSource()
 {
     var result = new TrackingCollection<Thing>(Observable.Empty<Thing>());
     result.Subscribe();
     result.AddItem(new Thing(1, "item1", DateTimeOffset.MinValue));
     result.AddItem(new Thing(2, "item2", DateTimeOffset.MinValue));
     result.AddItem(new Thing(3, "item3", DateTimeOffset.MinValue));
     return result;
 }
Пример #15
0
        public void CopyFromDoesNotLoseAvatar()
        {
            var userImage = AvatarProvider.CreateBitmapImage("pack://application:,,,/GitHub.App;component/Images/default_user_avatar.png");
            var orgImage = AvatarProvider.CreateBitmapImage("pack://application:,,,/GitHub.App;component/Images/default_org_avatar.png");

            var initialBitmapImageSubject = new Subject<BitmapImage>();

            var collectionEvent = new ManualResetEvent(false);
            var avatarPropertyEvent = new ManualResetEvent(false);

            //Creating an initial account with an observable that returns immediately
            const string login = "******";
            const int initialOwnedPrivateRepositoryCount = 1;

            var initialAccount = new Account(login, true, false, initialOwnedPrivateRepositoryCount, 0, initialBitmapImageSubject);

            //Creating the test collection
            var col = new TrackingCollection<IAccount>(Observable.Empty<IAccount>(), OrderedComparer<IAccount>.OrderByDescending(x => x.Login).Compare);
            col.Subscribe(account =>
            {
                collectionEvent.Set();
            }, () => { });

            //Adding that account to the TrackingCollection
            col.AddItem(initialAccount);

            //Waiting for the collection add the item
            collectionEvent.WaitOne();
            collectionEvent.Reset();

            //Checking some initial properties
            Assert.Equal(login, col[0].Login);
            Assert.Equal(initialOwnedPrivateRepositoryCount, col[0].OwnedPrivateRepos);

            //Demonstrating that the avatar is not yet present
            Assert.Null(col[0].Avatar);

            //Adding a listener to check for the changing of the Avatar property
            initialAccount.Changed.Subscribe(args =>
            {
                if (args.PropertyName == "Avatar")
                {
                    avatarPropertyEvent.Set();
                }
            });

            //Providing the first avatar
            initialBitmapImageSubject.OnNext(userImage);
            initialBitmapImageSubject.OnCompleted();

            //Waiting for the avatar to be added
            avatarPropertyEvent.WaitOne();
            avatarPropertyEvent.Reset();

            //Demonstrating that the avatar is present
            Assert.NotNull(col[0].Avatar);
            Assert.True(BitmapSourcesAreEqual(col[0].Avatar, userImage));
            Assert.False(BitmapSourcesAreEqual(col[0].Avatar, orgImage));

            //Creating an account update
            const int updatedOwnedPrivateRepositoryCount = 2;
            var updatedBitmapImageSubject = new Subject<BitmapImage>();
            var updatedAccount = new Account(login, true, false, updatedOwnedPrivateRepositoryCount, 0, updatedBitmapImageSubject);

            //Updating the account in the collection
            col.AddItem(updatedAccount);

            //Waiting for the collection to process the update
            collectionEvent.WaitOne();
            collectionEvent.Reset();

            //Providing the second avatar
            updatedBitmapImageSubject.OnNext(orgImage);
            updatedBitmapImageSubject.OnCompleted();

            //Waiting for the delayed bitmap image observable
            avatarPropertyEvent.WaitOne();
            avatarPropertyEvent.Reset();

            //Login is the id, so that should be the same
            Assert.Equal(login, col[0].Login);

            //CopyFrom() should have updated this field
            Assert.Equal(updatedOwnedPrivateRepositoryCount, col[0].OwnedPrivateRepos);

            //CopyFrom() should not cause a race condition here
            Assert.NotNull(col[0].Avatar);
            Assert.True(BitmapSourcesAreEqual(col[0].Avatar, orgImage));
            Assert.False(BitmapSourcesAreEqual(col[0].Avatar, userImage));
        }
Пример #16
0
        void Run2()
        {
            var count = 10;
            var col = new TrackingCollection<Thing>();
            col.ProcessingDelay = TimeSpan.FromMilliseconds(20);

            col.NewerComparer = OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare;
            list.ItemsSource = col;

            var source = Observable.Merge(
                Observable.Generate(0, i => i < count, i => i + 1, i => i, i => TimeSpan.FromMilliseconds(5))
                    .Select(i => GetThing(i, i, i, "Run 1")),
                Observable.Generate(0, i => i < count, i => i + 1, i => i, i => TimeSpan.FromMilliseconds(7))
                    .Select(i => GetThing(i, i, i + 1, "Run 2"))
            );

            col.Listen(source);
            col.Subscribe();
        }
Пример #17
0
        public PullRequestListViewModel(
            IModelServiceFactory modelServiceFactory,
            IPackageSettings settings,
            IPullRequestSessionManager sessionManager,
            IVisualStudioBrowser visualStudioBrowser)
        {
            Guard.ArgumentNotNull(modelServiceFactory, nameof(modelServiceFactory));
            Guard.ArgumentNotNull(settings, nameof(settings));
            Guard.ArgumentNotNull(sessionManager, nameof(sessionManager));
            Guard.ArgumentNotNull(visualStudioBrowser, nameof(visualStudioBrowser));

            constructing             = true;
            this.modelServiceFactory = modelServiceFactory;
            this.settings            = settings;
            this.visualStudioBrowser = visualStudioBrowser;

            Title = Resources.PullRequestsNavigationItemText;

            States = new List <PullRequestState> {
                new PullRequestState {
                    IsOpen = true, Name = "Open"
                },
                new PullRequestState {
                    IsOpen = false, Name = "Closed"
                },
                new PullRequestState {
                    Name = "All"
                }
            };

            trackingAuthors = new TrackingCollection <IAccount>(Observable.Empty <IAccount>(),
                                                                OrderedComparer <IAccount> .OrderByDescending(x => x.Login).Compare);
            trackingAssignees = new TrackingCollection <IAccount>(Observable.Empty <IAccount>(),
                                                                  OrderedComparer <IAccount> .OrderByDescending(x => x.Login).Compare);
            trackingAuthors.Subscribe();
            trackingAssignees.Subscribe();

            Authors   = trackingAuthors.CreateListenerCollection(EmptyUser, this.WhenAnyValue(x => x.SelectedAuthor));
            Assignees = trackingAssignees.CreateListenerCollection(EmptyUser, this.WhenAnyValue(x => x.SelectedAssignee));

            CreatePullRequests();

            this.WhenAny(x => x.SelectedState, x => x.Value)
            .Where(x => PullRequests != null)
            .Subscribe(s => UpdateFilter(s, SelectedAssignee, SelectedAuthor, SearchQuery));

            this.WhenAny(x => x.SelectedAssignee, x => x.Value)
            .Where(x => PullRequests != null && x != EmptyUser)
            .Subscribe(a => UpdateFilter(SelectedState, a, SelectedAuthor, SearchQuery));

            this.WhenAny(x => x.SelectedAuthor, x => x.Value)
            .Where(x => PullRequests != null && x != EmptyUser)
            .Subscribe(a => UpdateFilter(SelectedState, SelectedAssignee, a, SearchQuery));

            this.WhenAny(x => x.SearchQuery, x => x.Value)
            .Where(x => PullRequests != null)
            .Subscribe(f => UpdateFilter(SelectedState, SelectedAssignee, SelectedAuthor, f));

            this.WhenAnyValue(x => x.SelectedRepository)
            .Skip(1)
            .Subscribe(_ => ResetAndLoad());

            OpenPullRequest = ReactiveCommand.Create();
            OpenPullRequest.Subscribe(DoOpenPullRequest);
            CreatePullRequest = ReactiveCommand.Create();
            CreatePullRequest.Subscribe(_ => DoCreatePullRequest());

            OpenPullRequestOnGitHub = ReactiveCommand.Create();
            OpenPullRequestOnGitHub.Subscribe(x => DoOpenPullRequestOnGitHub((int)x));

            // Get the current pull request session and the selected repository. When the session's
            // repository is the same as our selected repository set CheckedOutPullRequest to the
            // current session's model, so that the checked out PR can be highlighted.
            Observable.CombineLatest(
                sessionManager.WhenAnyValue(x => x.CurrentSession),
                this.WhenAnyValue(x => x.SelectedRepository),
                (s, r) => new { Session = s, Repository = r })
            .Subscribe(x =>
            {
                CheckedOutPullRequest = x.Session?.RepositoryOwner == x.Repository?.Owner ?
                                        x.Session?.PullRequest : null;
            });

            constructing = false;
        }
Пример #18
0
    public void RemovingFirstItemWithFilterWorks()
    {
        var source = new Subject<Thing>();

        ITrackingCollection<Thing> col = new TrackingCollection<Thing>(
            Observable.Range(0, 5).Select(x => GetThing(x, x)),
            OrderedComparer<Thing>.OrderBy(x => x.UpdatedAt).Compare,
            (item, position, list) => true);
        col.ProcessingDelay = TimeSpan.Zero;

        var count = 0;
        var expectedCount = 5;
        var evt = new ManualResetEvent(false);
        col.Subscribe(t =>
        {
            if (++count == expectedCount)
                evt.Set();
        }, () => { });

        Assert.True(evt.WaitOne(40));
        evt.Reset();

        expectedCount = 6;
        col.RemoveItem(GetThing(0));

        Assert.True(evt.WaitOne(40));
        evt.Reset();

        CollectionAssert.AreEqual(col, Enumerable.Range(1, 4).Select(x => GetThing(x, x)));

        col.Dispose();

    }
Пример #19
0
    public void ChangingSortingAndUpdatingItemsUpdatesSortCorrectly()
    {
        var source = new Subject<Thing>();

        ITrackingCollection<Thing> col = new TrackingCollection<Thing>(
            source);
        col.Comparer = OrderedComparer<Thing>.OrderBy(x => x.UpdatedAt).Compare;
        col.NewerComparer = OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare;
        col.Filter = (item, position, list) =>
            position == 2 || position == 3 || position == 5 || position == 7;
        col.ProcessingDelay = TimeSpan.Zero;

        var count = 0;
        var expectedCount = 0;
        var evt = new ManualResetEvent(false);

        col.Subscribe(t =>
        {
            if (++count == expectedCount)
                evt.Set();
        }, () => { });

        expectedCount = 9;
        Enumerable.Range(0, expectedCount)
            .Select(x => GetThing(x, x))
            .ForEach(x => Add(source, x));

        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(new List<Thing> {
            GetThing(2, 2),
            GetThing(3, 3),
            GetThing(5, 5),
            GetThing(7, 7),
        }, col);

        expectedCount = 10;
        Add(source, GetThing(3, 3, 2));
        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(new List<Thing> {
            GetThing(2, 2),
            GetThing(3, 3),
            GetThing(5, 5),
            GetThing(7, 7),
        }, col);

        expectedCount = 11;
        Add(source, GetThing(3, 3, 4));
        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(new List<Thing> {
            GetThing(2, 2),
            GetThing(3, 3, 4),
            GetThing(5, 5),
            GetThing(7, 7),
        }, col);

        expectedCount = 12;
        Add(source, GetThing(3, 3, 6));
        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(new List<Thing> {
            GetThing(2, 2),
            GetThing(4, 4),
            GetThing(3, 3, 6),
            GetThing(7, 7),
        }, col);

        col.Comparer = OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare;
        CollectionAssert.AreEqual(new List<Thing> {
            GetThing(3, 3, 6),
            GetThing(6, 6),
            GetThing(4, 4),
            GetThing(1, 1),
        }, col);

        expectedCount = 13;
        Add(source, GetThing(4, 4));
        evt.WaitOne();
        evt.Reset();

        CollectionAssert.AreEqual(new List<Thing> {
            GetThing(3, 3, 6),
            GetThing(6, 6),
            GetThing(4, 4),
            GetThing(1, 1),
        }, col);

        expectedCount = 14;
        Add(source, GetThing(4, 4, 6));
        evt.WaitOne();
        evt.Reset();

        CollectionAssert.AreEqual(new List<Thing> {
            GetThing(3, 3, 6),
            GetThing(6, 6),
            GetThing(5, 5),
            GetThing(1, 1),
        }, col);

        expectedCount = 15;
        Add(source, GetThing(5, 5, 6));
        evt.WaitOne();
        evt.Reset();

        CollectionAssert.AreEqual(new List<Thing> {
            GetThing(3, 3, 6),
            GetThing(6, 6),
            GetThing(5, 5, 6),
            GetThing(1, 1),
        }, col);

        col.Dispose();
    }
Пример #20
0
    public void DoesUpdateThingIfTimeIsNewer()
    {
        ITrackingCollection<Thing> col = new TrackingCollection<Thing>(
            Observable.Never<Thing>(),
            OrderedComparer<Thing>.OrderBy(x => x.UpdatedAt).Compare);
        col.NewerComparer = OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare;
        col.ProcessingDelay = TimeSpan.Zero;

        var evt = new ManualResetEvent(false);
        col.Subscribe(t =>
        {
            evt.Set();
        }, () => { });

        var createdAndUpdatedTime = DateTimeOffset.Now;
        var newerUpdateTime = createdAndUpdatedTime.Add(TimeSpan.FromMinutes(1));

        const string originalTitle = "Original Thing";

        var originalThing = new Thing(1, originalTitle, createdAndUpdatedTime, createdAndUpdatedTime);
        col.AddItem(originalThing);

        evt.WaitOne();
        evt.Reset();

        Assert.AreEqual(originalTitle, col[0].Title);

        const string updatedTitle = "Updated Thing";

        var updatedThing = new Thing(1, updatedTitle, createdAndUpdatedTime, newerUpdateTime);
        col.AddItem(updatedThing);

        evt.WaitOne();
        evt.Reset();

        Assert.AreEqual(updatedTitle, col[0].Title);

        col.Dispose();
    }
Пример #21
0
    public void OrderByDoesntMatchOriginalOrderTimings()
    {
        var count = 0;
        var total = 1000;

        var list1 = new List<Thing>(Enumerable.Range(1, total).Select(i => GetThing(i, i, i, "Run 1")).ToList());
        var list2 = new List<Thing>(Enumerable.Range(1, total).Select(i => GetThing(i, i, i, "Run 2")).ToList());

        ITrackingCollection<Thing> col = new TrackingCollection<Thing>(
            list1.ToObservable(),
            OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare,
            (item, position, list) => item.Title.Equals("Run 2"));
        col.NewerComparer = OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare;
        col.ProcessingDelay = TimeSpan.Zero;

        var evt = new ManualResetEvent(false);
        var start = DateTimeOffset.UtcNow;

        col.Subscribe(t =>
        {
            if (++count == list1.Count)
                evt.Set();
        }, () => { });

        evt.WaitOne();
        var time = (DateTimeOffset.UtcNow - start).TotalMilliseconds;
        Assert.LessOrEqual(time, 100);
        evt.Reset();

        Assert.AreEqual(total, count);
        Assert.AreEqual(0, col.Count);

        count = 0;

        start = DateTimeOffset.UtcNow;
        // add new items
        foreach (var l in list2)
            col.AddItem(l);

        evt.WaitOne();
        time = (DateTimeOffset.UtcNow - start).TotalMilliseconds;
        Assert.LessOrEqual(time, 200);
        evt.Reset();

        Assert.AreEqual(total, count);
        Assert.AreEqual(total, col.Count);
        CollectionAssert.AreEqual(col, list2.Reverse<Thing>());

        col.Dispose();
    }
    public void ChangingComparers()
    {
        var source = new Subject<Thing>();

        var col = new TrackingCollection<Thing>(source, OrderedComparer<Thing>.OrderBy(x => x.CreatedAt).Compare) { ProcessingDelay = TimeSpan.Zero };

        var count = 0;
        var evt = new ManualResetEvent(false);
        var list1 = new List<Thing> {
            GetThing(1, 1, 9),
            GetThing(2, 2, 8),
            GetThing(3, 3, 7),
            GetThing(4, 4, 6),
            GetThing(5, 5, 5),
            GetThing(6, 6, 4),
            GetThing(7, 7, 3),
            GetThing(8, 8, 2),
            GetThing(9, 9, 1),
        };

        col.Subscribe(t =>
        {
            if (++count == list1.Count)
                evt.Set();
        }, () => { });

        foreach (var l in list1)
            Add(source, l);

        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(col, list1);
        col.SetComparer(null);
        CollectionAssert.AreEqual(col, list1.Reverse<Thing>().ToArray());
        col.Dispose();
    }
Пример #23
0
        public void CopyFromDoesNotLoseAvatar()
        {
            var userImage = AvatarProvider.CreateBitmapImage("pack://application:,,,/GitHub.App;component/Images/default_user_avatar.png");
            var orgImage  = AvatarProvider.CreateBitmapImage("pack://application:,,,/GitHub.App;component/Images/default_org_avatar.png");

            var initialBitmapImageSubject = new Subject <BitmapImage>();

            var collectionEvent     = new ManualResetEvent(false);
            var avatarPropertyEvent = new ManualResetEvent(false);

            //Creating an initial account with an observable that returns immediately
            const string login = "******";
            const int    initialOwnedPrivateRepositoryCount = 1;

            var initialAccount = new Account(login, true, false, initialOwnedPrivateRepositoryCount, 0, initialBitmapImageSubject);

            //Creating the test collection
            var col = new TrackingCollection <IAccount>(Observable.Empty <IAccount>(), OrderedComparer <IAccount> .OrderByDescending(x => x.Login).Compare);

            col.Subscribe(account =>
            {
                collectionEvent.Set();
            }, () => { });

            //Adding that account to the TrackingCollection
            col.AddItem(initialAccount);

            //Waiting for the collection add the item
            collectionEvent.WaitOne();
            collectionEvent.Reset();

            //Checking some initial properties
            Assert.That(login, Is.EqualTo(col[0].Login));
            Assert.That(initialOwnedPrivateRepositoryCount, Is.EqualTo(col[0].OwnedPrivateRepos));

            //Demonstrating that the avatar is not yet present
            Assert.That(col[0].Avatar, Is.Null);

            //Adding a listener to check for the changing of the Avatar property
            initialAccount.Changed.Subscribe(args =>
            {
                if (args.PropertyName == "Avatar")
                {
                    avatarPropertyEvent.Set();
                }
            });

            //Providing the first avatar
            initialBitmapImageSubject.OnNext(userImage);
            initialBitmapImageSubject.OnCompleted();

            //Waiting for the avatar to be added
            avatarPropertyEvent.WaitOne();
            avatarPropertyEvent.Reset();

            //Demonstrating that the avatar is present
            Assert.That(col[0].Avatar, Is.Not.Null);
            Assert.True(BitmapSourcesAreEqual(col[0].Avatar, userImage));
            Assert.False(BitmapSourcesAreEqual(col[0].Avatar, orgImage));

            //Creating an account update
            const int updatedOwnedPrivateRepositoryCount = 2;
            var       updatedBitmapImageSubject          = new Subject <BitmapImage>();
            var       updatedAccount = new Account(login, true, false, updatedOwnedPrivateRepositoryCount, 0, updatedBitmapImageSubject);

            //Updating the account in the collection
            col.AddItem(updatedAccount);

            //Waiting for the collection to process the update
            collectionEvent.WaitOne();
            collectionEvent.Reset();

            //Providing the second avatar
            updatedBitmapImageSubject.OnNext(orgImage);
            updatedBitmapImageSubject.OnCompleted();

            //Waiting for the delayed bitmap image observable
            avatarPropertyEvent.WaitOne();
            avatarPropertyEvent.Reset();

            //Login is the id, so that should be the same
            Assert.That(login, Is.EqualTo(col[0].Login));

            //CopyFrom() should have updated this field
            Assert.That(updatedOwnedPrivateRepositoryCount, Is.EqualTo(col[0].OwnedPrivateRepos));

            //CopyFrom() should not cause a race condition here
            Assert.That(col[0].Avatar, Is.Not.Null);
            Assert.True(BitmapSourcesAreEqual(col[0].Avatar, orgImage));
            Assert.False(BitmapSourcesAreEqual(col[0].Avatar, userImage));
        }
 public void DisposingThrows()
 {
     var col = new TrackingCollection<Thing>(Observable.Empty<Thing>());
     col.Dispose();
     Assert.Throws<ObjectDisposedException>(() => col.SetFilter(null));
     Assert.Throws<ObjectDisposedException>(() => col.SetComparer(null));
     Assert.Throws<ObjectDisposedException>(() => col.Subscribe());
     Assert.Throws<ObjectDisposedException>(() => col.AddItem(GetThing(1)));
     Assert.Throws<ObjectDisposedException>(() => col.RemoveItem(GetThing(1)));
 }
    public void ChangingItemContentRemovesItFromFilteredList2()
    {
        var source = new Subject<Thing>();

        var now = new DateTimeOffset(0, TimeSpan.FromTicks(0));
        var col = new TrackingCollection<Thing>(
            source,
            OrderedComparer<Thing>.OrderBy(x => x.CreatedAt).Compare,
            (item, position, list) => item.UpdatedAt > now + TimeSpan.FromMinutes(2) && item.UpdatedAt < now + TimeSpan.FromMinutes(8))
            { ProcessingDelay = TimeSpan.Zero };

        var count = 0;
        var expectedCount = 0;
        var evt = new ManualResetEvent(false);

        col.Subscribe(t =>
        {
            if (++count == expectedCount)
                evt.Set();
        }, () => { });

        expectedCount = 5;
        Add(source, GetThing(1, 1, 1));
        Add(source, GetThing(3, 3, 3));
        Add(source, GetThing(5, 5, 5));
        Add(source, GetThing(7, 7, 7));
        Add(source, GetThing(9, 9, 9));
        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(col, new List<Thing> {
            GetThing(3, 3, 3),
            GetThing(5, 5, 5),
            GetThing(7, 7, 7),
        });

        expectedCount = 6;
        Add(source, GetThing(7, 7, 8));
        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(col, new List<Thing> {
            GetThing(3, 3, 3),
            GetThing(5, 5, 5),
        });

        expectedCount = 7;
        Add(source, GetThing(7, 7, 7));
        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(col, new List<Thing> {
            GetThing(3, 3, 3),
            GetThing(5, 5, 5),
            GetThing(7, 7, 7),
        });

        expectedCount = 8;
        Add(source, GetThing(3, 3, 2));
        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(col, new List<Thing> {
            GetThing(5, 5, 5),
            GetThing(7, 7, 7),
        });

        expectedCount = 9;
        Add(source, GetThing(3, 3, 3));
        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(col, new List<Thing> {
            GetThing(3, 3, 3),
            GetThing(5, 5, 5),
            GetThing(7, 7, 7),
        });

        expectedCount = 10;
        Add(source, GetThing(5, 5, 1));
        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(col, new List<Thing> {
            GetThing(3, 3, 3),
            GetThing(7, 7, 7),
        });
        col.Dispose();
    }
    public void OrderByDescendingNoFilter()
    {
        var count = 6;

        var list1 = new List<Thing>(Enumerable.Range(1, count).Select(i => GetThing(i, i, count - i, "Run 1")).ToList());
        var list2 = new List<Thing>(Enumerable.Range(1, count).Select(i => GetThing(i, i, i, "Run 2")).ToList());

        var col = new TrackingCollection<Thing>(
            Observable.Never<Thing>(),
            OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare);
        col.ProcessingDelay = TimeSpan.Zero;

        var evt = new ManualResetEvent(false);
        col.Subscribe(t =>
        {
            if (++count == list1.Count)
                evt.Set();
        }, () => { });

        count = 0;
        // add first items
        foreach (var l in list1)
            col.AddItem(l);

        evt.WaitOne();
        evt.Reset();

        Assert.AreEqual(6, col.Count);
#if DEBUG
        CollectionAssert.AreEqual(list1, col.DebugInternalList);
#endif
        CollectionAssert.AreEqual(col, list1);

        count = 0;
        // add first items
        foreach (var l in list2)
            col.AddItem(l);

        evt.WaitOne();
        evt.Reset();

        Assert.AreEqual(6, col.Count);

        col.Dispose();
    }
    public void ChangingFilterUpdatesCollection()
    {
        var source = new Subject<Thing>();
        var col = new TrackingCollection<Thing>(
            source,
            OrderedComparer<Thing>.OrderBy(x => x.UpdatedAt).Compare,
            (item, position, list) => item.UpdatedAt < Now + TimeSpan.FromMinutes(10))
            { ProcessingDelay = TimeSpan.Zero };


        var count = 0;
        var expectedCount = 0;
        var evt = new ManualResetEvent(false);

        col.Subscribe(t =>
        {
            if (++count == expectedCount)
                evt.Set();
        }, () => { });

        expectedCount = 9;
        Add(source, GetThing(1, 1));
        Add(source, GetThing(2, 2));
        Add(source, GetThing(3, 3));
        Add(source, GetThing(4, 4));
        Add(source, GetThing(5, 5));
        Add(source, GetThing(6, 6));
        Add(source, GetThing(7, 7));
        Add(source, GetThing(8, 8));
        Add(source, GetThing(9, 9));
        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(col, new List<Thing> {
            GetThing(1, 1),
            GetThing(2, 2),
            GetThing(3, 3),
            GetThing(4, 4),
            GetThing(5, 5),
            GetThing(6, 6),
            GetThing(7, 7),
            GetThing(8, 8),
            GetThing(9, 9),
        });

        col.SetFilter((item, position, list) => item.UpdatedAt < Now + TimeSpan.FromMinutes(8));

        CollectionAssert.AreEqual(col, new List<Thing> {
            GetThing(1, 1),
            GetThing(2, 2),
            GetThing(3, 3),
            GetThing(4, 4),
            GetThing(5, 5),
            GetThing(6, 6),
            GetThing(7, 7),
        });
        col.Dispose();
    }
 public void NotInitializedCorrectlyThrows2()
 {
     var col = new TrackingCollection<Thing>(OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare);
     Assert.Throws<InvalidOperationException>(() => col.Subscribe(_ => { }, () => { }));
 }
    public void RemovingItemsFromCollectionManuallyThrows2()
    {
        var source = new Subject<Thing>();
        var col = new TrackingCollection<Thing>(source) { ProcessingDelay = TimeSpan.Zero };
        var count = 0;
        var expectedCount = 2;
        var evt = new ManualResetEvent(false);

        col.Subscribe(t =>
        {
            if (++count == expectedCount)
                evt.Set();
        }, () => { });

        Add(source, GetThing(1, 1));
        Add(source, GetThing(2, 2));
        evt.WaitOne();
        evt.Reset();
        Assert.Throws<InvalidOperationException>(() => col.RemoveAt(0));
        col.Dispose();
    }
Пример #30
0
    public async Task MultipleSortingAndFiltering()
    {
        var expectedTotal = 20;
        var rnd = new Random(214748364);

        var updatedAtMinutesStack = new Stack<int>(Enumerable.Range(1, expectedTotal).OrderBy(rnd.Next));

        var list1 = Observable.Defer(() => Enumerable.Range(1, expectedTotal)
            .OrderBy(rnd.Next)
            .Select(x => GetThing(x, x, x, ((char)('a' + x)).ToString()))
            .ToObservable())
            .Replay()
            .RefCount();

        var list2 = Observable.Defer(() => Enumerable.Range(1, expectedTotal)
            .OrderBy(rnd.Next)
            .Select(x => GetThing(x, x, updatedAtMinutesStack.Pop(), ((char)('c' + x)).ToString()))
            .ToObservable())
            .Replay()
            .RefCount();

        ITrackingCollection<Thing> col = new TrackingCollection<Thing>(
            list1.Concat(list2),
            OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare,
            (item, idx, list) => idx < 5
        );
        col.NewerComparer = OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare;
        col.Subscribe();

        await col.OriginalCompleted;

        // it's initially sorted by date, so id list should not match
        CollectionAssert.AreNotEqual(list1.Select(x => x.Number).ToEnumerable(), list2.Select(x => x.Number).ToEnumerable());

        var sortlist = col.ToArray();
        Array.Sort(sortlist, new LambdaComparer<Thing>(OrderedComparer<Thing>
            .OrderByDescending(x => x.UpdatedAt)
            .ThenByDescending(x => x.CreatedAt).Compare));
        CollectionAssert.AreEqual(sortlist.Take(5), col);

        col.Comparer = OrderedComparer<Thing>.OrderBy(x => x.Number).Compare;
        sortlist = col.ToArray();
        Array.Sort(sortlist, new LambdaComparer<Thing>(OrderedComparer<Thing>.OrderBy(x => x.Number).Compare));
        CollectionAssert.AreEqual(sortlist.Take(5), col);

        col.Comparer = OrderedComparer<Thing>.OrderBy(x => x.UpdatedAt).Compare;
        sortlist = col.ToArray();
        Array.Sort(sortlist, new LambdaComparer<Thing>(OrderedComparer<Thing>
            .OrderBy(x => x.UpdatedAt)
            .ThenBy(x => x.CreatedAt).Compare));
        CollectionAssert.AreEqual(sortlist.Take(5), col);

        col.Comparer = OrderedComparer<Thing>.OrderByDescending(x => x.Title).Compare;
        sortlist = col.ToArray();
        Array.Sort(sortlist, new LambdaComparer<Thing>(OrderedComparer<Thing>.OrderByDescending(x => x.Title).Compare));
        CollectionAssert.AreEqual(sortlist.Take(5), col);

        col.Comparer = OrderedComparer<Thing>.OrderBy(x => x.Title).Compare;
        sortlist = col.ToArray();
        Array.Sort(sortlist, new LambdaComparer<Thing>(OrderedComparer<Thing>.OrderBy(x => x.Title).Compare));
        CollectionAssert.AreEqual(sortlist.Take(5), col);

        col.Dispose();
    }
    public void Removing()
    {
        var source = new Subject<Thing>();

        var col = new TrackingCollection<Thing>(
            source,
            OrderedComparer<Thing>.OrderBy(x => x.UpdatedAt).Compare,
            (item, position, list) => (position > 2 && position < 5) || (position > 6 && position < 8))
            { ProcessingDelay = TimeSpan.Zero };

        var count = 0;
        var expectedCount = 0;
        var evt = new ManualResetEvent(false);

        col.Subscribe(t =>
        {
            if (++count == expectedCount)
                evt.Set();
        }, () => { });

        expectedCount = 11;
        Add(source, GetThing(0, 0));
        Add(source, GetThing(1, 1));
        Add(source, GetThing(2, 2));
        Add(source, GetThing(3, 3));
        Add(source, GetThing(4, 4));
        Add(source, GetThing(5, 5));
        Add(source, GetThing(6, 6));
        Add(source, GetThing(7, 7));
        Add(source, GetThing(8, 8));
        Add(source, GetThing(9, 9));
        Add(source, GetThing(10, 10));
        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(col, new List<Thing> {
            GetThing(3, 3),
            GetThing(4, 4),
            GetThing(7, 7),
        });

        expectedCount = 12;
        col.RemoveItem(GetThing(2));
        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(col, new List<Thing> {
            GetThing(4, 4),
            GetThing(5, 5),
            GetThing(8, 8),
        });

        expectedCount = 13;
        col.RemoveItem(GetThing(5));
        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(col, new List<Thing> {
            GetThing(4, 4),
            GetThing(6, 6),
            GetThing(9, 9),
        });

        col.SetFilter(null);

        expectedCount = 14;
        col.RemoveItem(GetThing(100)); // this one won't result in a new element from the observable
        col.RemoveItem(GetThing(10));
        evt.WaitOne();
        evt.Reset();

        Assert.AreEqual(8, col.Count);
        CollectionAssert.AreEqual(col, new List<Thing> {
            GetThing(0, 0),
            GetThing(1, 1),
            GetThing(3, 3),
            GetThing(4, 4),
            GetThing(6, 6),
            GetThing(7, 7),
            GetThing(8, 8),
            GetThing(9, 9),
        });
        col.Dispose();
    }
        public PullRequestListViewModel(
            IModelServiceFactory modelServiceFactory,
            IPackageSettings settings,
            IVisualStudioBrowser visualStudioBrowser)
        {
            Guard.ArgumentNotNull(modelServiceFactory, nameof(modelServiceFactory));
            Guard.ArgumentNotNull(settings, nameof(settings));
            Guard.ArgumentNotNull(visualStudioBrowser, nameof(visualStudioBrowser));

            constructing             = true;
            this.modelServiceFactory = modelServiceFactory;
            this.settings            = settings;
            this.visualStudioBrowser = visualStudioBrowser;

            Title = Resources.PullRequestsNavigationItemText;

            States = new List <PullRequestState> {
                new PullRequestState {
                    IsOpen = true, Name = "Open"
                },
                new PullRequestState {
                    IsOpen = false, Name = "Closed"
                },
                new PullRequestState {
                    Name = "All"
                }
            };

            trackingAuthors = new TrackingCollection <IAccount>(Observable.Empty <IAccount>(),
                                                                OrderedComparer <IAccount> .OrderByDescending(x => x.Login).Compare);
            trackingAssignees = new TrackingCollection <IAccount>(Observable.Empty <IAccount>(),
                                                                  OrderedComparer <IAccount> .OrderByDescending(x => x.Login).Compare);
            trackingAuthors.Subscribe();
            trackingAssignees.Subscribe();

            Authors   = trackingAuthors.CreateListenerCollection(EmptyUser, this.WhenAnyValue(x => x.SelectedAuthor));
            Assignees = trackingAssignees.CreateListenerCollection(EmptyUser, this.WhenAnyValue(x => x.SelectedAssignee));

            CreatePullRequests();

            this.WhenAny(x => x.SelectedState, x => x.Value)
            .Where(x => PullRequests != null)
            .Subscribe(s => UpdateFilter(s, SelectedAssignee, SelectedAuthor, SearchQuery));

            this.WhenAny(x => x.SelectedAssignee, x => x.Value)
            .Where(x => PullRequests != null && x != EmptyUser)
            .Subscribe(a => UpdateFilter(SelectedState, a, SelectedAuthor, SearchQuery));

            this.WhenAny(x => x.SelectedAuthor, x => x.Value)
            .Where(x => PullRequests != null && x != EmptyUser)
            .Subscribe(a => UpdateFilter(SelectedState, SelectedAssignee, a, SearchQuery));

            this.WhenAny(x => x.SearchQuery, x => x.Value)
            .Where(x => PullRequests != null)
            .Subscribe(f => UpdateFilter(SelectedState, SelectedAssignee, SelectedAuthor, f));

            this.WhenAnyValue(x => x.SelectedRepository)
            .Skip(1)
            .Subscribe(_ => ResetAndLoad());

            OpenPullRequest = ReactiveCommand.Create();
            OpenPullRequest.Subscribe(DoOpenPullRequest);
            CreatePullRequest = ReactiveCommand.Create();
            CreatePullRequest.Subscribe(_ => DoCreatePullRequest());

            OpenPullRequestOnGitHub = ReactiveCommand.Create();
            OpenPullRequestOnGitHub.Subscribe(x => DoOpenPullRequestOnGitHub((int)x));

            constructing = false;
        }
    public void MultipleSortingAndFiltering()
    {
        var expectedTotal = 20;
        var rnd = new Random(214748364);

        var titles1 = Enumerable.Range(1, expectedTotal).Select(x => ((char)('a' + x)).ToString()).ToList();
        var dates1 = Enumerable.Range(1, expectedTotal).Select(x => Now + TimeSpan.FromMinutes(x)).ToList();

        var idstack1 = new Stack<int>(Enumerable.Range(1, expectedTotal).OrderBy(rnd.Next));
        var datestack1 = new Stack<DateTimeOffset>(dates1);
        var titlestack1 = new Stack<string>(titles1.OrderBy(_ => rnd.Next()));

        var titles2 = Enumerable.Range(1, expectedTotal).Select(x => ((char)('c' + x)).ToString()).ToList();
        var dates2 = Enumerable.Range(1, expectedTotal).Select(x => Now + TimeSpan.FromMinutes(x)).ToList();

        var idstack2 = new Stack<int>(Enumerable.Range(1, expectedTotal).OrderBy(rnd.Next));
        var datestack2 = new Stack<DateTimeOffset>(new List<DateTimeOffset>() {
                dates2[2],  dates2[0],  dates2[1],  dates2[3],  dates2[5],
                dates2[9],  dates2[15], dates2[6],  dates2[7],  dates2[8],
                dates2[13], dates2[10], dates2[16], dates2[11], dates2[12],
                dates2[14], dates2[17], dates2[18], dates2[19], dates2[4],
        });
        var titlestack2 = new Stack<string>(titles2.OrderBy(_ => rnd.Next()));

        var list1 = Observable.Defer(() => Enumerable.Range(1, expectedTotal)
            .OrderBy(rnd.Next)
            .Select(x => new Thing(idstack1.Pop(), titlestack1.Pop(), datestack1.Pop()))
            .ToObservable())
            .Replay()
            .RefCount();

        var list2 = Observable.Defer(() => Enumerable.Range(1, expectedTotal)
            .OrderBy(rnd.Next)
            .Select(x => new Thing(idstack2.Pop(), titlestack2.Pop(), datestack2.Pop()))
            .ToObservable())
            .Replay()
            .RefCount();

        var col = new TrackingCollection<Thing>(
            list1.Concat(list2),
            OrderedComparer<Thing>.OrderByDescending(x => x.CreatedAt).Compare,
            (item, idx, list) => idx < 5
        )
        { ProcessingDelay = TimeSpan.Zero };

        var count = 0;
        var evt = new ManualResetEvent(false);
        col.Subscribe(t =>
        {
            if (++count == expectedTotal * 2)
                evt.Set();
        }, () => { });

        evt.WaitOne();
        evt.Reset();

        // it's initially sorted by date, so id list should not match
        CollectionAssert.AreNotEqual(list1.Select(x => x.Number).ToEnumerable(), list2.Select(x => x.Number).ToEnumerable());

        var sortlist = list1.ToEnumerable().ToArray();
        Array.Sort(sortlist, new LambdaComparer<Thing>(OrderedComparer<Thing>.OrderByDescending(x => x.CreatedAt).Compare));
        CollectionAssert.AreEqual(sortlist.Take(5), col);

        col.SetComparer(OrderedComparer<Thing>.OrderBy(x => x.Number).Compare);
        sortlist = list1.ToEnumerable().ToArray();
        Array.Sort(sortlist, new LambdaComparer<Thing>(OrderedComparer<Thing>.OrderBy(x => x.Number).Compare));
        CollectionAssert.AreEqual(sortlist.Take(5), col);

        col.SetComparer(OrderedComparer<Thing>.OrderBy(x => x.CreatedAt).Compare);
        sortlist = list1.ToEnumerable().ToArray();
        Array.Sort(sortlist, new LambdaComparer<Thing>(OrderedComparer<Thing>.OrderBy(x => x.CreatedAt).Compare));
        CollectionAssert.AreEqual(sortlist.Take(5), col);

        col.SetComparer(OrderedComparer<Thing>.OrderByDescending(x => x.Title).Compare);
        sortlist = list1.ToEnumerable().ToArray();
        Array.Sort(sortlist, new LambdaComparer<Thing>(OrderedComparer<Thing>.OrderByDescending(x => x.Title).Compare));
        CollectionAssert.AreEqual(sortlist.Take(5), col);

        col.SetComparer(OrderedComparer<Thing>.OrderBy(x => x.Title).Compare);
        sortlist = list1.ToEnumerable().ToArray();
        Array.Sort(sortlist, new LambdaComparer<Thing>(OrderedComparer<Thing>.OrderBy(x => x.Title).Compare));
        CollectionAssert.AreEqual(sortlist.Take(5), col);

        col.Dispose();
    }
Пример #34
0
        public async Task ExpiredIndexReturnsLive()
        {
            var expected = 5;

            var username = "******";
            var reponame = "repo";

            var cache        = new InMemoryBlobCache();
            var apiClient    = Substitute.For <IApiClient>();
            var modelService = new ModelService(apiClient, cache, Substitute.For <IAvatarProvider>());
            var user         = CreateOctokitUser(username);

            apiClient.GetUser().Returns(Observable.Return(new UserAndScopes(user, null)));
            apiClient.GetOrganizations().Returns(Observable.Empty <Organization>());
            var act = modelService.GetAccounts().ToEnumerable().First().First();

            var repo = Substitute.For <ILocalRepositoryModel>();

            repo.Name.Returns(reponame);
            repo.CloneUrl.Returns(new UriString("https://github.com/" + username + "/" + reponame));

            var indexKey = string.Format(CultureInfo.InvariantCulture, "{0}|{1}:{2}", CacheIndex.PRPrefix, user.Login, repo.Name);

            var prcache = Enumerable.Range(1, expected)
                          .Select(id => CreatePullRequest(user, id, ItemState.Open, "Cache " + id, DateTimeOffset.UtcNow, DateTimeOffset.UtcNow));

            // seed the cache
            prcache
            .Select(item => new ModelService.PullRequestCacheItem(item))
            .Select(item => item.Save <ModelService.PullRequestCacheItem>(cache, indexKey).ToEnumerable().First())
            .SelectMany(item => CacheIndex.AddAndSaveToIndex(cache, indexKey, item).ToEnumerable())
            .ToList();

            // expire the index
            var indexobj = await cache.GetObject <CacheIndex>(indexKey);

            indexobj.UpdatedAt = DateTimeOffset.UtcNow - TimeSpan.FromMinutes(6);
            await cache.InsertObject(indexKey, indexobj);

            var prlive = Observable.Range(1, expected)
                         .Select(id => CreatePullRequest(user, id, ItemState.Open, "Live " + id, DateTimeOffset.UtcNow, DateTimeOffset.UtcNow))
                         .DelaySubscription(TimeSpan.FromMilliseconds(10));

            apiClient.GetPullRequestsForRepository(user.Login, repo.Name).Returns(prlive);

            await modelService.InsertUser(new AccountCacheItem(user));

            ITrackingCollection <IPullRequestModel> col = new TrackingCollection <IPullRequestModel>();

            modelService.GetPullRequests(repo, col);
            col.ProcessingDelay = TimeSpan.Zero;

            var count = 0;
            var done  = new ReplaySubject <Unit>();

            done.OnNext(Unit.Default);
            done.Subscribe();

            col.Subscribe(t =>
            {
                if (++count == expected * 2)
                {
                    done.OnCompleted();
                }
            }, () => { });

            await done;

            Assert.Collection(col, col.Select(x => new Action <IPullRequestModel>(t => Assert.True(x.Title.StartsWith("Live")))).ToArray());
        }
    public void ProcessingDelayPingsRegularly()
    {
        int count, total;
        count = total = 400;

        var list1 = new List<Thing>(Enumerable.Range(1, count).Select(i => GetThing(i, i, count - i)).ToList());

        var col = new TrackingCollection<Thing>(
            list1.ToObservable().Delay(TimeSpan.FromMilliseconds(10)),
            OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare);
        col.ProcessingDelay = TimeSpan.FromMilliseconds(10);

        var sub = new Subject<Thing>();
        var times = new List<DateTimeOffset>();
        sub.Subscribe(t =>
        {
            times.Add(DateTimeOffset.UtcNow);
        });

        count = 0;

        var evt = new ManualResetEvent(false);
        col.Subscribe(t =>
        {
            sub.OnNext(t);
            if (++count == list1.Count)
            {
                sub.OnCompleted();
                evt.Set();
            }
        }, () => { });


        evt.WaitOne();
        evt.Reset();

        Assert.AreEqual(total, col.Count);

        CollectionAssert.AreEqual(col, list1);

        long totalTime = 0;

        for (var j = 1; j < times.Count; j++)
            totalTime += (times[j] - times[j - 1]).Ticks;
        var avg = TimeSpan.FromTicks(totalTime / times.Count).TotalMilliseconds;
        Assert.GreaterOrEqual(avg, 9);
        Assert.LessOrEqual(avg, 12);
        col.Dispose();
    }
Пример #36
0
        public async Task ExpiredIndexClearsItemsAsync()
        {
            var expected = 5;

            var username = "******";
            var reponame = "repo";

            var cache        = new InMemoryBlobCache();
            var apiClient    = Substitute.For <IApiClient>();
            var modelService = CreateTarget(apiClient: apiClient, hostCache: cache);
            var user         = CreateOctokitUser(username);

            apiClient.GetUser().Returns(Observable.Return(user));
            apiClient.GetOrganizations().Returns(Observable.Empty <Organization>());
            var act = modelService.GetAccounts().ToEnumerable().First().First();

            var repo = Substitute.For <LocalRepositoryModel>();

            repo.Name.Returns(reponame);
            repo.Owner.Returns(user.Login);
            repo.CloneUrl.Returns(new UriString("https://github.com/" + username + "/" + reponame));

            var indexKey = string.Format(CultureInfo.InvariantCulture, "{0}|{1}:{2}", CacheIndex.PRPrefix, user.Login, repo.Name);

            var prcache = Enumerable.Range(1, expected)
                          .Select(id => CreatePullRequest(user, id, ItemState.Open, "Cache " + id, DateTimeOffset.UtcNow, DateTimeOffset.UtcNow));

            // seed the cache
            prcache
            .Select(item => new ModelService.PullRequestCacheItem(item))
            .Select(item => item.Save <ModelService.PullRequestCacheItem>(cache, indexKey).ToEnumerable().First())
            .SelectMany(item => CacheIndex.AddAndSaveToIndex(cache, indexKey, item).ToEnumerable())
            .ToList();

            // expire the index
            var indexobj = await cache.GetObject <CacheIndex>(indexKey);

            indexobj.UpdatedAt = DateTimeOffset.UtcNow - TimeSpan.FromMinutes(6);
            await cache.InsertObject(indexKey, indexobj);

            var prlive = Observable.Range(5, expected)
                         .Select(id => CreatePullRequest(user, id, ItemState.Open, "Live " + id, DateTimeOffset.UtcNow, DateTimeOffset.UtcNow, 0))
                         .DelaySubscription(TimeSpan.FromMilliseconds(10));

            apiClient.GetPullRequestsForRepository(user.Login, repo.Name).Returns(prlive);

            await modelService.InsertUser(new AccountCacheItem(user));

            ITrackingCollection <IPullRequestModel> col = new TrackingCollection <IPullRequestModel>();

            modelService.GetPullRequests(repo, col);
            col.ProcessingDelay = TimeSpan.Zero;

            var count = 0;
            var done  = new ReplaySubject <Unit>();

            done.OnNext(Unit.Default);
            done.Subscribe();

            col.Subscribe(t =>
            {
                // we get all the items from the cache (items 1-5), all the items from the live (items 5-9),
                // and 4 deletions (items 1-4) because the cache expired the items that were not
                // a part of the live data
                if (++count == 14)
                {
                    done.OnCompleted();
                }
            }, () => { });

            await done;

            Assert.That(5, Is.EqualTo(col.Count));

            /**Assert.Collection(col,
             *  t => { Assert.StartsWith("Live", t.Title); Assert.Equal(5, t.Number); },
             *  t => { Assert.StartsWith("Live", t.Title); Assert.Equal(6, t.Number); },
             *  t => { Assert.StartsWith("Live", t.Title); Assert.Equal(7, t.Number); },
             *  t => { Assert.StartsWith("Live", t.Title); Assert.Equal(8, t.Number); },
             *  t => { Assert.StartsWith("Live", t.Title); Assert.Equal(9, t.Number); }
             * );*/
        }
    public void OrderByMatchesOriginalOrder()
    {
        var count = 0;
        var total = 1000;

        var list1 = new List<Thing>(Enumerable.Range(1, total).Select(i => GetThing(i, i, total - i, "Run 1")).ToList());
        var list2 = new List<Thing>(Enumerable.Range(1, total).Select(i => GetThing(i, i, total - i, "Run 2")).ToList());

        var col = new TrackingCollection<Thing>(
            list1.ToObservable(),
            OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare,
            (item, position, list) => item.Title.Equals("Run 2"));
        col.ProcessingDelay = TimeSpan.Zero;

        count = 0;
        var evt = new ManualResetEvent(false);
        col.Subscribe(t =>
        {
            if (++count == list1.Count)
                evt.Set();
        }, () => { });

        evt.WaitOne();
        evt.Reset();

        Assert.AreEqual(total, count);
        Assert.AreEqual(0, col.Count);

        count = 0;

        // add new items
        foreach (var l in list2)
            col.AddItem(l);

        evt.WaitOne();
        evt.Reset();

        Assert.AreEqual(total, count);
        Assert.AreEqual(total, col.Count);
        CollectionAssert.AreEqual(col, list2);

        col.Dispose();
    }
Пример #38
0
    public void OnlyIndexes2To4()
    {
        var count = 6;

        var list1 = new List<Thing>(Enumerable.Range(1, count).Select(i => GetThing(i, i, count - i, "Run 1")).ToList());

        ITrackingCollection<Thing> col = new TrackingCollection<Thing>(
            Observable.Never<Thing>(),
            OrderedComparer<Thing>.OrderBy(x => x.UpdatedAt).Compare,
            (item, position, list) => position >= 2 && position <= 4);
        col.NewerComparer = OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare;
        col.ProcessingDelay = TimeSpan.Zero;

        var evt = new ManualResetEvent(false);
        col.Subscribe(t =>
        {
            if (++count == list1.Count)
                evt.Set();
        }, () => { });

        count = 0;
        // add first items
        foreach (var l in list1)
            col.AddItem(l);

        evt.WaitOne();
        evt.Reset();

        Assert.AreEqual(3, col.Count);

#if DEBUG
        CollectionAssert.AreEqual(list1.Reverse<Thing>(), (col as TrackingCollection<Thing>).DebugInternalList);
#endif

        CollectionAssert.AreEqual(col, new List<Thing>() { list1[3], list1[2], list1[1] });

        col.Dispose();
    }
    public void SortingTestWithFilterBetween6And12()
    {
        var source = new Subject<Thing>();

        var col = new TrackingCollection<Thing>(
            source,
            OrderedComparer<Thing>.OrderByDescending(x => x.UpdatedAt).Compare,
            (item, position, list) => item.UpdatedAt.Minute >= 6 && item.UpdatedAt.Minute <= 12);
        col.ProcessingDelay = TimeSpan.Zero;

        var count = 0;
        var expectedCount = 0;
        var evt = new ManualResetEvent(false);

        col.Subscribe(t =>
        {
            if (++count == expectedCount)
                evt.Set();
        }, () => { });

        // testing ADD
        expectedCount = 1;
        // add a thing with UpdatedAt=0:0:10
        Add(source, GetThing(1, 10));
        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(col, new List<Thing> {
            GetThing(1, 10),
        });

        // testing ADD
        // add another thing with UpdatedAt=0:0:2
        expectedCount = 2;
        Add(source, GetThing(2, 2));
        evt.WaitOne();
        evt.Reset();
        // check that list has {0:0:10,0:0:2}
        CollectionAssert.AreEqual(col, new List<Thing> {
            GetThing(1, 10),
        });

        // testing MOVE
        // replace thing with UpdatedAt=0:0:2 to UpdatedAt=0:0:12
        expectedCount = 3;
        Add(source, GetThing(2, 12));
        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(col, new List<Thing> {
            GetThing(2, 12),
            GetThing(1, 10),
        });

        // testing INSERT
        expectedCount = 4;
        Add(source, GetThing(3, 11));
        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(col, new List<Thing> {
            GetThing(2, 12),
            GetThing(3, 11),
            GetThing(1, 10),
        });

        // testing INSERT
        expectedCount = 7;
        Add(source, GetThing(4, 5));
        Add(source, GetThing(5, 14));
        Add(source, GetThing(6, 13));
        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(col, new List<Thing> {
            GetThing(2, 12),
            GetThing(3, 11),
            GetThing(1, 10),
        });

        // testing MOVE from top to middle
        expectedCount = 8;
        Add(source, GetThing(5, 5));
        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(col, new List<Thing> {
            GetThing(2, 12),
            GetThing(3, 11),
            GetThing(1, 10),
        });

        // testing MOVE from top to bottom
        expectedCount = 9;
        Add(source, GetThing(6, 4));
        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(col, new List<Thing> {
            GetThing(2, 12),
            GetThing(3, 11),
            GetThing(1, 10),
        });

        // testing MOVE from bottom to top
        expectedCount = 10;
        Add(source, GetThing(6, 14));
        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(col, new List<Thing> {
            GetThing(2, 12),
            GetThing(3, 11),
            GetThing(1, 10),
        });

        // testing MOVE from middle bottom to middle top
        expectedCount = 11;
        Add(source, GetThing(3, 14));
        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(col, new List<Thing> {
            GetThing(2, 12),
            GetThing(1, 10),
        });

        // testing MOVE from middle top to middle bottom
        expectedCount = 12;
        Add(source, GetThing(2, 9));
        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(col, new List<Thing> {
            GetThing(1, 10),
            GetThing(2, 9),
        });

        // testing MOVE from middle bottom to middle top more than 1 position
        expectedCount = 13;
        Add(source, GetThing(5, 12));
        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(col, new List<Thing> {
            GetThing(5, 12),
            GetThing(1, 10),
            GetThing(2, 9),
        });

        expectedCount = 14;
        col.RemoveItem(GetThing(1, 10));
        evt.WaitOne();
        evt.Reset();
        CollectionAssert.AreEqual(col, new List<Thing> {
            GetThing(5, 12),
            GetThing(2, 9),
        });

        col.Dispose();
    }
Пример #40
0
        public async Task ExpiredIndexClearsItems()
        {
            var expected = 5;

            var username = "******";
            var reponame = "repo";

            var cache = new InMemoryBlobCache();
            var apiClient = Substitute.For<IApiClient>();
            var modelService = new ModelService(apiClient, cache, Substitute.For<IAvatarProvider>());
            var user = CreateOctokitUser(username);
            apiClient.GetUser().Returns(Observable.Return(new UserAndScopes(user, null)));
            apiClient.GetOrganizations().Returns(Observable.Empty<Organization>());
            var act = modelService.GetAccounts().ToEnumerable().First().First();

            var repo = Substitute.For<ILocalRepositoryModel>();
            repo.Name.Returns(reponame);
            repo.CloneUrl.Returns(new UriString("https://github.com/" + username + "/" + reponame));

            var indexKey = string.Format(CultureInfo.InvariantCulture, "{0}|{1}:{2}", CacheIndex.PRPrefix, user.Login, repo.Name);

            var prcache = Enumerable.Range(1, expected)
                .Select(id => CreatePullRequest(user, id, ItemState.Open, "Cache " + id, DateTimeOffset.UtcNow, DateTimeOffset.UtcNow));

            // seed the cache
            prcache
                .Select(item => new ModelService.PullRequestCacheItem(item))
                .Select(item => item.Save<ModelService.PullRequestCacheItem>(cache, indexKey).ToEnumerable().First())
                .SelectMany(item => CacheIndex.AddAndSaveToIndex(cache, indexKey, item).ToEnumerable())
                .ToList();

            // expire the index
            var indexobj = await cache.GetObject<CacheIndex>(indexKey);
            indexobj.UpdatedAt = DateTimeOffset.UtcNow - TimeSpan.FromMinutes(6);
            await cache.InsertObject(indexKey, indexobj);

            var prlive = Observable.Range(5, expected)
                .Select(id => CreatePullRequest(user, id, ItemState.Open, "Live " + id, DateTimeOffset.UtcNow, DateTimeOffset.UtcNow, 0))
                .DelaySubscription(TimeSpan.FromMilliseconds(10));

            apiClient.GetPullRequestsForRepository(user.Login, repo.Name).Returns(prlive);

            await modelService.InsertUser(new AccountCacheItem(user));

            ITrackingCollection<IPullRequestModel> col = new TrackingCollection<IPullRequestModel>();
            modelService.GetPullRequests(repo, col);
            col.ProcessingDelay = TimeSpan.Zero;

            var count = 0;
            var done = new ReplaySubject<Unit>();
            done.OnNext(Unit.Default);
            done.Subscribe();

            col.Subscribe(t =>
            {
                // we get all the items from the cache (items 1-5), all the items from the live (items 5-9),
                // and 4 deletions (items 1-4) because the cache expired the items that were not
                // a part of the live data
                if (++count == 14)
                {
                    done.OnCompleted();
                }
            }, () => { });

            await done;

            Assert.Equal(5, col.Count);
            Assert.Collection(col, 
                t => { Assert.True(t.Title.StartsWith("Live")); Assert.Equal(5, t.Number); },
                t => { Assert.True(t.Title.StartsWith("Live")); Assert.Equal(6, t.Number); },
                t => { Assert.True(t.Title.StartsWith("Live")); Assert.Equal(7, t.Number); },
                t => { Assert.True(t.Title.StartsWith("Live")); Assert.Equal(8, t.Number); },
                t => { Assert.True(t.Title.StartsWith("Live")); Assert.Equal(9, t.Number); }
            );
        }