@@ -491,6 +491,69 @@ public async Task RunCommand_SkipsBuild_WhenExtensionDevKitCapabilityIsAvailable
491491 Assert . False ( buildCalled , "Build should be skipped when extension DevKit capability is available." ) ;
492492 }
493493
494+ [ Fact ]
495+ public async Task RunCommand_SkipsBuild_WhenRunningInExtension ( )
496+ {
497+ var buildCalled = false ;
498+
499+ var extensionBackchannel = new TestExtensionBackchannel ( ) ;
500+ extensionBackchannel . GetCapabilitiesAsyncCallback = ct => Task . FromResult ( Array . Empty < string > ( ) ) ;
501+
502+ var appHostBackchannel = new TestAppHostBackchannel ( ) ;
503+ appHostBackchannel . GetDashboardUrlsAsyncCallback = ( ct ) => Task . FromResult ( new DashboardUrlsState
504+ {
505+ DashboardHealthy = true ,
506+ BaseUrlWithLoginToken = "http://localhost/dashboard" ,
507+ CodespacesUrlWithLoginToken = null
508+ } ) ;
509+ appHostBackchannel . GetAppHostLogEntriesAsyncCallback = ReturnLogEntriesUntilCancelledAsync ;
510+
511+ var backchannelFactory = ( IServiceProvider sp ) => appHostBackchannel ;
512+
513+ var extensionInteractionServiceFactory = ( IServiceProvider sp ) => new TestExtensionInteractionService ( sp ) ;
514+
515+ var runnerFactory = ( IServiceProvider sp ) => {
516+ var runner = new TestDotNetCliRunner ( ) ;
517+ runner . CheckHttpCertificateAsyncCallback = ( options , ct ) => 0 ;
518+ runner . BuildAsyncCallback = ( projectFile , options , ct ) => {
519+ buildCalled = true ;
520+ return 0 ;
521+ } ;
522+ runner . GetAppHostInformationAsyncCallback = ( projectFile , options , ct ) => ( 0 , true , VersionHelper . GetDefaultTemplateVersion ( ) ) ;
523+ runner . RunAsyncCallback = async ( projectFile , watch , noBuild , args , env , backchannelCompletionSource , options , ct ) => {
524+ var backchannel = sp . GetRequiredService < IAppHostBackchannel > ( ) ;
525+ backchannelCompletionSource ! . SetResult ( backchannel ) ;
526+ await Task . Delay ( Timeout . InfiniteTimeSpan , ct ) ;
527+ return 0 ;
528+ } ;
529+ return runner ;
530+ } ;
531+
532+ var projectLocatorFactory = ( IServiceProvider sp ) => new TestProjectLocator ( ) ;
533+
534+ using var workspace = TemporaryWorkspace . Create ( outputHelper ) ;
535+ var services = CliTestHelper . CreateServiceCollection ( workspace , outputHelper , options =>
536+ {
537+ options . ProjectLocatorFactory = projectLocatorFactory ;
538+ options . AppHostBackchannelFactory = backchannelFactory ;
539+ options . DotNetCliRunnerFactory = runnerFactory ;
540+ options . ExtensionBackchannelFactory = _ => extensionBackchannel ;
541+ options . InteractionServiceFactory = extensionInteractionServiceFactory ;
542+ } ) ;
543+
544+ var provider = services . BuildServiceProvider ( ) ;
545+ var command = provider . GetRequiredService < RootCommand > ( ) ;
546+ var result = command . Parse ( "run" ) ;
547+
548+ using var cts = new CancellationTokenSource ( ) ;
549+ var pendingRun = result . InvokeAsync ( cancellationToken : cts . Token ) ;
550+ cts . Cancel ( ) ;
551+ var exitCode = await pendingRun . WaitAsync ( CliTestConstants . DefaultTimeout ) ;
552+
553+ Assert . Equal ( ExitCodeConstants . Success , exitCode ) ;
554+ Assert . False ( buildCalled , "Build should be skipped when running in extension." ) ;
555+ }
556+
494557 [ Fact ]
495558 public async Task RunCommand_WhenSingleFileAppHostAndDefaultWatchEnabled_DoesNotUseWatchMode ( )
496559 {
0 commit comments