public void Start_WhenFileNotificationIsYield_ShouldCallSynchronize( [Frozen]TestScheduler scheduler, [Frozen(As = typeof(IObservable<MusicMirrorConfiguration>))]TestObservableWrapper<MusicMirrorConfiguration> configurationObservable, [Frozen]Mock<IFileObserverFactory> fileObserverFactory, [Frozen]Mock<IFileSynchronizerVisitorFactory> fileSynchronizerFactory, SynchronizeFilesWhenFileChanged sut, MusicMirrorConfiguration configuration, IFileNotification[][] fileNotification, Mock<IFileSynchronizerVisitor> fileSynchronizerVisitor) { //arrange configurationObservable.SetObservable(scheduler.CreateHotObservable(OnNext(Subscribed + 1, configuration))); const long NotificationsStart = Subscribed + 2; var fileObserver = scheduler.CreateHotObservable( fileNotification.Select((f, i) => OnNext(NotificationsStart + i, f)).ToArray()); fileObserverFactory.Setup(f => f.GetFileObserver(configuration.SourcePath)).Returns(fileObserver); fileSynchronizerFactory.Setup(f => f.CreateVisitor(configuration)).Returns(fileSynchronizerVisitor.Object); //act sut.Start(); scheduler.Start(); //assert foreach (var m in fileNotification.SelectMany(f => f).Select(f => Mock.Get(f))) { m.Verify(ff => ff.Accept(It.IsAny<CancellationToken>(), fileSynchronizerVisitor.Object)); } }
private async Task Log(Task task, string message, IFileNotification notification) { _log.Info(message); try { await task; } catch (Exception ex) { _log.Error(ex, "Error while visiting " + notification.Kind); throw; } }
void OnSourceFileNotification(IFileNotification notification) { Log(notification); _sourceFileIndices.AddOrUpdate(notification.File, SourceSymbolsFor, (file, oldValue) => SourceSymbolsFor(file)); }
private IObservable<Unit> SynchronizeFile(IFileNotification file, IFileSynchronizerVisitor visitor) { return Observable.FromAsync(async ct => await file.Accept(ct, visitor), _notificationsScheduler) .Do(_ => { _transcodingResultNotifications.OnNext(FileTranscodingResultNotification.CreateSuccess(file)); _numberOfFilesAddedInTranscodingQueue.OnNext(-1); }) .Catch((Exception ex) => { _transcodingResultNotifications.OnNext(FileTranscodingResultNotification.CreateFailure(file, ex)); _numberOfFilesAddedInTranscodingQueue.OnNext(-1); return Observable.Return(Unit.Default, ImmediateScheduler.Instance); }); }
public void SynchronizedFileCount_WhenTranscodingIsNotRunning_AndFileNotificationsArePushed_ShouldReturnCorrectValue( [Frozen]TestSchedulers schedulers, [Frozen]Mock<ITranscodingNotifications> notifications, ConfigurationPageViewModel sut, IFileNotification[] fileNotifications) { //arrange var fileNotificationsObservable = schedulers.CreateHotObservable( OnNext(202, fileNotifications)); var notificationsObservable = schedulers.CreateHotObservable( OnNext(201, false)); notifications.Setup(n => n.ObserveIsTranscodingRunning()).Returns(notificationsObservable); notifications.Setup(n => n.ObserveNotifications()).Returns(fileNotificationsObservable); //act var actual = schedulers.Start(() => sut.SynchronizedFileCount); //assert var expected = new[] { OnNext(200, SynchronizedFilesCountViewModel.Empty) }; actual.Messages.ShouldAllBeEquivalentTo(expected); }
public void SynchronizedFileCount_WhenTranscodingIsRunning_AndTranscodingResultsArePushedWithFailures_ShouldReturnCorrectValue( [Frozen]TestSchedulers schedulers, [Frozen]Mock<ITranscodingNotifications> notifications, IFileNotification[] fileNotifications, IFileNotification[] failuresNotifications, Fixture fixture) { //arrange var notificationsObservable = schedulers.CreateHotObservable( OnNext(201, true)); var transcodingResultsObservable = schedulers.CreateHotObservable( fileNotifications.Select((f, i) => OnNext(203 + i, FileTranscodingResultNotification.CreateSuccess(f))) .Concat(failuresNotifications.Select((f, i) => OnNext(203 + fileNotifications.Length + i, FileTranscodingResultNotification.CreateFailure(f, new Exception())))) .ToArray()); notifications.Setup(n => n.ObserveIsTranscodingRunning()).Returns(notificationsObservable); notifications.Setup(n => n.ObserveTranscodingResult()).Returns(transcodingResultsObservable); var sut = fixture.Create<ConfigurationPageViewModel>(); //act var actual = schedulers.Start(() => sut.SynchronizedFileCount); //assert var expected = new[] { OnNext(Subscribed, SynchronizedFilesCountViewModel.Empty), } .Concat(fileNotifications.Select((f, i) => OnNext(203 + i, new SynchronizedFilesCountViewModel(i + 1, 0))).ToArray()); actual.Messages.ShouldAllBeEquivalentTo(expected); }
public void SynchronizedFileCount_WhenTranscodingIsRunningChangesSeveralTimes_AndTranscodingResultsArePushed_ShouldReturnCorrectValue( [Frozen]TestSchedulers schedulers, [Frozen]Mock<ITranscodingNotifications> notifications, IFileNotification[] fileNotifications, Fixture fixture) { //arrange var notificationsObservable = schedulers.CreateHotObservable( OnNext(Subscribed + 1, false), OnNext(Subscribed + 100, true), OnNext(Subscribed + 199, false), OnNext(Subscribed + 200, true), OnNext(Subscribed + 299, false), OnNext(Subscribed + 300, true), OnNext(Subscribed + 399, false)); Func<long, IEnumerable<Recorded<Notification<IFileTranscodingResultNotification>>>> createFileNotifications = offset => fileNotifications.Select((f, i) => OnNext(offset + i, FileTranscodingResultNotification.CreateSuccess(f))); var transcodingResultsObservable = schedulers.CreateHotObservable( createFileNotifications(Subscribed + 101) .Concat(createFileNotifications(Subscribed + 201)) .Concat(createFileNotifications(Subscribed + 301)) .ToArray() ); notifications.Setup(n => n.ObserveIsTranscodingRunning()).Returns(notificationsObservable); notifications.Setup(n => n.ObserveTranscodingResult()).Returns(transcodingResultsObservable); var sut = fixture.Create<ConfigurationPageViewModel>(); //act var actual = schedulers.Start(() => sut.SynchronizedFileCount.Do(_ => { })); //assert Func<long, IEnumerable<Recorded<Notification<SynchronizedFilesCountViewModel>>>> createExpectedFileNotifications = offset => fileNotifications.Select((f, i) => OnNext(offset + i, new SynchronizedFilesCountViewModel(i + 1, 0))); var expected = new[] { OnNext(Subscribed, SynchronizedFilesCountViewModel.Empty), } .Concat(createExpectedFileNotifications(Subscribed + 101)) .Concat(createExpectedFileNotifications(Subscribed + 201)) .Concat(createExpectedFileNotifications(Subscribed + 301)) .ToArray(); actual.Messages.ShouldAllBeEquivalentTo(expected); }
private static IEnumerable<Recorded<System.Reactive.Notification<SynchronizedFilesCountViewModel>>> CreateExpectedFileNotifications( IFileNotification[][] fileNotifications, int offset) { return fileNotifications.Aggregate(new List<int>(), (list, files) => { list.Add(list.LastOrDefault() + files.Length); return list; }) .Select((f, i) => OnNext(Subscribed + i + offset, new SynchronizedFilesCountViewModel(0, f))); }
public void SynchronizedFileCount_WhenTranscodingIsRunningChangesSeveralTimes_AndFileNotificationsArePushedSeveralTimes_ShouldReturnCorrectValue( [Frozen]TestSchedulers schedulers, [Frozen]Mock<ITranscodingNotifications> notifications, IFileNotification[][] fileNotifications, Fixture fixture) { //arrange const int TranscodingStoppedRelativeTime = 50; var fileNotificationsObservable = schedulers.CreateHotObservable( fileNotifications.Select((f, i) => OnNext(Subscribed + i + 101, f)) .Concat(fileNotifications.Select((f, i) => OnNext(Subscribed + i + 201, f))) .Concat(fileNotifications.Select((f, i) => OnNext(Subscribed + i + 301, f))) .ToArray() ); var notificationsObservable = schedulers.CreateHotObservable( OnNext(Subscribed + 1, false), OnNext(Subscribed + 100, true), OnNext(Subscribed + 100 + TranscodingStoppedRelativeTime, false), OnNext(Subscribed + 200, true), OnNext(Subscribed + 200 + TranscodingStoppedRelativeTime, false), OnNext(Subscribed + 300, true), OnNext(Subscribed + 300 + TranscodingStoppedRelativeTime, false)); notifications.Setup(n => n.ObserveIsTranscodingRunning()).Returns(notificationsObservable); notifications.Setup(n => n.ObserveNotifications()).Returns(fileNotificationsObservable); var sut = fixture.Create<ConfigurationPageViewModel>(); //act var actual = schedulers.Start(() => sut.SynchronizedFileCount); //assert var expected = OnNext(Subscribed, SynchronizedFilesCountViewModel.Empty).Yield() .Concat(CreateExpectedFileNotifications(fileNotifications, 101)) .Concat(CreateExpectedFileNotifications(fileNotifications, 201)) .Concat(CreateExpectedFileNotifications(fileNotifications, 301)) .ToArray(); actual.Messages.ShouldAllBeEquivalentTo(expected); }
public void ObserveTranscodingResult_WhenFileNotificationIsYield_ShouldReturnCorrectValue( [Frozen]TestScheduler scheduler, [Frozen(As = typeof(IObservable<MusicMirrorConfiguration>))]TestObservableWrapper<MusicMirrorConfiguration> configurationObservable, [Frozen]Mock<IFileObserverFactory> fileObserverFactory, [Frozen]Mock<IFileSynchronizerVisitorFactory> fileSynchronizerFactory, SynchronizeFilesWhenFileChanged sut, MusicMirrorConfiguration configuration, IFileNotification[][] fileNotification, Mock<IFileSynchronizerVisitor> fileSynchronizerVisitor) { //arrange sut.SynchronizationScheduler = ImmediateScheduler.Instance; configurationObservable.SetObservable(scheduler.CreateHotObservable(OnNext(Subscribed + 1, configuration))); const long NotificationsStart = Subscribed + 2; var fileObserver = scheduler.CreateHotObservable( fileNotification.Select((f, i) => OnNext(NotificationsStart + i, f)).ToArray()); fileObserverFactory.Setup(f => f.GetFileObserver(configuration.SourcePath)).Returns(fileObserver); fileSynchronizerFactory.Setup(f => f.CreateVisitor(configuration)).Returns(fileSynchronizerVisitor.Object); scheduler.Schedule(200.Ticks(), () => sut.Start()); //act var actual = scheduler.Start(() => sut.ObserveTranscodingResult()); //assert var expected = fileNotification.SelectMany( (notifications, i) => notifications.Select( f => new FileTranscodingResultNotification.SuccessTranscodingResultNotification(f)) ).ToArray(); actual.Values().ShouldAllBeEquivalentTo(expected, o => o.RespectingRuntimeTypes()); }
private static void SetupTranscodingWorkWithIncrementalDuration(TestScheduler scheduler, IFileNotification[] fileNotification) { var i = 0; foreach (var f in fileNotification) { i++; var j = i; Mock.Get(f).Setup(ff => ff.Accept(It.IsAny<CancellationToken>(), It.IsAny<IFileSynchronizerVisitor>())) .Returns(() => { var completionSource = new TaskCompletionSource<bool>(); scheduler.ScheduleAbsolute(scheduler.Now.AddTicks(j).Ticks, () => completionSource.SetResult(true)); return completionSource.Task; }); } }
public void ObserveIsTranscodingRunning_WhenFilesAreTranscodingAndSubscribeOccursLaterOn_ShouldReturnCorrectValue( [Frozen]TestScheduler scheduler, [Frozen(As = typeof(IObservable<MusicMirrorConfiguration>))]TestObservableWrapper<MusicMirrorConfiguration> configurationObservable, [Frozen]Mock<IFileObserverFactory> fileObserverFactory, SynchronizeFilesWhenFileChanged sut, MusicMirrorConfiguration configuration, IFileNotification[] fileNotification ) { sut.SynchronizationScheduler = ImmediateScheduler.Instance; const long NotificationsStart = Subscribed + 1; const long Subscription = Subscribed + 3; configurationObservable.SetObservable(scheduler.CreateHotObservable(OnNext(NotificationsStart, configuration))); var fileObserver = scheduler.CreateHotObservable(OnNext(NotificationsStart, fileNotification)); fileObserverFactory.Setup(f => f.GetFileObserver(configuration.SourcePath)).Returns(fileObserver); SetupTranscodingWorkWithIncrementalDuration(scheduler, fileNotification); scheduler.Schedule(200.Ticks(), () => sut.Start()); //act var actual = scheduler.Start(() => sut.ObserveIsTranscodingRunning(), Created, Subscription, Disposed); //assert var expected = new[] { true, false }; //+1 because we expect that the tasks results of file.Accept will be scheduled on the TestScheduler actual.Values().ShouldAllBeEquivalentTo(expected); }
public void ObserveIsTranscodingRunning_WhenFilesAreTranscoding_ShouldReturnCorrectValue( [Frozen]TestScheduler scheduler, [Frozen(As = typeof(IObservable<MusicMirrorConfiguration>))]TestObservableWrapper<MusicMirrorConfiguration> configurationObservable, [Frozen]Mock<IFileObserverFactory> fileObserverFactory, SynchronizeFilesWhenFileChanged sut, MusicMirrorConfiguration configuration, IFileNotification[] fileNotification ) { //arrange sut.SynchronizationScheduler = ImmediateScheduler.Instance; configurationObservable.SetObservable(scheduler.CreateHotObservable(OnNext(Subscribed + 1, configuration))); const long NotificationsStart = Subscribed + 2; var fileObserver = scheduler.CreateHotObservable(OnNext(NotificationsStart, fileNotification)); fileObserverFactory.Setup(f => f.GetFileObserver(configuration.SourcePath)).Returns(fileObserver); SetupTranscodingWorkWithIncrementalDuration(scheduler, fileNotification); scheduler.Schedule(200.Ticks(), () => sut.Start()); //act var actual = scheduler.Start(() => sut.ObserveIsTranscodingRunning()); //assert var expected = new[] { false, true, false }; actual.Values().ShouldAllBeEquivalentTo(expected); }
public void ObserveFileNotifications_Start_WhenFileNotificationIsYield_ShouldCallSynchronize( [Frozen]TestScheduler scheduler, [Frozen(As = typeof(IObservable<MusicMirrorConfiguration>))]TestObservableWrapper<MusicMirrorConfiguration> configurationObservable, [Frozen]Mock<IFileObserverFactory> fileObserverFactory, SynchronizeFilesWhenFileChanged sut, MusicMirrorConfiguration configuration, IFileNotification[][] fileNotification) { //arrange configurationObservable.SetObservable(scheduler.CreateHotObservable(OnNext(Subscribed + 1, configuration))); var expectedNotifications = fileNotification.Select((f, i) => OnNext(Subscribed + i + 2, f)).ToArray(); var fileObserver = scheduler.CreateHotObservable(expectedNotifications); fileObserverFactory.Setup(f => f.GetFileObserver(configuration.SourcePath)).Returns(fileObserver); scheduler.Schedule(200.Ticks(), () => sut.Start()); //act var actual = scheduler.Start(() => sut.ObserveNotifications()); //assert var expected = expectedNotifications.Select(n => n.Value.Value); actual.Values().ShouldAllBeEquivalentTo(expected); }
public FileHandlerLogic(IRepository repository, IFileClassesCommunication fileClassesCommunication, IFileNotification fileNotification) : base(repository) { _fileClassesCommunication = fileClassesCommunication; _fileNotification = fileNotification; }