|
|
|
@ -11,6 +11,7 @@ using System.Threading; |
|
|
|
using System.Threading.Tasks; |
|
|
|
using Avalonia.Remote.Protocol; |
|
|
|
using Avalonia.Remote.Protocol.Designer; |
|
|
|
using Avalonia.Remote.Protocol.Viewport; |
|
|
|
using Xunit; |
|
|
|
using Xunit.Extensions; |
|
|
|
|
|
|
|
@ -124,5 +125,115 @@ namespace Avalonia.DesignerSupport.Tests |
|
|
|
proc.WaitForExit(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
[Theory] |
|
|
|
[InlineData( |
|
|
|
@"../../../../../tests/Avalonia.DesignerSupport.TestApp/bin/$BUILD/netcoreapp2.0/", |
|
|
|
"Avalonia.DesignerSupport.TestApp", |
|
|
|
"Avalonia.DesignerSupport.TestApp.dll", |
|
|
|
@"../../../../../tests/Avalonia.DesignerSupport.TestApp/MainWindow.xaml"), |
|
|
|
InlineData( |
|
|
|
@"../../../../../samples/ControlCatalog.NetCore/bin/$BUILD/netcoreapp2.0/", |
|
|
|
"ControlCatalog.NetCore", |
|
|
|
"ControlCatalog.dll", |
|
|
|
@"../../../../../samples/ControlCatalog/MainWindow.xaml")] |
|
|
|
public async Task Designer_Should_Provide_A_Frame( |
|
|
|
string outputDir, |
|
|
|
string executableName, |
|
|
|
string assemblyName, |
|
|
|
string xamlFile) |
|
|
|
{ |
|
|
|
|
|
|
|
var xaml = File.ReadAllText(xamlFile); |
|
|
|
string buildType; |
|
|
|
#if DEBUG
|
|
|
|
buildType = "Debug"; |
|
|
|
#else
|
|
|
|
buildType = "Release"; |
|
|
|
#endif
|
|
|
|
outputDir = Path.GetFullPath(outputDir.Replace("$BUILD", buildType)); |
|
|
|
|
|
|
|
var sessionId = Guid.NewGuid(); |
|
|
|
FrameMessage receivedFrame = null; |
|
|
|
|
|
|
|
var resultMessageReceivedToken = new CancellationTokenSource(); |
|
|
|
|
|
|
|
var tcpListener = new TcpListener(IPAddress.Loopback, 0); |
|
|
|
tcpListener.Start(); |
|
|
|
var port = ((IPEndPoint)tcpListener.LocalEndpoint).Port; |
|
|
|
tcpListener.Stop(); |
|
|
|
var transport = new BsonTcpTransport(); |
|
|
|
transport.Listen(IPAddress.Loopback, port, conn => |
|
|
|
{ |
|
|
|
conn.OnMessage += async (_, msg) => |
|
|
|
{ |
|
|
|
if (msg is StartDesignerSessionMessage start) |
|
|
|
{ |
|
|
|
Assert.Equal(sessionId, Guid.Parse(start.SessionId)); |
|
|
|
await conn.Send(new ClientSupportedPixelFormatsMessage |
|
|
|
{ |
|
|
|
Formats = new[] |
|
|
|
{ |
|
|
|
Avalonia.Remote.Protocol.Viewport.PixelFormat.Bgra8888, |
|
|
|
Avalonia.Remote.Protocol.Viewport.PixelFormat.Rgba8888, |
|
|
|
} |
|
|
|
}); |
|
|
|
await conn.Send(new UpdateXamlMessage |
|
|
|
{ |
|
|
|
AssemblyPath = Path.Combine(outputDir, assemblyName), |
|
|
|
Xaml = xaml |
|
|
|
}); |
|
|
|
} |
|
|
|
else if (msg is UpdateXamlResultMessage result) |
|
|
|
{ |
|
|
|
if (result.Error != null) |
|
|
|
outputHelper.WriteLine(result.Error); |
|
|
|
|
|
|
|
} |
|
|
|
else if (msg is FrameMessage fm) |
|
|
|
{ |
|
|
|
receivedFrame = fm; |
|
|
|
resultMessageReceivedToken.Cancel(); |
|
|
|
conn.Dispose(); |
|
|
|
} |
|
|
|
}; |
|
|
|
}); |
|
|
|
|
|
|
|
var cmdline = |
|
|
|
$"exec --runtimeconfig \"{outputDir}{executableName}.runtimeconfig.json\" --depsfile \"{outputDir}{executableName}.deps.json\" " |
|
|
|
+ $" \"{DesignerAppPath.Replace("$BUILD", buildType)}\" " |
|
|
|
+ $"--transport tcp-bson://127.0.0.1:{port}/ --session-id {sessionId} \"{outputDir}{executableName}.dll\""; |
|
|
|
|
|
|
|
using (var proc = new Process |
|
|
|
{ |
|
|
|
StartInfo = new ProcessStartInfo("dotnet", cmdline) |
|
|
|
{ |
|
|
|
UseShellExecute = false, |
|
|
|
RedirectStandardOutput = true, |
|
|
|
RedirectStandardError = true, |
|
|
|
CreateNoWindow = true, |
|
|
|
WorkingDirectory = outputDir, |
|
|
|
}, |
|
|
|
EnableRaisingEvents = true |
|
|
|
}) |
|
|
|
{ |
|
|
|
proc.Start(); |
|
|
|
|
|
|
|
var cancelled = false; |
|
|
|
try |
|
|
|
{ |
|
|
|
await Task.Delay(1000000, resultMessageReceivedToken.Token); |
|
|
|
} |
|
|
|
catch (TaskCanceledException) |
|
|
|
{ |
|
|
|
cancelled = true; |
|
|
|
} |
|
|
|
|
|
|
|
Assert.True(cancelled, $"Message Not Received."); |
|
|
|
Assert.NotNull(receivedFrame); |
|
|
|
proc.Kill(); |
|
|
|
proc.WaitForExit(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|