1+ using System ;
2+ using System . Collections . Generic ;
3+ using System . CommandLine . Suggest ;
4+ using System . IO ;
5+ using System . Linq ;
6+ using CommandDotNet . Builders ;
7+ using CommandDotNet . DotnetSuggest ;
8+ using CommandDotNet . TestTools ;
9+ using CommandDotNet . TestTools . Scenarios ;
10+ using FluentAssertions ;
11+ using Xunit ;
12+ using Xunit . Abstractions ;
13+
14+ namespace CommandDotNet . Tests . FeatureTests . SuggestDirective ;
15+
16+ public class SuggestDirectiveRegistrationTests
17+ {
18+ private readonly ITestOutputHelper _output ;
19+ private readonly string _filePath = Path . Join ( nameof ( SuggestDirectiveRegistrationTests ) , "suggest-test.exe" ) ;
20+
21+ public SuggestDirectiveRegistrationTests ( ITestOutputHelper output )
22+ {
23+ _output = output ;
24+ Ambient . Output = output ;
25+ }
26+
27+ [ Theory ]
28+ [ InlineData ( "[suggest]" , RegistrationStrategy . None , null , false , false ) ]
29+ [ InlineData ( "" , RegistrationStrategy . None , null , false , false ) ]
30+ [ InlineData ( "[suggest]" , RegistrationStrategy . EnsureOnEveryRun , null , false , false ) ]
31+ [ InlineData ( "" , RegistrationStrategy . EnsureOnEveryRun , null , false , true ) ]
32+ [ InlineData ( "[suggest]" , RegistrationStrategy . UseRegistrationDirective , "sug" , false , false ) ]
33+ [ InlineData ( "" , RegistrationStrategy . UseRegistrationDirective , "sug" , false , false ) ]
34+ [ InlineData ( "[sug]" , RegistrationStrategy . UseRegistrationDirective , "sug" , false , true ) ]
35+ [ InlineData ( "[sug]" , RegistrationStrategy . None , "sug" , false , false ) ]
36+ [ InlineData ( "" , RegistrationStrategy . EnsureOnEveryRun , null , true , false ) ]
37+ [ InlineData ( "[sug]" , RegistrationStrategy . UseRegistrationDirective , "sug" , true , false ) ]
38+ public void Suggest_can_register_with_Dotnet_Suggest ( string args , RegistrationStrategy strategy , string ? directive , bool isGlobal , bool shouldRegister )
39+ {
40+ #region ensure test cases are not misconfigured and summarize a few of the rules
41+ if ( strategy == RegistrationStrategy . None )
42+ {
43+ shouldRegister . Should ( ) . Be ( false , "should never register unless ensureRegisteredWithDotnetSuggest=true" ) ;
44+ }
45+ if ( args . StartsWith ( "[suggest]" ) )
46+ {
47+ shouldRegister . Should ( ) . Be ( false , "should never register when providing suggestions" ) ;
48+ }
49+ if ( isGlobal )
50+ {
51+ shouldRegister . Should ( ) . Be ( false , "should never register when app is global tool" ) ;
52+ }
53+ #endregion
54+
55+ var result = new AppRunner < App > ( )
56+ . UseDefaultMiddleware ( )
57+ . UseCommandLogger ( )
58+ . UseSuggestDirective_Experimental ( strategy , directive ! )
59+ . UseTestEnv ( new ( ) )
60+ . Verify ( new Scenario
61+ {
62+ When = { Args = args } ,
63+ Then = { Output = args . StartsWith ( "[sug" ) ? null : "lala" }
64+ } ,
65+ config : TestConfig . Default . Where ( a => a . AppInfoOverride = BuildAppInfo ( isGlobal ) ) ) ;
66+
67+ result . ExitCode . Should ( ) . Be ( 0 ) ;
68+
69+ ConfirmPathEnvVar ( shouldRegister , result ) ;
70+
71+ ConfirmRegistration ( shouldRegister ) ;
72+ }
73+
74+ private void ConfirmPathEnvVar ( bool shouldRegister , AppRunnerResult result )
75+ {
76+ var testEnvironment = ( TestEnvironment ) result . CommandContext . Environment ;
77+ var userEnvVars = testEnvironment . EnvVarByTarget . GetValueOrDefault ( EnvironmentVariableTarget . User ) ;
78+ if ( shouldRegister )
79+ {
80+ userEnvVars . Should ( ) . NotBeNull ( ) ;
81+ var pathEnvVar = userEnvVars ! . GetValueOrDefault ( "PATH" ) ;
82+ pathEnvVar . Should ( ) . NotBeNull ( ) ;
83+ pathEnvVar . Should ( ) . Contain ( _filePath ) ;
84+ }
85+ else
86+ {
87+ userEnvVars ? . GetValueOrDefault ( "PATH" ) ? . Should ( ) . NotContain ( _filePath ) ;
88+ }
89+ }
90+
91+ private static void ConfirmRegistration ( bool shouldRegister )
92+ {
93+ var path = new FileSuggestionRegistration ( ) . RegistrationConfigurationFilePath ;
94+ if ( File . Exists ( path ) )
95+ {
96+ var lines = File . ReadAllLines ( path ) ;
97+
98+ // _output.WriteLine($"contents of {path}");
99+ // lines.ForEach(l => _output.WriteLine(l));
100+ //
101+ // contents of /Users/{user}/.dotnet-suggest-registration.txt
102+ // SuggestDirectiveRegistrationTests/suggest-test.exe
103+
104+ var cleanedLines = lines . Where ( l => ! l . StartsWith ( nameof ( SuggestDirectiveRegistrationTests ) ) ) . ToArray ( ) ;
105+ File . WriteAllLines ( path , cleanedLines ) ;
106+
107+ if ( shouldRegister )
108+ {
109+ lines . Length . Should ( ) . NotBe ( cleanedLines . Length ) ;
110+ }
111+ else
112+ {
113+ lines . Length . Should ( ) . Be ( cleanedLines . Length ) ;
114+ }
115+ }
116+ }
117+
118+ private AppInfo BuildAppInfo ( bool isGlobalTool )
119+ {
120+ return new (
121+ false , false , false , isGlobalTool , GetType ( ) . Assembly ,
122+ _filePath , Path . GetFileName ( _filePath ) ) ;
123+ }
124+
125+ public class App
126+ {
127+ [ DefaultCommand ]
128+ public void Do ( IConsole console ) => console . WriteLine ( "lala" ) ;
129+ }
130+ }
0 commit comments