@@ -118,6 +118,122 @@ Describe "TabCompletion" -Tags CI {
118
118
}
119
119
}
120
120
121
+ context CustomProviderTests {
122
+ BeforeAll {
123
+ $testModulePath = Join-Path $TestDrive " ReproModule"
124
+ New-Item - Path $testModulePath - ItemType Directory > $null
125
+
126
+ New-ModuleManifest - Path " $testModulePath /ReproModule.psd1" - RootModule ' testmodule.dll'
127
+
128
+ $testBinaryModulePath = Join-Path $testModulePath " testmodule.dll"
129
+ $binaryModule = @'
130
+ using System;
131
+ using System.Linq;
132
+ using System.Management.Automation;
133
+ using System.Management.Automation.Provider;
134
+
135
+ namespace BugRepro
136
+ {
137
+ public class IntItemInfo
138
+ {
139
+ public string Name;
140
+ public IntItemInfo(string name) => Name = name;
141
+ }
142
+
143
+ [CmdletProvider("Int", ProviderCapabilities.None)]
144
+ public class IntProvider : NavigationCmdletProvider
145
+ {
146
+ public static string[] ToChunks(string path) => path.Split("/", StringSplitOptions.RemoveEmptyEntries);
147
+
148
+ protected string _ChildName(string path)
149
+ {
150
+ var name = ToChunks(path).LastOrDefault();
151
+ return name ?? string.Empty;
152
+ }
153
+
154
+ protected string Normalize(string path) => string.Join("/", ToChunks(path));
155
+
156
+ protected override string GetChildName(string path)
157
+ {
158
+ var name = _ChildName(path);
159
+ // if (!IsItemContainer(path)) { return string.Empty; }
160
+ return name;
161
+ }
162
+
163
+ protected override bool IsValidPath(string path) => int.TryParse(GetChildName(path), out int _);
164
+
165
+ protected override bool IsItemContainer(string path)
166
+ {
167
+ var name = _ChildName(path);
168
+ if (!int.TryParse(name, out int value))
169
+ {
170
+ return false;
171
+ }
172
+ if (ToChunks(path).Count() > 3)
173
+ {
174
+ return false;
175
+ }
176
+ return value % 2 == 0;
177
+ }
178
+
179
+ protected override bool ItemExists(string path)
180
+ {
181
+ foreach (var chunk in ToChunks(path))
182
+ {
183
+ if (!int.TryParse(chunk, out int value))
184
+ {
185
+ return false;
186
+ }
187
+ if (value < 0 || value > 9)
188
+ {
189
+ return false;
190
+ }
191
+ }
192
+ return true;
193
+ }
194
+
195
+ protected override void GetItem(string path)
196
+ {
197
+ var name = GetChildName(path);
198
+ if (!int.TryParse(name, out int _))
199
+ {
200
+ return;
201
+ }
202
+ WriteItemObject(new IntItemInfo(name), path, IsItemContainer(path));
203
+ }
204
+ protected override bool HasChildItems(string path) => IsItemContainer(path);
205
+
206
+ protected override void GetChildItems(string path, bool recurse)
207
+ {
208
+ if (!IsItemContainer(path)) { GetItem(path); return; }
209
+
210
+ for (var i = 0; i <= 9; i++)
211
+ {
212
+ var _path = $"{Normalize(path)}/{i}";
213
+ if (recurse)
214
+ {
215
+ GetChildItems(_path, recurse);
216
+ }
217
+ else
218
+ {
219
+ GetItem(_path);
220
+ }
221
+ }
222
+ }
223
+ }
224
+ }
225
+ '@
226
+ Add-Type - OutputAssembly $testBinaryModulePath - TypeDefinition $binaryModule
227
+
228
+ $pwsh = " $PSHOME \pwsh"
229
+ }
230
+
231
+ It " Should not complete invalid items when a provider path returns itself instead of its children" {
232
+ $result = & $pwsh - NoProfile - Command " Import-Module -Name $testModulePath ; (TabExpansion2 'Get-ChildItem Int::/2/3/').CompletionMatches.Count"
233
+ $result | Should - BeExactly " 0"
234
+ }
235
+ }
236
+
121
237
It ' should complete index expression for <Intent>' - TestCases @ (
122
238
@ {
123
239
Intent = ' Hashtable with no user input'
0 commit comments