Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/Protocol/LanguageProtocolDelegatingHandlers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,8 @@ CancellationToken cancellationToken
}

var subject = new AsyncSubject<TItem>();
// in the event nothing is emitted...
subject.OnNext(default);
_handler(request, subject, _capability, cancellationToken);
return await subject.Select(_factory).ToTask(cancellationToken).ConfigureAwait(false);
}
Expand Down Expand Up @@ -468,6 +470,8 @@ async Task<TResponse> IRequestHandler<TParams, TResponse>.Handle(TParams request
}

var subject = new AsyncSubject<TItem>();
// in the event nothing is emitted...
subject.OnNext(default);
_handler(request, subject, cancellationToken);
return await subject.Select(_factory).ToTask(cancellationToken).ConfigureAwait(false);
}
Expand Down Expand Up @@ -528,6 +532,8 @@ async Task<TResponse> IRequestHandler<TParams, TResponse>.Handle(TParams request
}

var subject = new AsyncSubject<TItem>();
// in the event nothing is emitted...
subject.OnNext(default);
_handler(request, _capability, subject, cancellationToken);
return await subject.Select(_factory).ToTask(cancellationToken).ConfigureAwait(false);
}
Expand Down Expand Up @@ -584,6 +590,8 @@ async Task<TResponse> IRequestHandler<TParams, TResponse>.Handle(TParams request
}

var subject = new AsyncSubject<TItem>();
// in the event nothing is emitted...
subject.OnNext(default);
_handler(request, subject, cancellationToken);
return await subject.Select(_factory).ToTask(cancellationToken).ConfigureAwait(false);
}
Expand Down
3 changes: 2 additions & 1 deletion test/Dap.Tests/Integration/ProgressTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using OmniSharp.Extensions.DebugAdapter.Server;
using OmniSharp.Extensions.DebugAdapter.Testing;
using OmniSharp.Extensions.JsonRpc.Testing;
using TestingUtils;
using Xunit;
using Xunit.Abstractions;

Expand Down Expand Up @@ -75,7 +76,7 @@ public async Task Should_Support_Progress_From_Sever_To_Client()
}
);

await Task.Delay(1000);
await data.DelayUntilCount(6, CancellationToken);

var results = data.Select(
z => z switch {
Expand Down
5 changes: 4 additions & 1 deletion test/Lsp.Tests/Integration/DynamicRegistrationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
using OmniSharp.Extensions.LanguageServer.Protocol.Server.Capabilities;
using OmniSharp.Extensions.LanguageServer.Protocol.Shared;
using OmniSharp.Extensions.LanguageServer.Server;
using TestingUtils;
using Xunit;
using Xunit.Abstractions;

Expand Down Expand Up @@ -124,7 +125,9 @@ public async Task Should_Unregister_Dynamically_While_Server_Is_Running()
await WaitForRegistrationUpdate(client);
disposable.Dispose();
await WaitForRegistrationUpdate(client);
await Task.Delay(1000);
await TestHelper.DelayUntil(
() => client.RegistrationManager.CurrentRegistrations, z => !SelectorMatches(z, x => x.HasLanguage && x.Language == "vb"), CancellationToken
);
}

client.RegistrationManager.CurrentRegistrations.Should().NotContain(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using OmniSharp.Extensions.LanguageServer.Protocol.Server;
using OmniSharp.Extensions.LanguageServer.Server;
using Serilog.Events;
using TestingUtils;
using Xunit;
using Xunit.Abstractions;

Expand Down Expand Up @@ -137,7 +138,7 @@ public async Task Should_Fallback_To_Original_Configuration()
await scopedConfiguration.WaitForChange(CancellationToken);
await SettleNext();

await Task.Delay(2000);
await TestHelper.DelayUntil(() => scopedConfiguration["mysection:key"] == "value", CancellationToken);

scopedConfiguration["mysection:key"].Should().Be("value");
scopedConfiguration["othersection:value"].Should().Be("key");
Expand Down
7 changes: 4 additions & 3 deletions test/Lsp.Tests/Integration/LanguageServerLoggingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using OmniSharp.Extensions.LanguageServer.Protocol.Window;
using OmniSharp.Extensions.LanguageServer.Server;
using Serilog.Events;
using TestingUtils;
using Xunit;
using Xunit.Abstractions;

Expand Down Expand Up @@ -53,7 +54,7 @@ public async Task Logs_Are_Sent_To_Client_From_Server()
logger.LogTrace("Just gotta let you trace!");
logger.LogDebug("Just gotta let you debug!");

await Task.Delay(1000);
await _logs.DelayUntilCount(6, CancellationToken);

_logs.Should().HaveCount(6);
_logs.Where(z => z.Type == MessageType.Error).Should().HaveCount(2);
Expand Down Expand Up @@ -89,7 +90,7 @@ public async Task Logs_Are_Sent_To_Client_From_Server_Respecting_SetMinimumLevel
logger.LogTrace("Just gotta let you trace!");
logger.LogDebug("Just gotta let you debug!");

await Task.Delay(1000);
await _logs.DelayUntilCount(3, CancellationToken);

_logs.Should().HaveCount(3);
_logs.Where(z => z.Type == MessageType.Error).Should().HaveCount(2);
Expand Down Expand Up @@ -125,7 +126,7 @@ public async Task Logs_Are_Sent_To_Client_From_Server_Respecting_TraceLevel()
logger.LogTrace("Just gotta let you trace!");
logger.LogDebug("Just gotta let you debug!");

await Task.Delay(1001);
await _logs.DelayUntilCount(4, CancellationToken);

_logs.Should().HaveCount(4);
_logs.Where(z => z.Type == MessageType.Error).Should().HaveCount(2);
Expand Down
5 changes: 3 additions & 2 deletions test/Lsp.Tests/Integration/LogMessageTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
using OmniSharp.Extensions.LanguageServer.Protocol.Window;
using OmniSharp.Extensions.LanguageServer.Server;
using TestingUtils;
using Xunit;
using Xunit.Abstractions;

Expand Down Expand Up @@ -42,7 +43,7 @@ public async Task Should_Log_Messages_Through_Window_Extension_Methods()
}
);

await Task.Delay(1000);
await _receivedMessages.DelayUntilCount(6, CancellationToken);

_receivedMessages.Should().HaveCount(6);
_receivedMessages.Should().Contain(z => z.Type == MessageType.Error);
Expand Down Expand Up @@ -71,7 +72,7 @@ public async Task Should_Log_Messages_Through_Server_Extension_Methods()
}
);

await Task.Delay(1000);
await _receivedMessages.DelayUntilCount(6, CancellationToken);

_receivedMessages.Should().HaveCount(6);
_receivedMessages.Should().Contain(z => z.Type == MessageType.Error);
Expand Down
4 changes: 3 additions & 1 deletion test/Lsp.Tests/Integration/PartialItemsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using OmniSharp.Extensions.LanguageServer.Protocol.Progress;
using OmniSharp.Extensions.LanguageServer.Protocol.Server.WorkDone;
using OmniSharp.Extensions.LanguageServer.Server;
using TestingUtils;
using Xunit;
using Xunit.Abstractions;

Expand Down Expand Up @@ -123,7 +124,8 @@ public async Task Should_Behave_Like_An_Observable_With_WorkDone()
Observer.Create<WorkDoneProgress>(z => work.Add(z))
).Subscribe(x => items.AddRange(x));

await Task.Delay(1000);

await work.DelayUntilCount(6, CancellationToken);
await SettleNext();

var workResults = work.Select(z => z.Message);
Expand Down
25 changes: 17 additions & 8 deletions test/Lsp.Tests/Integration/ProgressTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Reactive.Threading.Tasks;
using System.Threading.Tasks;
Expand All @@ -14,6 +16,7 @@
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
using OmniSharp.Extensions.LanguageServer.Protocol.Serialization;
using OmniSharp.Extensions.LanguageServer.Server;
using TestingUtils;
using Xunit;
using Xunit.Abstractions;

Expand Down Expand Up @@ -66,13 +69,16 @@ public async Task Should_Send_Progress_From_Server_To_Client()
}
);

await Task.Delay(1000);

workDoneObservable.Dispose();
await Observable.Create<Unit>(
observer => new CompositeDisposable() {
observable.Select(z => z.Value).Take(5).Subscribe(_ => observer.OnNext(Unit.Default), observer.OnCompleted),
workDoneObservable
}
).ToTask(CancellationToken);

var data = await observable.Select(z => z.Value).ToArray().ToTask(CancellationToken);

data.Should().ContainInOrder(new [] {"1", "3", "2", "4", "5" });
data.Should().ContainInOrder(new[] { "1", "3", "2", "4", "5" });
}

[Fact]
Expand Down Expand Up @@ -111,13 +117,16 @@ public async Task Should_Send_Progress_From_Client_To_Server()
}
);

await Task.Delay(1000);

workDoneObservable.Dispose();
await Observable.Create<Unit>(
observer => new CompositeDisposable() {
observable.Select(z => z.Value).Take(5).Subscribe(_ => observer.OnNext(Unit.Default), observer.OnCompleted),
workDoneObservable
}
).ToTask(CancellationToken);

var data = await observable.Select(z => z.Value).ToArray().ToTask(CancellationToken);

data.Should().ContainInOrder(new [] {"1", "3", "2", "4", "5" });
data.Should().ContainInOrder(new[] { "1", "3", "2", "4", "5" });
}

[Fact]
Expand Down
3 changes: 2 additions & 1 deletion test/Lsp.Tests/Integration/RequestCancellationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using OmniSharp.Extensions.LanguageServer.Protocol.Document;
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
using OmniSharp.Extensions.LanguageServer.Server;
using TestingUtils;
using Xunit;
using Xunit.Abstractions;

Expand Down Expand Up @@ -132,7 +133,7 @@ public async Task Can_Publish_Diagnostics_Delayed()

await SettleNext();

await Task.Delay(1000);
await _diagnostics.DelayUntilCount(1, CancellationToken);

_diagnostics.Should().HaveCount(1);
}
Expand Down
5 changes: 3 additions & 2 deletions test/Lsp.Tests/Integration/ShowMessageTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using OmniSharp.Extensions.LanguageServer.Protocol.Models;
using OmniSharp.Extensions.LanguageServer.Protocol.Window;
using OmniSharp.Extensions.LanguageServer.Server;
using TestingUtils;
using Xunit;
using Xunit.Abstractions;

Expand Down Expand Up @@ -43,7 +44,7 @@ public async Task Should_Show_Messages_Through_Window_Extension_Methods()
}
);

await Task.Delay(1000);
await _receivedMessages.DelayUntilCount(6, CancellationToken);

_receivedMessages.Should().HaveCount(6);
_receivedMessages.Should().Contain(z => z.Type == MessageType.Error);
Expand Down Expand Up @@ -72,7 +73,7 @@ public async Task Should_Show_Messages_Through_Server_Extension_Methods()
}
);

await Task.Delay(1000);
await _receivedMessages.DelayUntilCount(6, CancellationToken);

_receivedMessages.Should().HaveCount(6);
_receivedMessages.Should().Contain(z => z.Type == MessageType.Error);
Expand Down
60 changes: 60 additions & 0 deletions test/TestingUtils/FactWithSkipOnAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Xunit;

namespace TestingUtils
{
public class FactWithSkipOnAttribute : FactAttribute
{
private readonly SkipOnPlatform[] _platformsToSkip;
private string _skip;

public FactWithSkipOnAttribute(params SkipOnPlatform[] platformsToSkip)
{
_platformsToSkip = platformsToSkip;
}

public override string Skip
{
get => !UnitTestDetector.IsCI() && _platformsToSkip.Any(UnitTestDetector.PlatformToSkipPredicate)
? "Skipped on platform" + ( string.IsNullOrWhiteSpace(_skip) ? "" : " because " + _skip )
: null;
set => _skip = value;
}
}

public static class TestHelper
{
public static async Task DelayUntil<T>(Func<T> valueFunc, Func<T, bool> func, CancellationToken cancellationToken, TimeSpan? delay = null)
{
while (true)
{
if (func(valueFunc())) return;
await Task.Delay(delay ?? TimeSpan.FromMilliseconds(100), cancellationToken);
}
}

public static async Task DelayUntil(Func<bool> func, CancellationToken cancellationToken, TimeSpan? delay = null)
{
while (true)
{
if (func()) return;
await Task.Delay(delay ?? TimeSpan.FromMilliseconds(100), cancellationToken);
}
}

public static Task DelayUntil<T>(this T value, Func<T, bool> func, CancellationToken cancellationToken, TimeSpan? delay = null)
{
return DelayUntil(() => value, func, cancellationToken, delay);
}

public static Task DelayUntilCount<T>(this T value, int count, CancellationToken cancellationToken, TimeSpan? delay = null) where T : IEnumerable
{
return DelayUntil(() => value.OfType<object>().Count() >= count, cancellationToken, delay);
}
}
}
9 changes: 9 additions & 0 deletions test/TestingUtils/SkipOnPlatform.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace TestingUtils
{
public enum SkipOnPlatform
{
Linux,
Mac,
Windows,
}
}
24 changes: 24 additions & 0 deletions test/TestingUtils/TheoryWithSkipOnAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System.Linq;
using Xunit;

namespace TestingUtils
{
public class TheoryWithSkipOnAttribute : TheoryAttribute
{
private readonly SkipOnPlatform[] _platformsToSkip;
private string _skip;

public TheoryWithSkipOnAttribute(params SkipOnPlatform[] platformsToSkip)
{
_platformsToSkip = platformsToSkip;
}

public override string Skip
{
get => !UnitTestDetector.IsCI() && _platformsToSkip.Any(UnitTestDetector.PlatformToSkipPredicate)
? "Skipped on platform" + ( string.IsNullOrWhiteSpace(_skip) ? "" : " because " + _skip )
: null;
set => _skip = value;
}
}
}
Loading